MINI MINI MANI MO

Path : /proc/self/root/opt/oracle/product/18c/dbhomeXE/md/admin/
File Upload :
Current File : //proc/self/root/opt/oracle/product/18c/dbhomeXE/md/admin/sdorttz.sql

Rem
Rem $Header: sdo/admin/sdorttz.sql /main/9 2017/10/20 11:01:24 rjanders Exp $
Rem
Rem sdorttz.sql
Rem
Rem Copyright (c) 2016, 2017, Oracle and/or its affiliates. 
Rem All rights reserved.
Rem
Rem    NAME
Rem      sdorttz.sql - Router timezone create package
Rem
Rem    DESCRIPTION
Rem      For the SDO_TIMEZONES table (source of the timezones polygons)
Rem        - Add the tables metadata to the USER_SDO_GEOM_METADATA table
Rem        - Build a spatial index on the tables geometry field
Rem      Build the ROUTER_TIMEZONES table (the Routers timezone user data)
Rem
Rem    NOTES
Rem      It is assumed that the SDO_ROUTER_LOG directory exists and is writable
Rem      from PLSQL in the excuting schema. Users can run
Rem      sdo_router_partition.validate_sdo_router_log_dir to be sure
Rem
Rem      All logging is done to the sdo_router_timezones.log file in the
Rem      SDO_ROUTER_LOG_DIR directory. The file name can be changed from
Rem      the default in the calls, the directory can not.          
Rem
Rem    BEGIN SQL_FILE_METADATA 
Rem    SQL_SOURCE_FILE: sdo/admin/sdorttz.sql 
Rem    SQL_SHIPPED_FILE: 
Rem    SQL_PHASE: 
Rem    SQL_STARTUP_MODE: NORMAL 
Rem    SQL_IGNORABLE_ERRORS: NONE 
Rem    SQL_CALLING_FILE: 
Rem    END SQL_FILE_METADATA
Rem
Rem    MODIFIED   (MM/DD/YY)
Rem    rjanders    10/08/17 - Add MDSYS to spatial type
Rem    rjanders    06/30/17 - Add SYS/MDSYS prefixes
Rem    rjanders    04/25/17 - Remove 'set echo on' directive
Rem    mhorhamm    03/09/17 - Move is_simple_file_name to sdo_utl
Rem    begeorge    02/16/17 - bug 25513512
Rem    sravada     01/11/17 - bug 25370681
Rem    cfreiwal    04/04/16 - Router timezone user data creation package
Rem

Rem ********************************************************************
Rem Indicate that this is an Oracle-Supplied object
@@?/rdbms/admin/sqlsessstart.sql
Rem ********************************************************************

   -- Create the timezones generation package
--
CREATE OR REPLACE PACKAGE MDSYS.SDO_ROUTER_TIMEZONE AUTHID current_user AS
  PROCEDURE cleanup_timezones;
  PROCEDURE create_router_timezones_edges(log_file_name IN VARCHAR2 := 'sdo_router_timezones.log');
  PROCEDURE create_sdo_timezones_index(log_file_name IN VARCHAR2 := 'sdo_router_timezones.log');
END SDO_ROUTER_TIMEZONE;
/

CREATE OR REPLACE PACKAGE BODY MDSYS.SDO_ROUTER_TIMEZONE AS

---------- Start logging section

-- Timezone log file
  tz_log_file     utl_file.file_type := NULL;
  schema_name     VARCHAR2(260) := NULL;
  JAVA_ERROR      EXCEPTION;
  PARAMETER_ERROR EXCEPTION;

---
PROCEDURE log_message(message IN VARCHAR2, show_time IN BOOLEAN DEFAULT TRUE)
IS
BEGIN
  -- No logfile, return
  IF (utl_file.is_open(tz_log_file) = FALSE )  THEN
     RETURN;
  END IF;
  
  IF (show_time) THEN
    utl_file.put_line (tz_log_file, sdo_util.number_to_char(sysdate,'Dy fmMon DD HH24:MI:SS YYYY'));
  END IF;

  utl_file.put_line (tz_log_file, message);
  utl_file.fflush(tz_log_file);

EXCEPTION
  WHEN OTHERS THEN
    raise_application_error(-20002, '[ERROR] Writing timezones log file');
END log_message;

---
FUNCTION open_log_file(log_file_name IN VARCHAR2)
RETURN VARCHAR2 AS
  full_file_name  VARCHAR2(256);
  stmt            VARCHAR2(256);
BEGIN
  BEGIN
    if (sdo_util.is_simple_file_name(log_file_name) = 'FALSE') then
           raise_application_error(-20020, '[ERROR] bad file name');
    end if;
    -- Open (append) the Router timezones log file
    IF (NOT utl_file.is_open(tz_log_file)) THEN
      tz_log_file := utl_file.fopen ('SDO_ROUTER_LOG_DIR', log_file_name, 'A');
    END IF;
     
    stmt := 'SELECT directory_path FROM SYS.all_directories 
             WHERE directory_name=''SDO_ROUTER_LOG_DIR''';
    EXECUTE IMMEDIATE stmt INTO full_file_name;

    -- Make sure the path is terminated with a /
    IF (instr(full_file_name, '/', length(full_file_name)) = 0)
    THEN full_file_name := full_file_name || '/';
    END IF;

    full_file_name := full_file_name || log_file_name;

  EXCEPTION
    WHEN utl_file.invalid_path THEN
      raise_application_error(-20006, '[ERROR] SDO_ROUTER_LOG_DIR directory not found');
    WHEN utl_file.invalid_operation THEN
      raise_application_error(-20006, '[ERROR] Bad directory path specified for SDO_ROUTER_LOG_DIR directory');
    WHEN OTHERS THEN
      raise_application_error(-20001, '[ERROR] Could not open log file');
  END;
  RETURN full_file_name;
END open_log_file;

---------- End logging section

---------- Start utility section

--- Add metadata to USER_SDO_GEOM_METADATA
--- 
PROCEDURE add_metadata(table_name IN VARCHAR2)
IS
  l_table_name VARCHAR(256);
  stmt         VARCHAR2(256);
  no           NUMBER := 0;
BEGIN
  l_table_name := nls_upper(SYS.DBMS_ASSERT.SIMPLE_SQL_NAME(table_name));
  
  -- If the metadata already exists, drop it so it can be recreated
  stmt := 'SELECT COUNT(*) FROM mdsys.user_sdo_geom_metadata WHERE table_name = :name';
  EXECUTE IMMEDIATE stmt into no using l_table_name;
  IF (no = 1) THEN
    stmt := 'DELETE FROM mdsys.user_sdo_geom_metadata WHERE table_name = :name';
    EXECUTE IMMEDIATE stmt using l_table_name;
    log_message('[INFO] Dropped metadata for ' || table_name ||
                ' from mdsys.user_sdo_geom_metadata');
  END IF;

  -- Add the metadata
  stmt := 'INSERT INTO mdsys.user_sdo_geom_metadata ' ||
            '(table_name, column_name, diminfo, srid) ' ||
          'VALUES(' ||
            ':tname, ' ||
            '''GEOMETRY'', ' ||
            'MDSYS.SDO_DIM_ARRAY(' ||
              'MDSYS.SDO_DIM_ELEMENT(''Long'', -180, 180, 1), ' ||
              'MDSYS.SDO_DIM_ELEMENT(''Lat'', -90, 90, 1)), ' ||
             '8307)';
  EXECUTE IMMEDIATE stmt using l_table_name;
  COMMIT;  

  log_message('[INFO] Added metadata for ' || table_name ||
              ' to mdsys.user_sdo_geom_metadata');

  EXCEPTION
  WHEN OTHERS THEN
   log_message(SQLERRM);
   raise_application_error(-20101,
                           '[ERROR] While generating geometry metadata for ' ||
                             l_table_name);
END add_metadata;

--- 
FUNCTION index_exists(index_name IN VARCHAR2)
  RETURN VARCHAR2
IS
  stmt  VARCHAR2(256);
  no    NUMBER := 0;
BEGIN
  stmt := 'SELECT COUNT(*) FROM IND WHERE INDEX_NAME = :name';
  EXECUTE IMMEDIATE stmt into no using nls_upper(index_name);
  IF (no = 1) THEN
    RETURN 'TRUE';
  ELSE
    RETURN 'FALSE';
  END IF;    
END index_exists;

--- 
FUNCTION metadata_exists(table_name IN VARCHAR2)
  RETURN VARCHAR2
IS
  stmt  VARCHAR2(256);
  no    NUMBER := 0;
BEGIN
  stmt := 'SELECT COUNT(*) FROM mdsys.user_sdo_geom_metadata WHERE table_name = :name';
  EXECUTE IMMEDIATE stmt into no using nls_upper(table_name);
  IF (no = 1) THEN
    RETURN 'TRUE';
  ELSE
    RETURN 'FALSE';
  END IF;    
END metadata_exists;

---  
FUNCTION table_exists(tab_name IN VARCHAR2)
  RETURN VARCHAR2
IS
  stmt  VARCHAR2(256);
  no    NUMBER := 0;
BEGIN
  stmt := 'SELECT COUNT(*) FROM TAB WHERE TNAME = :name';
  EXECUTE IMMEDIATE stmt into no using nls_upper(tab_name);
  IF (no = 1) THEN
    RETURN 'TRUE';
  ELSE
    RETURN 'FALSE';
  END IF;    
END table_exists;

--
PROCEDURE clean_tables (all_tables IN BOOLEAN DEFAULT TRUE) 
IS
BEGIN   
  IF (table_exists('router_timezones_nodes') = 'TRUE') THEN
    EXECUTE IMMEDIATE 'DROP TABLE router_timezones_nodes';
  END IF;
  
  IF (table_exists('router_timezones_nodes_ins') = 'TRUE') THEN
    EXECUTE IMMEDIATE 'DROP TABLE router_timezones_nodes_ins';
  END IF;

  IF (table_exists('router_timezones_orphan_nodes') = 'TRUE') THEN
    EXECUTE IMMEDIATE 'DROP TABLE router_timezones_orphan_nodes';
  END IF;
  
  IF (all_tables) THEN
    IF (table_exists('router_timezones_edges') = 'TRUE') THEN
      EXECUTE IMMEDIATE 'DROP TABLE router_timezones_edges';
    END IF;
  END IF;
END clean_tables;

-- Make sure all of the edges in the edge table are in a timezone
PROCEDURE validate_edges_table
IS
  stmt     VARCHAR2(256);
  edges    NUMBER := 0;
  tz_edges NUMBER := 0;
BEGIN
  stmt := 'SELECT COUNT(edge_id) FROM router_timezones_edges';
  EXECUTE IMMEDIATE stmt into tz_edges;

  stmt := 'SELECT COUNT(edge_id) FROM edge';
  EXECUTE IMMEDIATE stmt into edges;
  
  IF (tz_edges != edges) THEN
    raise_application_error(-20102, '[ERROR] Timezones edge table validation failed.');
  END IF;
  
END validate_edges_table;

-- Make sure all of the nodes in the node table are in a timezone
PROCEDURE validate_nodes_table
IS
  stmt     VARCHAR2(256);
  nodes    NUMBER := 0;
  tz_nodes NUMBER := 0;
BEGIN
  stmt := 'SELECT COUNT(node_id) FROM router_timezones_nodes';
  EXECUTE IMMEDIATE stmt into tz_nodes;

  stmt := 'SELECT COUNT(node_id) FROM node';
  EXECUTE IMMEDIATE stmt into nodes;

  IF (tz_nodes != nodes) THEN
    raise_application_error(-20103, '[ERROR] Timezones node table validation failed.');
  END IF;

 END validate_nodes_table;

---------- End utility section

---------- Start public API section

--- Cleanup temporary timezones tables
PROCEDURE cleanup_timezones
IS
BEGIN
   clean_tables(FALSE);
END cleanup_timezones;

--- Create the raw timezones data needed by the user data generation in sdo_router_partition
PROCEDURE create_router_timezones_edges(log_file_name IN VARCHAR2 := 'sdo_router_timezones.log')
IS
  full_file_name VARCHAR2(256);
  schema_name    VARCHAR2(130):= sys_context('userenv', 'CURRENT_SCHEMA');
  stmt           VARCHAR2(512);

BEGIN
  full_file_name := open_log_file(log_file_name);

  log_message('******** Begin generation of router_timezones_edges (timezones raw data)');
  log_message('** Logfile location: ' || full_file_name, FALSE);
  log_message('[INFO] Creating router_timezones_edges table for ' || schema_name);

  -- Make sure the raw timezones data exists. This it the TZ_WORLD timezone
  -- database with the shapefiles converted to SDO_GEOMETRYs. This table must
  -- be imported into the Router schema from the Router/demo directory
  IF (table_exists('SDO_TIMEZONES') = 'FALSE' ) THEN
    raise_application_error(-20104, '[ERROR] Table not found: sdo_timezones');
  END IF;

  IF (metadata_exists('SDO_TIMEZONES') = 'FALSE' ) THEN
    raise_application_error(-20105, '[ERROR] Spatial metadata not found for: sdo_timezones');
  END IF;

  IF (index_exists('SDO_TIMEZONES_GEOM_INDEX') = 'FALSE' ) THEN
    raise_application_error(-20106, '[ERROR] Spatial index not found for: sdo_timezones');
  END IF;

  -- Cleanup any stray temporary tables, for both nodes and edges
  clean_tables(TRUE);

  -- First pass, associate most of the nodes with a timezone polygon
  log_message('[INFO] Associate nodes to timezones');
  stmt := 'CREATE TABLE router_timezones_nodes PARALLEL 4 NOLOGGING AS ' ||
          '  SELECT /*+ PARALLEL(node 4) */ n.node_id, t.tzid, n.geometry ' ||
          '  FROM sdo_timezones t, node n ' ||
          '  WHERE SDO_RELATE(n.geometry, t.geometry, ''MASK=ANYINTERACT'')=''TRUE''';
  EXECUTE IMMEDIATE stmt;

  -- Add geometry metadata
  add_metadata('router_timezones_nodes');

  -- Create indexes on the node_id and geometry columns 
  log_message('[INFO] Creating node id index on the router_timezones_nodes table');
  stmt := 'CREATE INDEX rtzn_nid_idx ON router_timezones_nodes(node_id) PARALLEL 4';
  EXECUTE IMMEDIATE stmt;
     
  log_message('[INFO] Creating spatial index on the router_timezones_nodes table');
  stmt := 'CREATE INDEX rtzn_geom_idx ON router_timezones_nodes(geometry) ' ||
          'INDEXTYPE IS mdsys.spatial_index PARALLEL 4';
  EXECUTE IMMEDIATE stmt;

  -- Create the orphan nodes table for nodes that had no interaction with
  -- a timezone polygon
  stmt := 'CREATE TABLE router_timezones_orphan_nodes AS ' ||
          '  SELECT /*+ PARALLEL(node 4) */ node_id, geometry ' ||
          '  FROM node ' ||
          '  WHERE node_id NOT IN ' ||
          '    (SELECT /*+ PARALLEL(router_timezones_nodes 4) */ node_id ' ||
          '     FROM router_timezones_nodes)';
  EXECUTE IMMEDIATE stmt;
  
  log_message('[INFO] Associate orphan nodes to timezone polygons');
  stmt := 'CREATE TABLE router_timezones_nodes_ins AS '||
          '  SELECT /*+ index(n rtzn_geom_idx) */ o.node_id, n.tzid, o.geometry '||
          '  FROM router_timezones_orphan_nodes o, router_timezones_nodes n ' ||
          '  WHERE sdo_nn(n.geometry, o.geometry, ''sdo_num_res=1 unit=meter'', 1) = ''TRUE'''; 
  EXECUTE IMMEDIATE stmt;

  stmt := 'INSERT /*+ APPEND */ INTO router_timezones_nodes ' ||
          '  SELECT * FROM router_timezones_nodes_ins';
  EXECUTE IMMEDIATE stmt;
  COMMIT;

  -- Duplicate nodes show up when a node is located in two timezone polygons
  -- that overlap. Not a frequent occurance but it happens.
  log_message('[INFO] Duplicate node cleanup');
  stmt := 'DELETE FROM router_timezones_nodes WHERE rowid NOT IN ' ||
          '  (SELECT MAX(rowid) FROM router_timezones_nodes GROUP BY node_id)';
  EXECUTE IMMEDIATE stmt;  
  COMMIT;

  -- Make sure all nodes are associated with a timezone
  validate_nodes_table;
  
  -- Create the final router_timezones_edges table which will drive the timezones
  -- user data generation in the router_parition package.
  log_message('[INFO] Associate edges to timezones');

  -- Positive edge ids, use the timezone of the start node
  stmt := 'CREATE TABLE router_timezones_edges NOLOGGING PARALLEL 4 AS ' ||
          '  SELECT e.edge_id, e.partition_id, n.tzid ' ||
          '  FROM edge e, router_timezones_nodes n ' ||
          '  WHERE edge_id>0 AND e.start_node_id=n.node_id';
  EXECUTE IMMEDIATE stmt;

  -- Negative edge ids, use the timezone of the end node
  stmt := 'INSERT /*+ APPEND */ INTO router_timezones_edges ' ||
          '  SELECT e.edge_id, e.partition_id, n.tzid ' ||
          '  FROM edge e, router_timezones_nodes n ' ||
          '  WHERE edge_id<0 AND e.end_node_id=n.node_id';
  EXECUTE IMMEDIATE stmt;
  COMMIT;
  -- Reasoning, now both directions of a two way edge are in the same timezone

  log_message('[INFO] Creating edge id index on the router_timezones_edges table');
  stmt := 'CREATE INDEX rte_eid_idx ON router_timezones_edges(edge_id) PARALLEL 4';
  EXECUTE IMMEDIATE stmt;

  -- Make sure all edges are associated with a timezone
  validate_edges_table;

  log_message('[INFO] Creating partition id index on the router_timezones_edges table');
  stmt := 'CREATE INDEX rte_pid_idx ON router_timezones_edges(partition_id) PARALLEL 4';
  EXECUTE IMMEDIATE stmt;

  log_message('[INFO] Creating timezone id index on the router_timezones_edges table');
  stmt := 'CREATE INDEX rte_tzid_idx ON router_timezones_edges(tzid) PARALLEL 4';
  EXECUTE IMMEDIATE stmt;
  
  -- Clean up the nodes tables but leave the edges table for the partitioning package
  clean_tables(FALSE);
  
  log_message('******** Completed generation of router_timezones_edges');

  -- Close the log file
  utl_file.fclose(tz_log_file);
EXCEPTION
  WHEN OTHERS THEN
   log_message(SQLERRM);
   utl_file.fclose(tz_log_file);
   raise_application_error(-20107, 'Creation of the timezones edges table failed');
END create_router_timezones_edges; 

--- Spatial index creation on the sdo_timezones table 
PROCEDURE create_sdo_timezones_index(log_file_name IN VARCHAR2 := 'sdo_router_timezones.log')
IS
  full_file_name VARCHAR2(256);
  schema_name    VARCHAR2(130):= sys_context('userenv', 'CURRENT_SCHEMA');
BEGIN
  full_file_name := open_log_file(log_file_name);

  log_message('******** Begin indexing of the sdo_timezones table');
  log_message('** Logfile location: ' || full_file_name, FALSE);
  log_message('[INFO] Creating metadata and spatial index on ' ||
                'sdo_timezones for ' || schema_name);

  IF (table_exists('SDO_TIMEZONES') = 'FALSE' ) THEN
    raise_application_error(-20107, '[ERROR] Table not found: sdo_timezones');
  END IF;

  -- Add metadata for the geometry column
  add_metadata('sdo_timezones');

  IF (index_exists('sdo_timezones_geom_index') = 'TRUE') THEN
     EXECUTE IMMEDIATE 'DROP INDEX sdo_timezones_geom_index';
  END IF;

  -- Create the spatial index on the sdo_timezones table
  EXECUTE IMMEDIATE 'CREATE INDEX sdo_timezones_geom_index ON sdo_timezones(geometry) ' ||
                   '  INDEXTYPE IS mdsys.spatial_index PARALLEL 4';

  -- If there is no spatial index on the node table then build one
  IF ((index_exists('node_geometry_index') = 'FALSE') AND
      (index_exists('node_geom_idx') = 'FALSE'))
  THEN
     log_message('[INFO] Rebuilding the spatial index on node table ');

     -- Add geometry metadata
     add_metadata('node');
     
     EXECUTE IMMEDIATE 'CREATE INDEX node_geometry_index ON node(geometry) ' ||
                   '  INDEXTYPE IS mdsys.spatial_index PARALLEL 4';
  END IF;

EXCEPTION
  WHEN OTHERS THEN
   log_message(SQLERRM);
   utl_file.fclose(tz_log_file);
   raise_application_error(-20100, 'Indexing on the sdo_timezones table failed');

END create_sdo_timezones_index; 

---------- End public API section

END SDO_ROUTER_TIMEZONE;
/

show errors;

grant execute on SDO_ROUTER_TIMEZONE to public;
create or replace  public synonym SDO_ROUTER_TIMEZONE for 
  MDSYS.SDO_ROUTER_TIMEZONE;

commit;

Rem ********************************************************************
Rem Indicate this is an Oracle-Supplied object
@?/rdbms/admin/sqlsessend.sql
Rem ********************************************************************

OHA YOOOO