MINI MINI MANI MO

Path : /opt/oracle/product/18c/dbhomeXE/javavm/install/
File Upload :
Current File : //opt/oracle/product/18c/dbhomeXE/javavm/install/jvm_ojds.sql

Rem
Rem $Header: javavm/install/jvm_ojds.sql /main/5 2017/07/03 21:56:53 stanaya Exp $
Rem
Rem jvm_ojds.sql
Rem
Rem Copyright (c) 2011, 2017, Oracle and/or its affiliates. 
Rem All rights reserved.
Rem
Rem    NAME
Rem      jvm_ojds.sql - Database support for Orcle Java Directory Service
Rem
Rem    DESCRIPTION
Rem      Creates tables, sequences and indexes for Ojds tables.
Rem      Creates pl/sql procdures and funtions for Ojds support. 
Rem
Rem    NOTES
Rem      Create packages ojds_namespace and ojds_context.
Rem
Rem    BEGIN SQL_FILE_METADATA
Rem    SQL_SOURCE_FILE: javavm/install/jvm_ojds.sql
Rem    SQL_SHIPPED_FILE: javavm/install/jvm_ojds.sql
Rem    SQL_PHASE: JVM_OJDS
Rem    SQL_STARTUP_MODE: NORMAL
Rem    SQL_IGNORABLE_ERRORS: NONE
Rem    END SQL_FILE_METADATA
Rem    
Rem    MODIFIED   (MM/DD/YY)
Rem    etucker     02/22/17 - qaulify SYSTEM objects
Rem    nneeluru    03/13/14 - Longer identifiers
Rem    etucker     09/03/12 - add protection agains missing ojds_context
Rem                           package
Rem    etucker     05/31/11 - Created
Rem
Rem 
SET ECHO ON
SET FEEDBACK 1
SET NUMWIDTH 10
SET LINESIZE 80
SET TRIMSPOOL ON
SET TAB OFF
SET PAGESIZE 100

-- This is the generator of node ids
create sequence OJVMSYS.ojds$node_number$;

-- This is the generator of node ids
create table OJVMSYS.ojds$bindings$ (parent number(28),child number(28),
                                    id varchar(256),
                                    binding_type number);
-- Set up the primary key for the bindings table
alter table OJVMSYS.ojds$bindings$ add primary key (parent, id);

-- This is the table that stores nodes (directories or leaves)
-- refcount is the number of times the node appears in 
-- OJVMSYS.ojds$bindings$.child
create table OJVMSYS.ojds$inode$ (node number(28), type number, 
                                refcount number, creation_ts date, 
                                last_modified date, owner varchar2(128), 
                                is_context number(1),
                                class_name varchar(4000),
                                class_factory varchar(4000),
                                class_factory_location varchar(4000),
                                shared number(1));

-- Create an index so that nodes may be quickly retrieved
create index OJVMSYS.ojds$node_index on OJVMSYS.ojds$inode$ (node);


-- This is the table that stores the attributes the namespace
create table OJVMSYS.ojds$attributes$ (node number(28), id varchar(256),
                                     data blob);

-- Set up the primary key for the attributes table
alter table OJVMSYS.ojds$attributes$ add primary key (node, id);

-- This is the table that stores the reference address data in the namespace
create table OJVMSYS.ojds$refaddr$ (node number(28),
                                  ref_seq number,
                                  ref_minor_seq number,
                                  ref_kind number,
                                  ref_type varchar(200),
                                  ref_string varchar(4000),
                                  ref_bytes raw(2000));

create index OJVMSYS.ojds$refaddr_index on OJVMSYS.ojds$refaddr$ (node, ref_seq, ref_minor_seq);

-- This is the table that stores permissions on nodes
-- Read = 0
-- Write = 1
-- Execute = 2
create table OJVMSYS.ojds$permissions$ (node number(28), 
                                      type number, 
                                      schema  varchar2(128));

-- Create an index so that permissions may be quickly retrieved
create index OJVMSYS.ojds$perm_index on OJVMSYS.ojds$permissions$ (node, type);

-- This is the generator of shared obj mem ids
create sequence OJVMSYS.ojds$shared$obj$seq$;

-- This is the table that stores the shared obj mem information
create table OJVMSYS.ojds$shared$obj$ (node number(28), timestamp date, 
                                     key varchar(30), byte_size number);

-- Create an index so that shared obj mems may be quickly retrieved
create index OJVMSYS.ojds$shared$obj_index on OJVMSYS.ojds$shared$obj$ (node, timestamp);


create or replace synonym ojds$node_number$ for OJVMSYS.ojds$node_number$;
create or replace synonym ojds$bindings$ for OJVMSYS.ojds$bindings$;
create or replace synonym ojds$inode$ for OJVMSYS.ojds$inode$;
create or replace synonym ojds$attributes$ for OJVMSYS.ojds$attributes$;
create or replace synonym ojds$refaddr$ for OJVMSYS.ojds$refaddr$;
create or replace synonym ojds$permissions$ for OJVMSYS.ojds$permissions$;
create or replace synonym ojds$shared$obj$seq$ for OJVMSYS.ojds$shared$obj$seq$;
create or replace synonym ojds$shared$obj$ for OJVMSYS.ojds$shared$obj$;

-- The ojds bindings and node tables should not be inserted,
-- deleted directly.
create or replace package ojds_context authid current_user as
  -- make a new context with the identified parent and return its node
  function mkcontext (p number, c varchar2) return number;
  -- make a new reference and return its node
  function mkreference (r varchar2) return number;
  -- bind a node to a parent
  procedure link (p number, c number, i varchar2, bt number);
  -- remove a node from a parent
  procedure unlink (p number, i varchar2);
  -- remove nodes with zero reference_count
  function rmUnrefNodes (junk number) return boolean;
  -- remove non-empty context
  function rmEmptyCtx (c number) return number;
  procedure relink (p number, i varchar2, nc number, nt number);
  -- helper for buiding initial context in sql.
  procedure addperm (i number, t number, s varchar2);
  -- invoked when a user is dropped cascade
  procedure user_dropped (the_user varchar2);
  procedure role_dropped (the_role varchar2);
  procedure drop_inode_s (the_dropped varchar2);
  procedure drop_permission_s (the_dropped varchar2);
  function drop_inode_slow (the_dropped varchar2) return boolean;
  procedure drop_inode_node (inode_number NUMBER);
  procedure drop_all_child_links (inode_number NUMBER);
  function is_this_a_context (inode_number NUMBER) return boolean;
end ojds_context;
/

create or replace package body ojds_context as
  -- make a new context and return its node
  function mkcontext (p number, c varchar2) return number is
    inode number;
  begin
    select ojds$node_number$.nextval into inode from SYS.dual;
    insert into ojds$inode$ (node, type, refcount, creation_ts,
                                   last_modified, owner, is_context)
      values (inode, 1, 0, sysdate, sysdate, c, 1);

    -- "." and ".." do not contribute to reference counting
    -- that's why the links are inserted and deleted manually
    -- bind ".." to the parent
    insert into ojds$bindings$ (parent, child, id, binding_type)
      values (inode, p, '..', 1);
    -- bind "." to the parent
    insert into ojds$bindings$ (parent, child, id, binding_type)
      values (inode, inode, '.', 1);
    return inode;
  end;

  -- make a new reference and return its node
  function mkreference (r varchar2) return number is
    inode number;
  begin
    select ojds$node_number$.nextval into inode from SYS.dual;
    insert into ojds$inode$ (node, type, refcount, creation_ts,
                                   last_modified, owner, is_context)
      values (inode, 2, 0, sysdate, sysdate, r, 0);
    return inode;
  end;

  -- bind a node to a parent
  procedure link (p number, c number, i varchar2 , bt number) is
  begin
    -- update the refcount first, as we should be idempotent on
    -- ref managment.
    update ojds$inode$ set refcount = refcount + 1 where node = c;
    insert into ojds$bindings$ (parent, child, id, binding_type)
      values (p, c, i, bt);
  end;

  -- remove a node from a parent
  procedure unlink (p number, i varchar2) is
    c number;
    bt number;
  begin
    -- gets the child and lock the rows in bindings$ and inode$ tables
    select b.child, b.binding_type into c, bt
        from ojds$bindings$ b, ojds$inode$ n
        where b.parent = p and b.id = i and
              n.node = b.child for update;
    -- delete "." and ".." if it's a context
    if bt = 1 then
      delete from ojds$bindings$ where parent = c and (id = '.' or id = '..');
    end if;
    -- delete the parent -> child link
    delete from ojds$bindings$ 
      where parent = p and id = i;
    -- update the child ref count
    update ojds$inode$ set refcount = refcount - 1 where node = c;
    -- delete the child if refcount is 0
    delete from ojds$inode$ where refcount = 0 and node = c;
    -- if child was deleted also delete its entries in $permissions
    if sql%rowcount > 0 then -- true if the node was deleted in $inode
      delete from ojds$permissions$ where node = c;
      delete from ojds$attributes$ where node = c;
      delete from ojds$refaddr$ where node = c;
    end if;
  exception
    when others then -- catches the case of deleting an unknown binding
      if sql%notfound then
        null;
      end if;
  end;

  -- remove unreferenced nodes
  function rmUnrefNodes (junk number) return boolean is
    cursor unrefNodes_cur is select node from ojds$inode$ where refcount = 0;
    notEmpty boolean;
  begin
    notEmpty := FALSE;
    for unrefNodes_rec in unrefNodes_cur
    loop
      notEmpty := TRUE;
      -- delete the inode, permission, and attributes
      delete from ojds$inode$ where node = unrefNodes_rec.node;
      delete from ojds$permissions$ where node = unrefNodes_rec.node;
      delete from ojds$attributes$ where node = unrefNodes_rec.node;
      delete from ojds$refaddr$ where node = unrefNodes_rec.node;
      -- delete child bindings and children's refcount
      update ojds$inode$ set refcount = refcount - 1 where 
        node in (select i.node from ojds$inode$ i, ojds$bindings$ b
          where i.node = b.child and b.parent = unrefNodes_rec.node and b.id <> '..' and b.id <> '.');
      delete from ojds$bindings$ where parent = unrefNodes_rec.node;
    end loop;
    return notEmpty;
  end;

  -- remove empty context; return 1 if it's NOT EMPTY; returns 0 : success.
  function rmEmptyCtx (c number) return number is
    cnt number;
  begin
    select count(*) into cnt from ojds$bindings$ where parent = c and id <> '.' and id <> '..';
    if (cnt <> 0)
      then
        return 1;  -- not empty
    end if;
    -- delete its own "." and ".."
    delete from ojds$bindings$ where parent = c;
    -- delete all pointers to itself
    delete from ojds$bindings$ where child = c;
    -- delete the inode, permission, and attributes
    delete from ojds$inode$ where node = c;
    delete from ojds$permissions$ where node = c;
    delete from ojds$attributes$ where node = c;
    delete from ojds$refaddr$ where node = c;
    return 0;
  end;

  -- relink an entry
  procedure relink (p number, i varchar2, nc number, nt number) is
    c number;
  begin
    -- gets the child and lock the rows in bindings$ and inode$ tables
    select b.child into c from ojds$bindings$ b, ojds$inode$ n
      where b.parent = p and b.id = i and
            n.node = b.child for update;
    -- update the child ref count
    update ojds$inode$ set refcount = refcount - 1 where node = c;
    -- update the binding
    update ojds$bindings$ set child = nc, binding_type = nt where parent = p and id = i;
    -- ref managment.
    update ojds$inode$ set refcount = refcount + 1 where node = nc;
    -- delete the child if refcount is 0
    delete from ojds$inode$ where refcount = 0 and node = c;
    -- if child was deleted also delete its entries in $permissions
    if sql%rowcount > 0 then -- true if the node was deleted in $inode
      delete from ojds$permissions$ where node = c;
      delete from ojds$attributes$ where node = c;
      delete from ojds$refaddr$ where node = c;
    end if;
  exception
    when others then -- catches the case of deleting an unknown binding
      if sql%notfound then
        link(p, nc, i, nt);
      end if;
  end;

  -- since permissions are lists, the java code that
  -- manipulates this deletes all the permissions, and
  -- adds the new ones since permissions are gc'd with their
  -- associated inode, this should really be done with
  -- some sort of constraint or procedure, but I don't know
  -- how to pass arrays to sql from java. 
  -- helper function for building initial context
  procedure addperm (i number, t number, s varchar2) is
  begin
    insert into ojds$permissions$ (node, type, schema) values (i, t, s);
  end;

  -- drop user artifacts when a user is dropped.
  procedure user_dropped (the_user varchar2) is
  begin
    drop_inode_s(the_user);
    drop_permission_s(the_user);
  end;

  procedure role_dropped (the_role varchar2) is
  begin
    drop_permission_s(the_role);
  end;

  procedure drop_permission_s (the_dropped varchar2) is
  begin
    delete from ojds$permissions$ where schema=the_dropped;
  end;

  procedure drop_inode_s (the_dropped varchar2) is 
    tmpp boolean;
  begin
    delete from ojds$permissions$ where schema=the_dropped;
    -- check inode owner
    loop
      tmpp := drop_inode_slow(the_dropped);
      exit when tmpp = FALSE;
    end loop;
  end;

  procedure drop_inode_node (inode_number NUMBER) is
  begin
    delete from ojds$inode$ where node = inode_number;
    delete from ojds$permissions$ where node = inode_number;
    delete from ojds$attributes$ where node = inode_number;
    delete from ojds$refaddr$ where node = inode_number;
    -- delete inward pointers.
    delete from ojds$bindings$ where child = inode_number;
  end;

  function is_this_a_context (inode_number NUMBER) return boolean is
    tmp1 NUMBER;
  begin
    select is_context into tmp1 from ojds$inode$ where node = inode_number;
    if (tmp1 = 0)
    then
      return FALSE;
    else
      return TRUE;
    end if;
  end;

  function drop_inode_slow (the_dropped varchar2) return boolean is
    cursor drop_inode_cur is select node from ojds$inode$ where owner=the_dropped;
    notEmpty boolean;
    inode_number NUMBER;
    is_context_ NUMBER;
  begin
    notEmpty := FALSE;
    open drop_inode_cur;
    fetch drop_inode_cur into inode_number;
    if drop_inode_cur%NOTFOUND then
      close drop_inode_cur;
      return FALSE;
    end if;
    close drop_inode_cur;

    if (is_this_a_context(inode_number)) then
      -- take care of '.' and '..'
      delete from ojds$bindings$ where parent=inode_number and ((id = '.') or (id = '..'));
      drop_all_child_links(inode_number);
    end if;
    drop_inode_node(inode_number);
    return TRUE;
  end;

  -- after deleting pointers to children and decrement children's reference count
  -- we can use 'rmUnrefNode' to take care of the rest
  procedure drop_all_child_links (inode_number NUMBER) is
    cursor all_children_cur is select child from ojds$bindings$ where parent = inode_number and id <> '.' and id <> '..';
    tmpp boolean;
  begin
    for children_rec in all_children_cur
    loop
      update ojds$inode$ set refcount = refcount - 1 where node = children_rec.child;
    end loop;
    delete from ojds$bindings$ where parent=inode_number and id <> '.' and id <> '..';
    -- remove nodes with zero refcount cascadingly
    loop
      tmpp := rmUnrefNodes(1);
      exit when tmpp = FALSE;
    end loop;
  end;
end ojds_context;
/

grant execute on ojds_context to DBA;

create or replace package ojds_namespace authid current_user as
  -- Write the serialized command
  procedure write(bytes long raw);
  -- Execute the command
  function execute return number;
  -- Read the serialzed result
  function read return long raw;
end ojds_namespace;
/

create or replace package body ojds_namespace as

  -- Write the serialized command
  procedure write(bytes long raw)
  as language java name
  'oracle.aurora.jndi.ojds.Server.write(byte[])';

  -- Execute the command
  function execute return number
  as language java name
  'oracle.aurora.jndi.ojds.Server.execute() return boolean';

  -- Read the serialzed result
  function read return long raw
  as language java name
  'oracle.aurora.jndi.ojds.Server.read() return byte[]';

end ojds_namespace;
/

create or replace public synonym ojds_namespace for ojds_namespace;
grant execute on ojds_namespace to public;

-- Create the initial context
declare
  root number;
  pubn number;
  etc number;
  pub varchar2(30) := 'PUBLIC';
  sys varchar2(30) := 'SYS';
  read number;
  write number;
  execute number;
  object_type number;
  context_type number;
begin
  read := 0;
  write := 1;
  execute := 2;
  object_type := 0;
  context_type := 1;
  root := 1;
  -- create root
  root := ojds_context.mkcontext (root, sys);
  ojds_context.addperm (root, read, pub);
  ojds_context.addperm (root, write, sys);
  ojds_context.addperm (root, execute, pub);
  -- devilishly setup the root node refcount 
  update ojds$inode$ set refcount = 666 where node = root;
  -- since no one refers to root, it should never get deleted by gc

 -- create public
  pubn := ojds_context.mkcontext (root, sys);
  ojds_context.addperm (pubn, read, pub);
  ojds_context.addperm (pubn, write, pub);
  ojds_context.addperm (pubn, execute, pub);
  -- pub is in root
  ojds_context.link (root, pubn, 'public', context_type);

 -- create etc
  etc := ojds_context.mkcontext(root, sys);
  ojds_context.addperm (etc, read, pub);
  ojds_context.addperm (etc, write, sys);
  ojds_context.addperm (etc, execute, pub);
  -- etc is in root
  ojds_context.link (root, etc, 'etc', context_type);
end;
/
 -- Commit these changes
commit;

-- remove all artifacts when a drop user cascade occurs
insert into duc$ (OWNER, PACK, PROC, FIELD1, OPERATION#, SEQ) values ('SYS', 'OJDS_CONTEXT', 'USER_DROPPED', 0, 1, 1);

-- remove all artifacts when an owning role is dropped.
create or replace trigger OJDS$ROLE_TRIGGER$ after drop on database when (ora_dict_obj_type='ROLE')
  begin
    ojds_context.role_dropped(ora_dict_obj_name);
  exception -- if not present then ignore 
  when others then
  if sqlcode not in (-00604, -04063, -06508) then raise; end if;
  end;
/
commit;

OHA YOOOO