2448 lines
83 KiB
Plaintext
2448 lines
83 KiB
Plaintext
{
|
|
|
|
This library extracts column types and convert them to Informix encoded types.
|
|
Used by fgldbsch.4gl.
|
|
|
|
API functions:
|
|
|
|
fgldbsch_init() returning integer
|
|
-- initialization function
|
|
-- returns < 0 if problem
|
|
|
|
fgldbsch_set_parameter(name string, value string)
|
|
-- set fgldbsch parameters
|
|
dbname : Data source name
|
|
dbdriver : Database driver name
|
|
username : DB user name (login)
|
|
userpswd : DB user password
|
|
dbowner : DB table owner
|
|
tabname : Extract only this table
|
|
cvmeth : Conversion string (A/B/C sequence)
|
|
casens : Upper/Lower case conversion (C/U/L)
|
|
systabs : Extract system tables (Y/N)
|
|
compat : Old fglschema compat mode
|
|
verbose : Verbose mode (Y/N)
|
|
|
|
fgldbsch_connect() returning integer
|
|
-- connects to the server using parameters for connection info.
|
|
-- returns < 0 if problem
|
|
|
|
fgldbsch_disconnect() returning integer
|
|
-- disconnects from the database server
|
|
-- returns < 0 if problem
|
|
|
|
fgldbsch_get_db_type() returning string
|
|
-- returns the type of server (IFX, ORA, ADS, DB2, ASA, PGS, MYS)
|
|
|
|
fgldbsch_extract() returning integer
|
|
-- extracts schema information
|
|
-- returns < 0 if problem
|
|
|
|
fgldbsch_next_table() returning integer
|
|
-- 1 = new table found
|
|
-- 0 = no more tables
|
|
-- returns < 0 if problem
|
|
|
|
fgldbsch_get_table_name() returning string
|
|
-- returns name of current table
|
|
|
|
fgldbsch_get_column_count() returning integer
|
|
-- returns the number of columns in current table
|
|
|
|
fgldbsch_get_column_info(integer)
|
|
returning tabname string, colname string, nattype string,
|
|
ifxtype integer, ifxleng integer
|
|
-- returns the column info by column position
|
|
-- WARNING: ifxtype can be -1 to indicate an unsupported data type.
|
|
|
|
}
|
|
|
|
DEFINE params RECORD
|
|
dbname STRING,
|
|
dbdriver STRING,
|
|
dbowner STRING,
|
|
dbtype CHAR(3),
|
|
username STRING,
|
|
userpswd STRING,
|
|
tabname STRING,
|
|
cvmeth CHAR(40),
|
|
casens CHAR(1),
|
|
systabs CHAR(1),
|
|
compat CHAR(1),
|
|
verbose CHAR(1)
|
|
END RECORD
|
|
|
|
DEFINE current_tabname STRING
|
|
|
|
TYPE t_coldef RECORD
|
|
colname STRING,
|
|
nattype STRING,
|
|
ifxtype INTEGER,
|
|
ifxleng INTEGER
|
|
END RECORD
|
|
DEFINE coldef DYNAMIC ARRAY OF t_coldef
|
|
|
|
DEFINE new_tabname STRING
|
|
DEFINE new_coldef t_coldef
|
|
|
|
DEFINE s_msv_identity_prepared SMALLINT
|
|
|
|
CONSTANT dtiqual_year = 0
|
|
CONSTANT dtiqual_month = 2
|
|
CONSTANT dtiqual_day = 4
|
|
CONSTANT dtiqual_hour = 6
|
|
CONSTANT dtiqual_minute = 8
|
|
CONSTANT dtiqual_second = 10
|
|
CONSTANT dtiqual_frac1 = 11
|
|
CONSTANT dtiqual_frac2 = 12
|
|
CONSTANT dtiqual_frac3 = 13
|
|
CONSTANT dtiqual_frac4 = 14
|
|
CONSTANT dtiqual_frac5 = 15
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
FUNCTION fgldbsch_display_convtables()
|
|
DISPLAY ""
|
|
DISPLAY " Data type conversion tables"
|
|
DISPLAY " ---------------------------"
|
|
DISPLAY ""
|
|
DISPLAY "If you specify X, the columns with the corresponding data type will be"
|
|
DISPLAY "ignored and not appear in the schema file."
|
|
DISPLAY ""
|
|
DISPLAY "Informix to Informix conversion table:"
|
|
DISPLAY ""
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " Informix Informix A Informix B "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " 1 BOOLEAN BOOLEAN (ns) CHAR(1) "
|
|
DISPLAY " 2 INT8 INT8 (ns) DECIMAL(19,0) "
|
|
DISPLAY " 3 SERIAL8 SERIAL8 (ns) DECIMAL(19,0) "
|
|
DISPLAY " 4 LVARCHAR(m) LVARCHAR (ns) VARCHAR2(m) "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " (ns) = Not supported in 4gl."
|
|
DISPLAY ""
|
|
DISPLAY "Oracle conversion table:"
|
|
DISPLAY ""
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " Oracle Informix A Informix B "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " 1 NUMBER(p,s) DECIMAL(p,s) DECIMAL(p,s) "
|
|
DISPLAY " 2 CHAR(n) CHAR(n) CHAR(n) "
|
|
DISPLAY " 3 VARCHAR(n) VARCHAR(n,0) CHAR(n) "
|
|
DISPLAY " 4 VARCHAR2(n) VARCHAR2(n) CHAR(n) "
|
|
DISPLAY " 5 DATE DATE DATETIME Y TO S "
|
|
DISPLAY " 6 NUMBER(5,0) SMALLINT DECIMAL(5,0) "
|
|
DISPLAY " 7 NUMBER(10,0) INTEGER DECIMAL(10,0) "
|
|
DISPLAY " 8 TIMESTAMP(n>0) DATETIME Y TO F(n) DATETIME Y TO F(n) "
|
|
DISPLAY " 9 INTERVAL Y(n) TO M INTERVAL Y(n) TO M INTERVAL Y(n) TO M "
|
|
DISPLAY " 10 INTERVAL D(n) TO S(p) INTERVAL D(n) TO F(p) INTERVAL D(n) TO F(p)"
|
|
DISPLAY " 11 FLOAT(p) DECIMAL(p/3) FLOAT "
|
|
DISPLAY " 12 TIMESTAMP(0) DATETIME Y TO S DATE "
|
|
DISPLAY " 13 BLOB BYTE BYTE "
|
|
DISPLAY " 14 CLOB TEXT TEXT "
|
|
DISPLAY " 15 NCHAR(n) CHAR(n) NCHAR(n) "
|
|
DISPLAY " 16 NVARCHAR2(n) VARCHAR2(n) NVARCHAR2(n) "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY ""
|
|
DISPLAY "IBM DB2 conversion table:"
|
|
DISPLAY ""
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " IBM DB2 Informix A "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " 1 DECIMAL(p,s) DECIMAL(p,s) "
|
|
DISPLAY " 2 CHAR(n) CHAR(n) "
|
|
DISPLAY " 3 VARCHAR(n) VARCHAR(n,0) "
|
|
DISPLAY " 4 DATE DATE "
|
|
DISPLAY " 5 TIME DATETIME H TO S "
|
|
DISPLAY " 6 TIMESTAMP DATETIME Y TO F(5) "
|
|
DISPLAY " 7 SMALLINT SMALLINT "
|
|
DISPLAY " 8 INTEGER INTEGER "
|
|
DISPLAY " 9 REAL SMALLFLOAT "
|
|
DISPLAY " 10 DOUBLE FLOAT "
|
|
DISPLAY " 11 BLOB BYTE "
|
|
DISPLAY " 12 CLOB TEXT "
|
|
DISPLAY " 13 GRAPHIC(n) CHAR(n) "
|
|
DISPLAY " 14 VARGRAPHIC(n) VARCHAR2(n) "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY ""
|
|
DISPLAY "SQL Server conversion table:"
|
|
DISPLAY ""
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " SQL Server Informix A Informix B "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " 1 DECIMAL(p,s) DECIMAL(p,s) DECIMAL(p,s) "
|
|
DISPLAY " 2 CHAR(n) CHAR(n) CHAR(n) "
|
|
DISPLAY " 3 VARCHAR(n) VARCHAR(n,0) CHAR(n) "
|
|
DISPLAY " 4 SMALLDATETIME DATE DATE "
|
|
DISPLAY " 5 DATETIME DATETIME Y TO F(3) DATE "
|
|
DISPLAY " 6 SMALLINT SMALLINT SMALLINT "
|
|
DISPLAY " 7 INTEGER INTEGER INTEGER "
|
|
DISPLAY " 8 REAL SMALLFLOAT SMALLFLOAT "
|
|
DISPLAY " 9 FLOAT FLOAT FLOAT "
|
|
DISPLAY " 10 NCHAR(n) CHAR(n/2) NCHAR(n/2) "
|
|
DISPLAY " 11 NVARCHAR(n) VARCHAR2(n/2) NVARCHAR2(n/2) "
|
|
DISPLAY " 12 IMAGE BYTE BYTE "
|
|
DISPLAY " 13 TEXT TEXT TEXT "
|
|
DISPLAY " 14 NTEXT TEXT TEXT "
|
|
DISPLAY " 15 VARCHAR(MAX) TEXT TEXT "
|
|
DISPLAY " 16 NVARCHAR(MAX) TEXT TEXT "
|
|
DISPLAY " 17 VARBINARY(n) BYTE BYTE "
|
|
DISPLAY " 18 VARBINARY(MAX) BYTE BYTE "
|
|
DISPLAY " 19 TINYINT SMALLINT SMALLINT "
|
|
DISPLAY " 20 BIGINT DECIMAL(19,0) DECIMAL(19,0) "
|
|
DISPLAY " 21 UNIQUEIDENTIFIER CHAR(36) VARCHAR(36) "
|
|
DISPLAY " 22 BIT SMALLINT CHAR(1) "
|
|
DISPLAY " 23 DATE DATE DATE "
|
|
DISPLAY " 24 DATETIME2(0) DATETIME Y TO S DATE "
|
|
DISPLAY " 25 DATETIME2(n<=5) DATETIME Y TO F(n) DATE "
|
|
DISPLAY " 26 DATETIME2(6) VARCHAR2(26) VARCHAR2(26) "
|
|
DISPLAY " 27 DATETIME2(7) VARCHAR2(27) VARCHAR2(27) "
|
|
DISPLAY " 28 TIME(0) DATETIME H TO S DATETIME H TO S "
|
|
DISPLAY " 29 TIME(n<=5) DATETIME H TO F(n) DATETIME H TP F(n) "
|
|
DISPLAY " 30 TIME(6) VARCHAR(15) VARCHAR(15) "
|
|
DISPLAY " 31 TIME(7) VARCHAR(16) VARCHAR(16) "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY ""
|
|
DISPLAY "PostgreSQL conversion table:"
|
|
DISPLAY ""
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " PostgreSQL Informix A "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " 1 DECIMAL(p,s) DECIMAL(p,s) "
|
|
DISPLAY " 2 FLOAT4 SMALLFLOAT "
|
|
DISPLAY " 3 FLOAT8 FLOAT "
|
|
DISPLAY " 4 CHAR(n) CHAR(n) "
|
|
DISPLAY " 5 VARCHAR(n) VARCHAR2(n) "
|
|
DISPLAY " 6 DATE DATE "
|
|
DISPLAY " 7 TIME DATETIME H TO S "
|
|
DISPLAY " 8 DATETIME DATETIME Y TO F(5) "
|
|
DISPLAY " 9 INT2 SMALLINT "
|
|
DISPLAY " 10 INT4 INTEGER "
|
|
DISPLAY " 11 BOOL CHAR(1) "
|
|
DISPLAY " 12 BIGINT DECIMAL(19,0) "
|
|
DISPLAY " 13 INT8 DECIMAL(19,0) "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY ""
|
|
DISPLAY "MySQL conversion table:"
|
|
DISPLAY ""
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " MySQL Informix A Informix B "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " 1 CHAR(n) CHAR(n) CHAR(n) "
|
|
DISPLAY " 2 VARCHAR(n) VARCHAR2(n) VARCHAR(n) "
|
|
DISPLAY " 3 DECIMAL(p,s) DECIMAL(p,s) DECIMAL(p,s) "
|
|
DISPLAY " 4 FLOAT SMALLFLOAT SMALLFLOAT "
|
|
DISPLAY " 5 DOUBLE FLOAT FLOAT "
|
|
DISPLAY " 6 TINYINT SMALLINT SMALLINT "
|
|
DISPLAY " 7 SMALLINT SMALLINT SMALLINT "
|
|
DISPLAY " 8 MEDIUMINT INTEGER INTEGER "
|
|
DISPLAY " 9 INTEGER INTEGER INTEGER "
|
|
DISPLAY " 10 BIGINT DECIMAL(19,0) DECIMAL(19,0) "
|
|
DISPLAY " 11 DATE DATE DATE "
|
|
DISPLAY " 12 TIME DATETIME H TO S DATETIME H TO S "
|
|
DISPLAY " 13 DATETIME DATETIME Y TO S DATETIME Y TO S "
|
|
DISPLAY " 14 TIMESTAMP DATETIME Y TO S DATETIME Y TO S "
|
|
DISPLAY " 15 ENUM(*) VARCHAR2(255) VARCHAR2(1024) "
|
|
DISPLAY " 16 TINYTEXT VARCHAR2(255) TEXT "
|
|
DISPLAY " 17 TEXT VARCHAR2(65535) TEXT "
|
|
DISPLAY " 18 MEDIUMTEXT TEXT TEXT "
|
|
DISPLAY " 19 LONGTEXT TEXT TEXT "
|
|
DISPLAY " 20 TINYBLOB BYTE BYTE "
|
|
DISPLAY " 21 BLOB BYTE BYTE "
|
|
DISPLAY " 22 MEDIUMBLOB BYTE BYTE "
|
|
DISPLAY " 23 LONGBLOB BYTE BYTE "
|
|
DISPLAY " 24 BINARY(M) BYTE BYTE "
|
|
DISPLAY " 25 VARBINARY(M) BYTE BYTE "
|
|
DISPLAY " 26 YEAR DATETIME Y TO Y SMALLINT "
|
|
DISPLAY " 27 BIT(M) SMALLINT SMALLINT "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY ""
|
|
DISPLAY "Genero db conversion table:"
|
|
DISPLAY ""
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " Genero db Informix A "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY " 1 DECIMAL(p,s) DECIMAL(p,s) "
|
|
DISPLAY " 2 NUMERIC(p,s) DECIMAL(p,s) "
|
|
DISPLAY " 3 MONEY(p,s) MONEY(19,4) "
|
|
DISPLAY " 4 CHAR(n) CHAR(n) "
|
|
DISPLAY " 5 VARCHAR(n) VARCHAR2(n) "
|
|
DISPLAY " 6 VARCHAR2(n) VARCHAR2(n) "
|
|
DISPLAY " 7 NCHAR(n) NCHAR(n) "
|
|
DISPLAY " 8 NVARCHAR(n) NVARCHAR2(n) "
|
|
DISPLAY " 9 NVARCHAR2(n) NVARCHAR2(n) "
|
|
DISPLAY " 10 DATE DATE "
|
|
DISPLAY " 11 TIME DATETIME H TO S "
|
|
DISPLAY " 12 TIMESTAMP DATETIME Y TO F(3) "
|
|
DISPLAY " 13 DATETIME DATETIME Y TO F(3) "
|
|
DISPLAY " 14 BIGINT DECIMAL(19,0) "
|
|
DISPLAY " 15 TINYINT SMALLINT "
|
|
DISPLAY " 16 SMALLINT SMALLINT "
|
|
DISPLAY " 17 INTEGER INTEGER "
|
|
DISPLAY " 18 DOUBLE SMALLFLOAT "
|
|
DISPLAY " 19 REAL SMALLFLOAT "
|
|
DISPLAY " 20 FLOAT FLOAT "
|
|
DISPLAY " 21 BINARY BYTE "
|
|
DISPLAY " 22 VARBINARY BYTE "
|
|
DISPLAY " 23 LONGVARBINARY BYTE "
|
|
DISPLAY " 24 LONGVARCHAR TEXT "
|
|
DISPLAY " 25 DATETIME s TO e DATETIME s TO e "
|
|
DISPLAY " 26 INTERVAL s TO e INTERVAL s TO e "
|
|
DISPLAY " ------------------------------------------------------------------"
|
|
DISPLAY ""
|
|
END FUNCTION
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
FUNCTION fgldbsch_set_parameter(name, value)
|
|
DEFINE name, value STRING
|
|
CASE name
|
|
WHEN "compat" LET params.compat = value
|
|
WHEN "dbname" LET params.dbname = value
|
|
WHEN "dbdriver" LET params.dbdriver = value
|
|
WHEN "username" LET params.username = value
|
|
WHEN "userpswd" LET params.userpswd = value
|
|
WHEN "dbowner" LET params.dbowner = value
|
|
WHEN "tabname" LET params.tabname = value
|
|
WHEN "cvmeth" LET params.cvmeth = value
|
|
WHEN "casens" LET params.casens = value
|
|
WHEN "systabs" LET params.systabs = value
|
|
WHEN "verbose" LET params.verbose = value
|
|
END CASE
|
|
END FUNCTION
|
|
|
|
FUNCTION fgldbsch_get_db_type()
|
|
RETURN params.dbtype
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_get_db_type()
|
|
DEFINE dbt CHAR(3)
|
|
INITIALIZE dbt TO NULL
|
|
IF dbt IS NULL THEN
|
|
IF _fgldbsch_try_select("SELECT user FROM user_users WHERE username=user") THEN
|
|
LET dbt = "ORA"
|
|
END IF
|
|
END IF
|
|
IF dbt IS NULL THEN
|
|
IF _fgldbsch_try_select("SELECT DISTINCT(@@SERVERNAME) FROM INFORMATION_SCHEMA.TABLES") THEN
|
|
LET dbt = "MSV"
|
|
END IF
|
|
END IF
|
|
IF dbt IS NULL THEN
|
|
IF _fgldbsch_try_select("SELECT CURRENT USER FROM SYS.SYSCATALOG WHERE TNAME='SYSTABLE'") THEN
|
|
LET dbt = "ASA"
|
|
END IF
|
|
END IF
|
|
IF dbt IS NULL THEN
|
|
IF _fgldbsch_try_select("SELECT USER FROM sysibm.systables WHERE name='SYSTABLES'") THEN
|
|
LET dbt = "DB2"
|
|
END IF
|
|
END IF
|
|
IF dbt IS NULL THEN
|
|
IF _fgldbsch_try_select("SELECT USER FROM informix.systables WHERE tabid=1") THEN
|
|
LET dbt = "IFX"
|
|
END IF
|
|
END IF
|
|
IF dbt IS NULL THEN
|
|
IF _fgldbsch_try_select("SELECT USER FROM pg_type WHERE typname = 'bool'") THEN
|
|
LET dbt = "PGS"
|
|
END IF
|
|
END IF
|
|
IF dbt IS NULL THEN
|
|
IF _fgldbsch_try_select("SELECT CURDATE()") THEN
|
|
LET dbt = "MYS"
|
|
END IF
|
|
END IF
|
|
IF dbt IS NULL THEN
|
|
IF _fgldbsch_try_select("SELECT USER FROM SYSTEM.TABLE_OF_TABLES WHERE TABLE_NAME = 'TABLE_OF_TABLES'") THEN
|
|
LET dbt = "ADS"
|
|
END IF
|
|
END IF
|
|
RETURN dbt
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_try_select(stmt)
|
|
DEFINE stmt STRING
|
|
DEFINE uname CHAR(50)
|
|
WHENEVER ERROR CONTINUE
|
|
DECLARE sTSU CURSOR FROM stmt
|
|
IF sqlca.sqlcode!=0 THEN RETURN FALSE END IF
|
|
OPEN sTSU
|
|
IF sqlca.sqlcode!=0 THEN RETURN FALSE END IF
|
|
FETCH sTSU INTO uname
|
|
IF sqlca.sqlcode!=0 THEN RETURN FALSE END IF
|
|
CLOSE sTSU
|
|
IF sqlca.sqlcode!=0 THEN RETURN FALSE END IF
|
|
FREE sTSU
|
|
IF sqlca.sqlcode!=0 THEN RETURN FALSE END IF
|
|
WHENEVER ERROR STOP
|
|
RETURN TRUE
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_uplow(name)
|
|
DEFINE name STRING
|
|
CASE params.casens
|
|
WHEN "U" RETURN UPSHIFT(name)
|
|
WHEN "L" RETURN DOWNSHIFT(name)
|
|
OTHERWISE RETURN name
|
|
END CASE
|
|
END FUNCTION
|
|
|
|
FUNCTION fgldbsch_init()
|
|
LET params.systabs = "N" -- No system tables by default
|
|
LET params.casens = "L" -- lower case by default
|
|
LET params.cvmeth = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
|
END FUNCTION
|
|
|
|
FUNCTION fgldbsch_fini()
|
|
END FUNCTION
|
|
|
|
FUNCTION fgldbsch_connect()
|
|
DEFINE dbspec STRING
|
|
DEFINE s INTEGER
|
|
LET s = 0
|
|
WHENEVER ERROR CONTINUE
|
|
LET dbspec = params.dbname
|
|
IF params.dbdriver IS NOT NULL THEN
|
|
LET dbspec = dbspec || "+driver='"||params.dbdriver||"'"
|
|
END IF
|
|
IF params.username IS NOT NULL THEN
|
|
CONNECT TO dbspec AS "fgldbsch" USER params.username USING params.userpswd
|
|
ELSE
|
|
CONNECT TO dbspec AS "fgldbsch"
|
|
END IF
|
|
LET s = STATUS
|
|
WHENEVER ERROR STOP
|
|
IF s == 0 THEN
|
|
LET params.dbtype = _fgldbsch_get_db_type()
|
|
-- Give a chance to DDL transactions...
|
|
WHENEVER ERROR CONTINUE
|
|
SET LOCK MODE TO WAIT 5
|
|
WHENEVER ERROR STOP
|
|
END IF
|
|
RETURN s
|
|
END FUNCTION
|
|
|
|
FUNCTION fgldbsch_disconnect()
|
|
WHENEVER ERROR CONTINUE
|
|
DISCONNECT "fgldbsch"
|
|
WHENEVER ERROR STOP
|
|
RETURN STATUS
|
|
END FUNCTION
|
|
|
|
FUNCTION fgldbsch_extract()
|
|
LET current_tabname = NULL
|
|
CASE params.dbtype
|
|
WHEN "IFX" RETURN _fgldbsch_extract_ifx_start()
|
|
WHEN "ORA" RETURN _fgldbsch_extract_ora_start()
|
|
WHEN "MSV" RETURN _fgldbsch_extract_msv_start()
|
|
WHEN "DB2" RETURN _fgldbsch_extract_db2_start()
|
|
WHEN "PGS" RETURN _fgldbsch_extract_pgs_start()
|
|
WHEN "MYS" RETURN _fgldbsch_extract_mys_start()
|
|
WHEN "ADS" RETURN _fgldbsch_extract_ads_start()
|
|
END CASE
|
|
RETURN -1
|
|
END FUNCTION
|
|
|
|
FUNCTION fgldbsch_next_table()
|
|
CALL coldef.clear()
|
|
IF current_tabname IS NOT NULL THEN
|
|
CALL coldef.appendElement()
|
|
LET coldef[1].* = new_coldef.*
|
|
LET current_tabname = new_tabname
|
|
END IF
|
|
CASE params.dbtype
|
|
WHEN "IFX" RETURN _fgldbsch_extract_ifx_next()
|
|
WHEN "ORA" RETURN _fgldbsch_extract_ora_next()
|
|
WHEN "MSV" RETURN _fgldbsch_extract_msv_next()
|
|
WHEN "DB2" RETURN _fgldbsch_extract_db2_next()
|
|
WHEN "PGS" RETURN _fgldbsch_extract_pgs_next()
|
|
WHEN "MYS" RETURN _fgldbsch_extract_mys_next()
|
|
WHEN "ADS" RETURN _fgldbsch_extract_ads_next()
|
|
END CASE
|
|
RETURN -1
|
|
END FUNCTION
|
|
|
|
FUNCTION fgldbsch_get_table_name()
|
|
RETURN _fgldbsch_uplow(current_tabname)
|
|
END FUNCTION
|
|
|
|
FUNCTION fgldbsch_get_column_count()
|
|
RETURN coldef.getLength()
|
|
END FUNCTION
|
|
|
|
FUNCTION fgldbsch_get_column_info(c)
|
|
DEFINE c INTEGER
|
|
IF c<0 OR c>fgldbsch_get_column_count() THEN
|
|
RETURN NULL, NULL, NULL, -1, -1
|
|
END IF
|
|
RETURN _fgldbsch_uplow(current_tabname),
|
|
_fgldbsch_uplow(coldef[c].colname),
|
|
coldef[c].nattype,
|
|
coldef[c].ifxtype,
|
|
coldef[c].ifxleng
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_register_column(tabname, colname, nattype, ifxtype, ifxleng)
|
|
DEFINE tabname, colname, nattype STRING
|
|
DEFINE ifxtype, ifxleng INTEGER
|
|
LET new_tabname = tabname CLIPPED
|
|
LET new_coldef.colname = colname CLIPPED
|
|
LET new_coldef.nattype = nattype CLIPPED
|
|
LET new_coldef.ifxtype = ifxtype
|
|
LET new_coldef.ifxleng = ifxleng
|
|
IF current_tabname IS NULL THEN
|
|
LET current_tabname = tabname CLIPPED
|
|
ELSE
|
|
IF tabname != current_tabname THEN
|
|
LET new_tabname = tabname CLIPPED
|
|
RETURN 1
|
|
END IF
|
|
END IF
|
|
CALL coldef.appendElement()
|
|
LET coldef[coldef.getLength()].* = new_coldef.*
|
|
RETURN 0
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_owner_warning()
|
|
IF params.verbose = "Y" THEN
|
|
DISPLAY SFMT("WARNING: No owner specified, using %1 as default", params.username CLIPPED)
|
|
DISPLAY ""
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_dtin_qualcode(qname)
|
|
DEFINE qname STRING
|
|
CASE qname
|
|
WHEN "YEAR" RETURN 0
|
|
WHEN "MONTH" RETURN 2
|
|
WHEN "DAY" RETURN 4
|
|
WHEN "HOUR" RETURN 6
|
|
WHEN "MINUTE" RETURN 8
|
|
WHEN "SECOND" RETURN 10
|
|
WHEN "FRACTION" RETURN 12 -- As first qualifier
|
|
WHEN "FRACTION(1)" RETURN 11 -- Not used with ADS
|
|
WHEN "FRACTION(2)" RETURN 12 -- Not used with ADS
|
|
WHEN "FRACTION(3)" RETURN 13 -- Not used with ADS
|
|
WHEN "FRACTION(4)" RETURN 14 -- Not used with ADS
|
|
WHEN "FRACTION(5)" RETURN 15 -- Not used with ADS
|
|
END CASE
|
|
RETURN -1
|
|
END FUNCTION
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
FUNCTION _fgldbsch_ifx_decimal(tn,len)
|
|
DEFINE tn STRING
|
|
DEFINE len, prec, scal SMALLINT
|
|
LET prec = len / 256
|
|
LET scal = len mod 256
|
|
IF scal == 255 THEN
|
|
RETURN SFMT("%1(%2)",tn,prec)
|
|
ELSE
|
|
RETURN SFMT("%1(%2,%3)",tn,prec,scal)
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_ifx_varchar(tn,len)
|
|
DEFINE tn STRING
|
|
DEFINE len, lmin, lmax SMALLINT
|
|
DEFINE xlen INTEGER
|
|
IF len < 0 THEN
|
|
LET xlen = len + 65536
|
|
ELSE
|
|
LET xlen = len
|
|
END IF
|
|
LET lmin = xlen / 256
|
|
LET lmax = xlen mod 256
|
|
IF lmin == 0 THEN
|
|
RETURN SFMT("%1(%2)",tn,lmax)
|
|
ELSE
|
|
RETURN SFMT("%1(%2,%3)",tn,lmax,lmin)
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_ifx_dtiq(qual,p)
|
|
DEFINE qual,p SMALLINT
|
|
CASE qual
|
|
WHEN dtiqual_year RETURN "YEAR"
|
|
WHEN dtiqual_month RETURN "MONTH"
|
|
WHEN dtiqual_day RETURN "DAY"
|
|
WHEN dtiqual_hour RETURN "HOUR"
|
|
WHEN dtiqual_minute RETURN "MINUTE"
|
|
WHEN dtiqual_second RETURN "SECOND"
|
|
END CASE
|
|
IF p==1 THEN
|
|
RETURN "FRACTION"
|
|
ELSE
|
|
CASE qual
|
|
WHEN dtiqual_frac1 RETURN "FRACTION(1)"
|
|
WHEN dtiqual_frac2 RETURN "FRACTION(2)"
|
|
WHEN dtiqual_frac3 RETURN "FRACTION(3)"
|
|
WHEN dtiqual_frac4 RETURN "FRACTION(4)"
|
|
WHEN dtiqual_frac5 RETURN "FRACTION(5)"
|
|
END CASE
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_ifx_datetime(len)
|
|
DEFINE len, q1, q2 SMALLINT
|
|
LET q1 = (len MOD 256) / 16
|
|
LET q2 = (len MOD 256) MOD 16
|
|
RETURN SFMT("DATETIME %1 TO %2", _fgldbsch_ifx_dtiq(q1,1), _fgldbsch_ifx_dtiq(q2,2))
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_ifx_interval(len)
|
|
DEFINE len, l, q1, q2 SMALLINT
|
|
LET q1 = (len MOD 256) / 16
|
|
LET q2 = (len MOD 256) MOD 16
|
|
LET l = ( len / 256 ) - ( q2 - q1 )
|
|
IF q1 < dtiqual_frac1 THEN
|
|
RETURN SFMT("INTERVAL %1(%2) TO %3", _fgldbsch_ifx_dtiq(q1,1), l, _fgldbsch_ifx_dtiq(q2,2))
|
|
ELSE
|
|
RETURN SFMT("INTERVAL %1 TO %2", _fgldbsch_ifx_dtiq(q1,1), _fgldbsch_ifx_dtiq(q2,2))
|
|
END IF
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_informix_typename(ifxtype, ifxleng, xtdtype)
|
|
DEFINE ifxtype SMALLINT
|
|
DEFINE ifxleng SMALLINT
|
|
DEFINE xtdtype INTEGER
|
|
DEFINE nattype STRING
|
|
DEFINE modv SMALLINT
|
|
LET nattype = SFMT("encoded=(%1,%2)",ifxtype,ifxleng)
|
|
LET modv = ( ifxtype MOD 256 )
|
|
CASE
|
|
WHEN modv<=16
|
|
CASE modv
|
|
WHEN 0 LET nattype = SFMT("CHAR(%1)",ifxleng)
|
|
WHEN 1 LET nattype = "SMALLINT"
|
|
WHEN 2 LET nattype = "INTEGER"
|
|
WHEN 3 LET nattype = "FLOAT"
|
|
WHEN 4 LET nattype = "SMALLFLOAT"
|
|
WHEN 5 LET nattype = _fgldbsch_ifx_decimal("DECIMAL",ifxleng)
|
|
WHEN 6 LET nattype = "SERIAL"
|
|
WHEN 7 LET nattype = "DATE"
|
|
WHEN 8 LET nattype = _fgldbsch_ifx_decimal("DECIMAL",ifxleng)
|
|
WHEN 9 LET nattype = "NULL"
|
|
WHEN 10 LET nattype = _fgldbsch_ifx_datetime(ifxleng)
|
|
WHEN 11 LET nattype = "BYTE"
|
|
WHEN 12 LET nattype = "TEXT"
|
|
WHEN 13 LET nattype = _fgldbsch_ifx_varchar("VARCHAR",ifxleng)
|
|
WHEN 14 LET nattype = _fgldbsch_ifx_interval(ifxleng)
|
|
WHEN 15 LET nattype = SFMT("NCHAR(%1)",ifxleng)
|
|
WHEN 16 LET nattype = _fgldbsch_ifx_varchar("NVARCHAR",ifxleng)
|
|
END CASE
|
|
WHEN modv=41 AND xtdtype==5 LET nattype = "BOOL"
|
|
WHEN modv=17 LET nattype = "INT8"
|
|
WHEN modv=18 LET nattype = "SERIAL8"
|
|
WHEN modv=40 AND xtdtype==1 LET nattype = "LVARCHAR"
|
|
END CASE
|
|
RETURN nattype
|
|
END FUNCTION
|
|
|
|
-- Converts special Informix database types that are not supported in 4gl...
|
|
FUNCTION _fgldbsch_convert_datatype_ifx( tabname, colname, ifxtype, ifxleng, xtdtype )
|
|
DEFINE tabname, colname CHAR(200)
|
|
DEFINE ifxtype SMALLINT
|
|
DEFINE ifxleng SMALLINT
|
|
DEFINE xtdtype INTEGER
|
|
DEFINE nattype STRING
|
|
|
|
DEFINE modv SMALLINT
|
|
DEFINE base SMALLINT
|
|
|
|
IF ifxtype>=4096 THEN -- Unsupported Informix datatype
|
|
RETURN NULL, -1, 0
|
|
END IF
|
|
|
|
LET nattype = _fgldbsch_informix_typename(ifxtype, ifxleng, xtdtype)
|
|
|
|
LET modv = ( ifxtype MOD 256 )
|
|
LET ifxtype = ( ifxtype MOD 2048 ) -- Distinct type
|
|
|
|
CASE
|
|
WHEN modv=41 AND xtdtype==5 -- BOOL
|
|
IF params.cvmeth[1,1] = "B" THEN
|
|
LET base = ifxtype / 256
|
|
LET ifxtype = ( base * 256 )
|
|
LET ifxleng = 1
|
|
IF params.compat == "Y" THEN
|
|
DISPLAY SFMT("Warning: BOOLEAN type column \"%1.%2\" converted to CHAR(1).",
|
|
tabname CLIPPED, colname CLIPPED)
|
|
END IF
|
|
ELSE
|
|
LET ifxtype = -1
|
|
END IF
|
|
WHEN modv=17 -- INT8
|
|
IF params.cvmeth[2,2] = "B" THEN
|
|
LET base = ifxtype / 256
|
|
LET ifxtype = ( base * 256 ) + 5
|
|
LET ifxleng = 4864
|
|
IF params.compat == "Y" THEN
|
|
DISPLAY SFMT("Warning: INT8 type column \"%1.%2\" converted to DECIMAL(19,0).",
|
|
tabname CLIPPED, colname CLIPPED)
|
|
END IF
|
|
ELSE
|
|
LET ifxtype = -1
|
|
END IF
|
|
WHEN modv=18 -- SERIAL8
|
|
IF params.cvmeth[3,3] = "B" THEN
|
|
LET base = ifxtype / 256
|
|
LET ifxtype = ( base * 256 ) + 5
|
|
LET ifxleng = 4864
|
|
IF params.compat == "Y" THEN
|
|
DISPLAY SFMT("Warning: SERIAL8 type column \"%1.%2\" converted to DECIMAL(19,0).",
|
|
tabname CLIPPED, colname CLIPPED)
|
|
END IF
|
|
ELSE
|
|
LET ifxtype = -1
|
|
END IF
|
|
WHEN modv=40 AND xtdtype==1 -- LVARCHAR
|
|
IF params.cvmeth[4,4] = "B" THEN
|
|
LET base = ifxtype / 256
|
|
-- Type code 201 is VARCHAR2 with size>255 in .sch!
|
|
LET ifxtype = ( base * 256 ) + 201
|
|
IF params.compat == "Y" THEN
|
|
DISPLAY SFMT("Warning: LVARCHAR type column \"%1.%2\" converted to VARCHAR2(%3).",
|
|
tabname CLIPPED, colname CLIPPED, ifxleng)
|
|
END IF
|
|
ELSE
|
|
LET ifxtype = -1
|
|
END IF
|
|
OTHERWISE
|
|
IF modv<=16 THEN
|
|
LET ifxtype = ifxtype
|
|
ELSE
|
|
LET ifxtype = -1
|
|
END IF
|
|
END CASE
|
|
|
|
RETURN nattype, ifxtype, ifxleng
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_get_selection_filter_ifx(p)
|
|
DEFINE p STRING
|
|
DEFINE s STRING
|
|
LET s = " "
|
|
IF params.tabname IS NOT NULL THEN
|
|
LET s = s, " AND ",p,".TABNAME = '",params.tabname,"'"
|
|
END IF
|
|
IF params.systabs=="N" THEN
|
|
LET s = s, " AND ",p,".TABID > 99 "
|
|
END IF
|
|
IF params.dbowner IS NOT NULL THEN
|
|
LET s = s, " AND ",p,".OWNER='",params.dbowner,"'"
|
|
END IF
|
|
RETURN s
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_ifx_start()
|
|
DEFINE stmt STRING
|
|
DEFINE tabname CHAR(200) -- Warning: Must use CHAR to support SE engines!
|
|
DEFINE hassyno INTEGER
|
|
DEFINE syncount INTEGER
|
|
DEFINE xtdtcol STRING
|
|
DEFINE rsyn RECORD
|
|
ltabname CHAR(64),
|
|
rservername CHAR(64),
|
|
dbname CHAR(64),
|
|
owner CHAR(64),
|
|
rtabname CHAR(64),
|
|
lservername CHAR(64)
|
|
END RECORD
|
|
|
|
WHENEVER ERROR CONTINUE
|
|
DROP TABLE FGLDBSCH_COLS
|
|
WHENEVER ERROR STOP
|
|
CREATE TEMP TABLE FGLDBSCH_COLS (
|
|
TABNAME CHAR(200), -- Warning: Must use CHAR to support SE engines!
|
|
COLNAME CHAR(200),
|
|
COLTYPE SMALLINT,
|
|
COLLENGTH SMALLINT,
|
|
COLNO SMALLINT,
|
|
COLEXT INTEGER
|
|
)
|
|
|
|
-- Check if synonym table exists
|
|
SELECT t.tabname INTO tabname
|
|
FROM "informix".systables t
|
|
WHERE t.tabname = "syssyntable"
|
|
LET hassyno = (SQLCA.SQLCODE==0)
|
|
-- No check if there are rows in syssyntable
|
|
IF hassyno THEN
|
|
DECLARE cifx_syssyntable CURSOR
|
|
FOR SELECT t.tabname FROM "informix".syssyntable t
|
|
OPEN cifx_syssyntable
|
|
FETCH cifx_syssyntable
|
|
LET hassyno = (SQLCA.SQLCODE==0)
|
|
FREE cifx_syssyntable
|
|
END IF
|
|
|
|
-- Check if extended types table exist (IDS)
|
|
-- The coltypes 40 and 41 and OPAQUE types (variable and fixed).
|
|
-- To detect LVARCHAR, BOOLEAN, CLOB and BLOB columns, we must
|
|
-- look in the extended_id column to get the final type!
|
|
-- Extended types are IDS specific types, defined in sysxtdtypes.
|
|
SELECT t.tabname INTO tabname
|
|
FROM "informix".systables t
|
|
WHERE t.tabname = "sysxtdtypes"
|
|
IF SQLCA.SQLCODE == 0 THEN
|
|
LET xtdtcol = " C.EXTENDED_ID"
|
|
ELSE
|
|
LET xtdtcol = " 0"
|
|
END IF
|
|
|
|
LET stmt = "INSERT INTO FGLDBSCH_COLS SELECT",
|
|
" T.TABNAME,",
|
|
" C.COLNAME,",
|
|
" C.COLTYPE,",
|
|
" C.COLLENGTH,",
|
|
" C.COLNO,",
|
|
xtdtcol,
|
|
" FROM ""informix"".SYSCOLUMNS C, ""informix"".SYSTABLES T",
|
|
" WHERE C.TABID = T.TABID",
|
|
_fgldbsch_get_selection_filter_ifx("T")
|
|
|
|
EXECUTE IMMEDIATE stmt
|
|
|
|
IF hassyno THEN
|
|
-- Local PUBLIC/PRIVATE synonyms:
|
|
-- WARNING: We do not manage owners in the schema files!
|
|
-- If no owner is specified, we extract only PUBLIC synonyms.
|
|
-- If an owner is specified, we extract PUBLIC and PRIVATE synonyms.
|
|
LET stmt =
|
|
"INSERT INTO FGLDBSCH_COLS SELECT",
|
|
" T.TABNAME,", -- Name of the synonym!
|
|
" C.COLNAME,",
|
|
" C.COLTYPE,",
|
|
" C.COLLENGTH,",
|
|
" C.COLNO,",
|
|
xtdtcol,
|
|
" FROM ""informix"".SYSCOLUMNS C, ""informix"".SYSSYNTABLE S, ""informix"".SYSTABLES T",
|
|
" WHERE S.BTABID = C.TABID",
|
|
" AND T.TABID = S.TABID",
|
|
" AND S.BTABID IS NOT NULL",
|
|
_fgldbsch_get_selection_filter_ifx("T")
|
|
IF params.dbowner IS NOT NULL THEN
|
|
LET stmt = stmt, " AND T.TABTYPE IN ('P','S')"
|
|
ELSE
|
|
LET stmt = stmt, " AND T.TABTYPE = 'S'" -- ONLY PUBLIC SYNONYMS!!!
|
|
END IF
|
|
|
|
EXECUTE IMMEDIATE stmt
|
|
|
|
END IF
|
|
|
|
IF hassyno THEN
|
|
-- Remove synonyms only exist OnLine and higher engines, which support
|
|
-- the DBSERVERNAME built-in function. So, only try to deal with
|
|
-- remote synonyms if there are any to deal with.
|
|
SELECT COUNT(*) INTO syncount FROM 'informix'.SYSSYNTABLE WHERE btabid IS NULL
|
|
IF syncount>0 THEN
|
|
LET stmt =
|
|
"SELECT T.TABNAME LTABNAME, S.SERVERNAME RSERVERNAME,",
|
|
" S.DBNAME, S.OWNER, S.TABNAME RTABNAME, DBSERVERNAME LSERVERNAME",
|
|
" FROM 'informix'.SYSTABLES T, 'informix'.SYSSYNTABLE S",
|
|
" WHERE T.TABID = S.TABID",
|
|
" AND T.TABTYPE = 'S'", -- ONLY PUBLIC SYNONYMS!!!
|
|
" AND S.BTABID IS NULL",
|
|
_fgldbsch_get_selection_filter_ifx("T")
|
|
DECLARE c_remsyn CURSOR FROM stmt
|
|
FOREACH c_remsyn INTO rsyn.*
|
|
IF rsyn.rservername IS NULL OR rsyn.rservername = ' ' THEN
|
|
LET rsyn.rservername = rsyn.lservername
|
|
END IF
|
|
LET stmt = "INSERT INTO FGLDBSCH_COLS SELECT ",
|
|
"'", rsyn.ltabname CLIPPED, "',",
|
|
" C.COLNAME, C.COLTYPE, C.COLLENGTH, C.COLNO,", xtdtcol,
|
|
" FROM ",
|
|
rsyn.dbname CLIPPED, "@", rsyn.rservername CLIPPED, ":'informix'.SYSTABLES T,",
|
|
rsyn.dbname CLIPPED, "@", rsyn.rservername CLIPPED, ":'informix'.SYSCOLUMNS C",
|
|
" WHERE C.TABID = T.Tabid AND T.TABNAME = '", rsyn.rtabname CLIPPED,
|
|
"' AND T.OWNER = '", rsyn.owner CLIPPED, "'"
|
|
EXECUTE IMMEDIATE stmt
|
|
END FOREACH
|
|
END IF
|
|
END IF
|
|
|
|
WHENEVER ERROR CONTINUE
|
|
DECLARE ctc_ifx CURSOR FOR SELECT * FROM FGLDBSCH_COLS ORDER BY 1, 5
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
OPEN ctc_ifx
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
WHENEVER ERROR STOP
|
|
|
|
RETURN 0
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_ifx_next()
|
|
DEFINE tabname VARCHAR(200)
|
|
DEFINE colname CHAR(200)
|
|
DEFINE coltype INTEGER
|
|
DEFINE coltplen INTEGER
|
|
DEFINE colident SMALLINT
|
|
DEFINE xtdtype INTEGER
|
|
DEFINE nattype STRING
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
|
|
WHILE TRUE
|
|
WHENEVER ERROR CONTINUE
|
|
FETCH ctc_ifx INTO
|
|
tabname,
|
|
colname,
|
|
coltype,
|
|
coltplen,
|
|
colident,
|
|
xtdtype
|
|
|
|
WHENEVER ERROR STOP
|
|
IF SQLCA.SQLCODE < 0 THEN RETURN SQLCA.SQLCODE END IF
|
|
|
|
IF SQLCA.SQLCODE == NOTFOUND THEN
|
|
CLOSE ctc_ifx
|
|
RETURN ( coldef.getLength() > 0 )
|
|
END IF
|
|
|
|
CALL _fgldbsch_convert_datatype_ifx(
|
|
tabname,
|
|
colname,
|
|
coltype,
|
|
coltplen,
|
|
xtdtype
|
|
) RETURNING
|
|
nattype,
|
|
ifxtype,
|
|
ifxleng
|
|
|
|
IF _fgldbsch_register_column(tabname, colname, nattype, ifxtype, ifxleng) THEN
|
|
EXIT WHILE
|
|
END IF
|
|
|
|
END WHILE
|
|
|
|
RETURN 1
|
|
|
|
END FUNCTION
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
FUNCTION _fgldbsch_convert_datatype_ora( oratype, oraleng, oraprec, orascal, oranull )
|
|
DEFINE oratype VARCHAR(100)
|
|
DEFINE oraleng INTEGER
|
|
DEFINE oraprec INTEGER
|
|
DEFINE orascal INTEGER
|
|
DEFINE oranull CHAR(1)
|
|
DEFINE ot VARCHAR(100)
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
DEFINE nattype STRING
|
|
|
|
LET ifxtype = -1
|
|
|
|
LET ot = UPSHIFT(oratype)
|
|
LET nattype = ot
|
|
CASE
|
|
WHEN ot = "CHAR"
|
|
LET ifxtype = 0
|
|
LET ifxleng = oraleng
|
|
LET nattype = SFMT("%1(%2)",ot,oraleng)
|
|
WHEN ot = "VARCHAR"
|
|
CASE params.cvmeth[3,3]
|
|
WHEN "A"
|
|
LET ifxtype = 201
|
|
LET ifxleng = oraleng
|
|
WHEN "B"
|
|
LET ifxtype = 0
|
|
LET ifxleng = oraleng
|
|
END CASE
|
|
LET nattype = SFMT("%1(%2)",ot,oraleng)
|
|
WHEN ot = "VARCHAR2"
|
|
CASE params.cvmeth[4,4]
|
|
WHEN "A"
|
|
LET ifxtype = 201
|
|
LET ifxleng = oraleng
|
|
WHEN "B"
|
|
LET ifxtype = 0
|
|
LET ifxleng = oraleng
|
|
END CASE
|
|
LET nattype = SFMT("%1(%2)",ot,oraleng)
|
|
WHEN ot = "NCHAR"
|
|
CASE params.cvmeth[15,15]
|
|
WHEN "A"
|
|
LET ifxtype = 0
|
|
LET ifxleng = oraleng
|
|
WHEN "B"
|
|
LET ifxtype = 15
|
|
LET ifxleng = oraleng
|
|
END CASE
|
|
LET nattype = SFMT("%1(%2)",ot,oraleng)
|
|
WHEN ot = "NVARCHAR2"
|
|
CASE params.cvmeth[16,16]
|
|
WHEN "A"
|
|
LET ifxtype = 201
|
|
LET ifxleng = oraleng
|
|
WHEN "B"
|
|
LET ifxtype = 202
|
|
LET ifxleng = oraleng
|
|
END CASE
|
|
LET nattype = SFMT("%1(%2)",ot,oraleng)
|
|
WHEN ot = "NUMBER"
|
|
CASE
|
|
WHEN oraprec=5 AND orascal=0 AND params.cvmeth[6,6]='A'
|
|
LET ifxtype = 1 -- SMALLINT
|
|
LET ifxleng = 2
|
|
WHEN oraprec=10 AND orascal=0 AND params.cvmeth[7,7]='A'
|
|
LET ifxtype = 2 -- INTEGER
|
|
LET ifxleng = 4
|
|
OTHERWISE
|
|
LET ifxtype = 5 -- DECIMAL
|
|
LET ifxleng = oraprec * 256 + orascal
|
|
END CASE
|
|
CASE
|
|
WHEN oraprec IS NOT NULL AND orascal IS NOT NULL
|
|
LET nattype = SFMT("%1(%2,%3)",ot,oraprec,orascal)
|
|
WHEN oraprec IS NOT NULL
|
|
LET nattype = SFMT("%1(%2)",ot,oraprec)
|
|
OTHERWISE
|
|
LET nattype = ot
|
|
END CASE
|
|
WHEN ot = "DATE"
|
|
CASE params.cvmeth[5,5]
|
|
WHEN "A"
|
|
LET ifxtype = 7
|
|
LET ifxleng = 4
|
|
WHEN "B"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 3594
|
|
END CASE
|
|
LET nattype = ot
|
|
WHEN ot[1,9] = "TIMESTAMP"
|
|
IF orascal==0 THEN -- TIMESTAMP(0) exists in Oracle!
|
|
CASE params.cvmeth[12,12]
|
|
WHEN "A"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 3594
|
|
WHEN "B"
|
|
LET ifxtype = 7
|
|
LET ifxleng = 4
|
|
END CASE
|
|
ELSE
|
|
LET ifxtype = 10
|
|
CASE orascal
|
|
WHEN 1 LET ifxleng = 3851 -- (15*256)+(0*16)+11
|
|
WHEN 2 LET ifxleng = 4108 -- (16*256)+(0*16)+12
|
|
WHEN 3 LET ifxleng = 4365 -- (17*256)+(0*16)+13
|
|
WHEN 4 LET ifxleng = 4622 -- (18*256)+(0*16)+14
|
|
WHEN 5 LET ifxleng = 4879 -- (19*256)+(0*16)+15
|
|
WHEN 6 LET ifxleng = -1 -- Precision of 6 not supported!
|
|
END CASE
|
|
END IF
|
|
LET nattype = SFMT("%1(%2)",ot,orascal)
|
|
WHEN ot[1,8] = "INTERVAL"
|
|
LET ifxtype = 14
|
|
CASE oraleng
|
|
WHEN 5 -- ORACLE INTERVAL YEAR TO MONTH
|
|
LET ifxleng = ((oraprec+2)*256)+(0*16)+2
|
|
LET nattype = "INTERVAL YEAR TO MONTH"
|
|
WHEN 11 -- ORACLE INTERVAL DAY TO SECOND (= ifx FRACTION)
|
|
IF orascal<6 THEN
|
|
LET ifxleng = ((oraprec+6+orascal)*256)+(4*16)+(10+orascal)
|
|
ELSE
|
|
LET ifxtype = -1
|
|
END IF
|
|
LET nattype = "INTERVAL DAY TO FRACTION"
|
|
OTHERWISE
|
|
LET ifxtype = -1
|
|
LET nattype = NULL
|
|
END CASE
|
|
WHEN ot = "FLOAT"
|
|
CASE params.cvmeth[11,11]
|
|
WHEN "A"
|
|
LET ifxtype = 5 -- DECIMAL
|
|
LET ifxleng = oraprec * 0.30103
|
|
LET ifxleng = (ifxleng+1)*256 + 255
|
|
WHEN "B"
|
|
LET ifxtype = 3 -- FLOAT
|
|
LET ifxleng = 8
|
|
END CASE
|
|
WHEN ot = "BLOB"
|
|
LET ifxtype = 11 -- BYTE
|
|
LET ifxleng = 56
|
|
WHEN ot = "CLOB"
|
|
LET ifxtype = 12 -- TEXT
|
|
LET ifxleng = 56
|
|
END CASE
|
|
|
|
IF ifxtype>-1 AND oranull="N" THEN
|
|
LET ifxtype = ifxtype + 256
|
|
END IF
|
|
|
|
RETURN nattype, ifxtype, ifxleng
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_get_selection_filter_ora(p)
|
|
DEFINE p STRING
|
|
DEFINE s STRING
|
|
LET s = " "
|
|
IF params.tabname IS NOT NULL THEN
|
|
LET s = s, " AND UPPER(",p,".TABLE_NAME) = '",UPSHIFT(params.tabname),"'"
|
|
END IF
|
|
IF params.systabs=="N" THEN
|
|
LET s = s, " AND ",p,".OWNER <> 'SYS' AND ",p,".OWNER <> 'SYSTEM'"
|
|
END IF
|
|
IF params.dbowner IS NULL THEN
|
|
CALL _fgldbsch_owner_warning()
|
|
LET params.dbowner = params.username
|
|
END IF
|
|
IF params.dbowner IS NOT NULL THEN
|
|
LET s = s, " AND UPPER(",p,".OWNER)='",UPSHIFT(params.dbowner),"'"
|
|
END IF
|
|
RETURN s
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_ora_start()
|
|
DEFINE stmt STRING
|
|
|
|
LET stmt = "SELECT",
|
|
" C.TABLE_NAME,",
|
|
" C.COLUMN_NAME,",
|
|
" C.DATA_TYPE,",
|
|
" C.DATA_LENGTH,",
|
|
" C.DATA_PRECISION,",
|
|
" C.DATA_SCALE,",
|
|
" C.NULLABLE,",
|
|
" C.COLUMN_ID",
|
|
" FROM ALL_TAB_COLUMNS C",
|
|
" WHERE C.TABLE_NAME NOT LIKE 'BIN$%'",
|
|
_fgldbsch_get_selection_filter_ora("C"),
|
|
" ORDER BY C.TABLE_NAME, C.COLUMN_ID"
|
|
|
|
WHENEVER ERROR CONTINUE
|
|
DECLARE ctc_ora CURSOR FROM stmt
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
OPEN ctc_ora
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
WHENEVER ERROR STOP
|
|
|
|
RETURN 0
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_ora_next()
|
|
DEFINE tabname VARCHAR(200)
|
|
DEFINE colname VARCHAR(200)
|
|
DEFINE coltype VARCHAR(100)
|
|
DEFINE coltplen INTEGER
|
|
DEFINE coltpprc INTEGER
|
|
DEFINE coltpscl INTEGER
|
|
DEFINE colnullc CHAR(1)
|
|
DEFINE colident INTEGER
|
|
DEFINE nattype STRING
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
|
|
WHILE TRUE
|
|
WHENEVER ERROR CONTINUE
|
|
FETCH ctc_ora INTO
|
|
tabname,
|
|
colname,
|
|
coltype,
|
|
coltplen,
|
|
coltpprc,
|
|
coltpscl,
|
|
colnullc,
|
|
colident
|
|
WHENEVER ERROR STOP
|
|
IF SQLCA.SQLCODE < 0 THEN RETURN SQLCA.SQLCODE END IF
|
|
|
|
IF SQLCA.SQLCODE == NOTFOUND THEN
|
|
CLOSE ctc_ora
|
|
RETURN ( coldef.getLength() > 0 )
|
|
END IF
|
|
|
|
CALL _fgldbsch_convert_datatype_ora(
|
|
coltype,
|
|
coltplen,
|
|
coltpprc,
|
|
coltpscl,
|
|
colnullc
|
|
) RETURNING
|
|
nattype,
|
|
ifxtype,
|
|
ifxleng
|
|
|
|
IF _fgldbsch_register_column(tabname, colname, nattype, ifxtype, ifxleng) THEN
|
|
EXIT WHILE
|
|
END IF
|
|
|
|
END WHILE
|
|
|
|
RETURN 1
|
|
|
|
END FUNCTION
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
FUNCTION _fgldbsch_convert_datatype_db2( db2type, db2leng, db2scal, db2null )
|
|
DEFINE db2type VARCHAR(100)
|
|
DEFINE db2leng INTEGER
|
|
DEFINE db2scal INTEGER
|
|
DEFINE db2null CHAR(1)
|
|
DEFINE nattype STRING
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
DEFINE tn STRING
|
|
|
|
LET ifxtype = -1
|
|
|
|
LET tn = UPSHIFT(db2type)
|
|
LET nattype = tn
|
|
CASE tn
|
|
WHEN "CHARACTER"
|
|
LET ifxtype = 0
|
|
LET ifxleng = db2leng
|
|
LET nattype = SFMT("%1(%2)",tn,db2leng)
|
|
WHEN "VARCHAR"
|
|
LET ifxtype = 201
|
|
LET ifxleng = db2leng
|
|
LET nattype = SFMT("%1(%2)",tn,db2leng)
|
|
WHEN "DECIMAL"
|
|
LET ifxtype = 5
|
|
LET ifxleng = db2leng * 256 + db2scal
|
|
LET nattype = SFMT("%1(%2,%3)",tn,db2leng,db2scal)
|
|
WHEN "REAL"
|
|
LET ifxtype = 4
|
|
LET ifxleng = 4
|
|
WHEN "DOUBLE"
|
|
LET ifxtype = 3
|
|
LET ifxleng = 8
|
|
WHEN "SMALLINT"
|
|
LET ifxtype = 1
|
|
LET ifxleng = 2
|
|
WHEN "INTEGER"
|
|
LET ifxtype = 2
|
|
LET ifxleng = 4
|
|
WHEN "DATE"
|
|
LET ifxtype = 7
|
|
LET ifxleng = 4
|
|
WHEN "TIME"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 1642
|
|
WHEN "TIMESTAMP"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 4879
|
|
WHEN "BLOB"
|
|
LET ifxtype = 11
|
|
LET ifxleng = 56
|
|
WHEN "CLOB"
|
|
LET ifxtype = 12
|
|
LET ifxleng = 56
|
|
WHEN "GRAPHIC"
|
|
LET ifxtype = 0
|
|
LET ifxleng = db2leng
|
|
LET nattype = SFMT("%1(%2)",tn,db2leng)
|
|
WHEN "VARGRAPHIC"
|
|
LET ifxtype = 201
|
|
LET ifxleng = db2leng
|
|
LET nattype = SFMT("%1(%2)",tn,db2leng)
|
|
WHEN "XML"
|
|
LET ifxtype = 201
|
|
LET ifxleng = 16384 -- 0x4000 (see driver)
|
|
END CASE
|
|
|
|
IF ifxtype>-1 AND db2null="N" THEN
|
|
LET ifxtype = ifxtype + 256
|
|
END IF
|
|
|
|
RETURN nattype, ifxtype, ifxleng
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_get_selection_filter_db2(t,c)
|
|
DEFINE t,c STRING
|
|
DEFINE s STRING
|
|
LET s = " "
|
|
IF params.tabname IS NOT NULL THEN
|
|
LET s = s, " AND UPPER(",t,") = '",UPSHIFT(params.tabname),"'"
|
|
END IF
|
|
IF params.systabs=="N" THEN
|
|
LET s = s, " AND UPPER(",c,") <> 'SYSIBM'",
|
|
" AND UPPER(",c,") <> 'SYSCAT'",
|
|
" AND UPPER(",c,") <> 'SYSSTAT'"
|
|
END IF
|
|
IF params.dbowner IS NULL THEN
|
|
CALL _fgldbsch_owner_warning()
|
|
LET params.dbowner = params.username
|
|
END IF
|
|
IF params.dbowner IS NOT NULL THEN
|
|
LET s = s, " AND UPPER(",c,")='",UPSHIFT(params.dbowner),"'"
|
|
END IF
|
|
RETURN s
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_db2_start()
|
|
DEFINE stmt STRING
|
|
|
|
LET stmt = "SELECT",
|
|
" TBNAME,",
|
|
" NAME,",
|
|
" TYPENAME,",
|
|
" LENGTH,",
|
|
" SCALE,",
|
|
" NULLS,",
|
|
" COLNO",
|
|
" FROM SYSIBM.SYSCOLUMNS",
|
|
" WHERE 1=1",
|
|
_fgldbsch_get_selection_filter_db2("TBNAME","TBCREATOR"),
|
|
" ORDER BY TBNAME, COLNO"
|
|
|
|
WHENEVER ERROR CONTINUE
|
|
DECLARE ctc_db2 CURSOR FROM stmt
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
OPEN ctc_db2
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
WHENEVER ERROR STOP
|
|
|
|
RETURN 0
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_db2_next()
|
|
DEFINE tabname VARCHAR(200)
|
|
DEFINE colname VARCHAR(200)
|
|
DEFINE coltype VARCHAR(100)
|
|
DEFINE coltplen INTEGER
|
|
DEFINE coltpscl INTEGER
|
|
DEFINE colnullc CHAR(1)
|
|
DEFINE colident INTEGER
|
|
DEFINE nattype STRING
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
|
|
WHILE TRUE
|
|
WHENEVER ERROR CONTINUE
|
|
FETCH ctc_db2 INTO
|
|
tabname,
|
|
colname,
|
|
coltype,
|
|
coltplen,
|
|
coltpscl,
|
|
colnullc,
|
|
colident
|
|
WHENEVER ERROR STOP
|
|
IF SQLCA.SQLCODE < 0 THEN RETURN SQLCA.SQLCODE END IF
|
|
|
|
IF SQLCA.SQLCODE == NOTFOUND THEN
|
|
CLOSE ctc_db2
|
|
RETURN ( coldef.getLength() > 0 )
|
|
END IF
|
|
|
|
CALL _fgldbsch_convert_datatype_db2(
|
|
coltype,
|
|
coltplen,
|
|
coltpscl,
|
|
colnullc
|
|
) RETURNING
|
|
nattype,
|
|
ifxtype,
|
|
ifxleng
|
|
|
|
IF _fgldbsch_register_column(tabname, colname, nattype, ifxtype, ifxleng) THEN
|
|
EXIT WHILE
|
|
END IF
|
|
|
|
END WHILE
|
|
|
|
RETURN 1
|
|
|
|
END FUNCTION
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
FUNCTION _fgldbsch_msv_is_identity( tabname, colname )
|
|
DEFINE tabname VARCHAR(200)
|
|
DEFINE colname VARCHAR(200)
|
|
DEFINE r INTEGER
|
|
|
|
WHENEVER ERROR CONTINUE
|
|
IF NOT s_msv_identity_prepared THEN
|
|
PREPARE s_msv_identity FROM
|
|
"SELECT CAST(c.is_identity AS INT)" ||
|
|
" FROM sys.all_objects o, sys.all_columns c" ||
|
|
" WHERE o.name = ? AND c.name = ?" ||
|
|
" AND o.object_id = c.object_id" ||
|
|
" AND o.type = 'U'"
|
|
LET s_msv_identity_prepared = (SQLCA.SQLCODE == 0)
|
|
END IF
|
|
IF s_msv_identity_prepared THEN
|
|
EXECUTE s_msv_identity USING tabname, colname INTO r
|
|
END IF
|
|
WHENEVER ERROR STOP
|
|
|
|
RETURN r
|
|
|
|
END FUNCTION
|
|
|
|
# Note1:
|
|
# When using UTF-8 in FGL applications, we recommend to use the same size
|
|
# for the N[VAR]CHAR SQL SERVER column as for the FGL variable:
|
|
# [VAR]CHAR(500) in FGL <=> N[VAR]CHAR(500) in SQL SERVER
|
|
# This is to be Informix compatible and store up to 500 ASCII chars...
|
|
# So when extracting a DB schema from SQL SERVER, N[VAR]CHAR size (in bytes)
|
|
# must be divided by two.
|
|
# Warning: We cannot use the CHARACTER_MAXIMUM_LENGTH column in the SELECT,
|
|
# because multi-byte applications (BIG5) can store MB chars in [VAR]CHAR,
|
|
# and in this case we must use CHARACTER_OCTET_LENGTH as is.
|
|
|
|
FUNCTION _fgldbsch_convert_datatype_msv( tabname, colname, msvtype, msvchrl, msvprec, msvscal, msvdtpr, msvnull )
|
|
DEFINE tabname VARCHAR(200)
|
|
DEFINE colname VARCHAR(200)
|
|
DEFINE msvtype VARCHAR(100)
|
|
DEFINE msvchrl INTEGER
|
|
DEFINE msvprec INTEGER
|
|
DEFINE msvscal INTEGER
|
|
DEFINE msvdtpr INTEGER
|
|
DEFINE msvnull CHAR(4)
|
|
DEFINE nattype STRING
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
|
|
LET ifxtype = -1
|
|
|
|
LET nattype = msvtype
|
|
CASE
|
|
WHEN msvtype = "CHAR"
|
|
LET ifxtype = 0
|
|
LET ifxleng = msvchrl
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvchrl)
|
|
WHEN msvtype = "VARCHAR" AND msvchrl == -1 -- VARCHAR(MAX)
|
|
LET ifxtype = 12 -- TEXT
|
|
LET ifxleng = 56
|
|
LET nattype = "VARCHAR(MAX)"
|
|
WHEN msvtype = "VARCHAR" AND msvchrl > 0 -- VARCHAR(n)
|
|
CASE params.cvmeth[3,3]
|
|
WHEN "A"
|
|
LET ifxtype = 201
|
|
LET ifxleng = msvchrl
|
|
WHEN "B"
|
|
LET ifxtype = 0
|
|
LET ifxleng = msvchrl
|
|
END CASE
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvchrl)
|
|
WHEN msvtype = "NCHAR"
|
|
CASE params.cvmeth[10,10]
|
|
WHEN "A"
|
|
LET ifxtype = 0
|
|
LET ifxleng = msvchrl / 2 -- See Note1
|
|
WHEN "B"
|
|
LET ifxtype = 15
|
|
LET ifxleng = msvchrl / 2 -- See Note1
|
|
END CASE
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvchrl)
|
|
WHEN msvtype = "NVARCHAR" AND msvchrl == -1 -- NVARCHAR(MAX)
|
|
LET ifxtype = 12 -- TEXT
|
|
LET ifxleng = 56
|
|
LET nattype = "NVARCHAR(MAX)"
|
|
WHEN msvtype = "NVARCHAR" AND msvchrl > 0 -- NVARCHAR(n)
|
|
CASE params.cvmeth[11,11]
|
|
WHEN "A"
|
|
LET ifxtype = 201
|
|
LET ifxleng = msvchrl / 2 -- See Note1
|
|
WHEN "B"
|
|
LET ifxtype = 202
|
|
LET ifxleng = msvchrl / 2 -- See Note1
|
|
END CASE
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvchrl)
|
|
WHEN msvtype = "NUMERIC"
|
|
LET ifxtype = 5
|
|
LET ifxleng = msvprec * 256 + msvscal
|
|
LET nattype = SFMT("%1(%2,%3)",msvtype,msvprec,msvscal)
|
|
WHEN msvtype = "DECIMAL"
|
|
LET ifxtype = 5
|
|
LET ifxleng = msvprec * 256 + msvscal
|
|
LET nattype = SFMT("%1(%2,%3)",msvtype,msvprec,msvscal)
|
|
WHEN msvtype = "FLOAT"
|
|
LET ifxtype = 3
|
|
LET ifxleng = 8
|
|
WHEN msvtype = "REAL"
|
|
LET ifxtype = 4
|
|
LET ifxleng = 4
|
|
WHEN msvtype = "TINYINT"
|
|
LET ifxtype = 1
|
|
LET ifxleng = 2
|
|
WHEN msvtype = "SMALLINT"
|
|
LET ifxtype = 1
|
|
LET ifxleng = 2
|
|
WHEN msvtype = "INT"
|
|
IF _fgldbsch_msv_is_identity( tabname, colname ) THEN
|
|
LET ifxtype = 6
|
|
ELSE
|
|
LET ifxtype = 2
|
|
END IF
|
|
LET ifxleng = 4
|
|
WHEN msvtype = "BIGINT"
|
|
LET ifxtype = 5
|
|
LET ifxleng = 19 * 256
|
|
WHEN msvtype = "SMALLDATETIME"
|
|
LET ifxtype = 7
|
|
LET ifxleng = 4
|
|
WHEN msvtype = "DATETIME"
|
|
CASE params.cvmeth[5,5]
|
|
WHEN "A"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 4365
|
|
WHEN "B"
|
|
LET ifxtype = 7
|
|
LET ifxleng = 4
|
|
END CASE
|
|
WHEN msvtype = "IMAGE"
|
|
LET ifxtype = 11 -- BYTE
|
|
LET ifxleng = 56
|
|
WHEN msvtype = "TEXT"
|
|
LET ifxtype = 12 -- TEXT
|
|
LET ifxleng = 56
|
|
WHEN msvtype = "NTEXT"
|
|
LET ifxtype = 12 -- TEXT
|
|
LET ifxleng = 56
|
|
WHEN msvtype = "VARBINARY" AND msvchrl == -1 -- VARBINARY(MAX)
|
|
LET ifxtype = 11 -- BYTE
|
|
LET ifxleng = 56
|
|
LET nattype = "VARBINARY(MAX)"
|
|
WHEN msvtype = "VARBINARY" AND msvchrl > 0 -- VARBINARY(n)
|
|
LET ifxtype = 11 -- BYTE
|
|
LET ifxleng = 56
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvchrl)
|
|
WHEN msvtype = "UNIQUEIDENTIFIER"
|
|
CASE params.cvmeth[21,21]
|
|
WHEN "A"
|
|
LET ifxtype = 0
|
|
LET ifxleng = 36
|
|
WHEN "B"
|
|
LET ifxtype = 201
|
|
LET ifxleng = 36
|
|
WHEN "X"
|
|
-- Column will be ignored!
|
|
LET ifxtype = -2
|
|
END CASE
|
|
WHEN msvtype = "BIT"
|
|
CASE params.cvmeth[22,22]
|
|
WHEN "A"
|
|
LET ifxtype = 1
|
|
LET ifxleng = 2
|
|
WHEN "B"
|
|
LET ifxtype = 0
|
|
LET ifxleng = 1
|
|
END CASE
|
|
WHEN msvtype = "DATE"
|
|
LET ifxtype = 7
|
|
LET ifxleng = 4
|
|
WHEN msvtype = "DATETIME2" AND msvdtpr == 0
|
|
CASE params.cvmeth[24,24]
|
|
WHEN "A"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 3594 -- DATETIME YEAR TO SECOND
|
|
WHEN "B"
|
|
LET ifxtype = 7
|
|
LET ifxleng = 4
|
|
END CASE
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvdtpr)
|
|
WHEN msvtype = "DATETIME2" AND msvdtpr <= 5
|
|
CASE params.cvmeth[25,25]
|
|
WHEN "A"
|
|
LET ifxtype = 10
|
|
CASE msvdtpr
|
|
WHEN 1 LET ifxleng = 3851 -- DATETIME YEAR TO FRACTION(1)
|
|
WHEN 2 LET ifxleng = 4108 -- DATETIME YEAR TO FRACTION(2)
|
|
WHEN 3 LET ifxleng = 4365 -- DATETIME YEAR TO FRACTION(3)
|
|
WHEN 4 LET ifxleng = 4622 -- DATETIME YEAR TO FRACTION(4)
|
|
WHEN 5 LET ifxleng = 4879 -- DATETIME YEAR TO FRACTION(5)
|
|
END CASE
|
|
WHEN "B"
|
|
LET ifxtype = 7
|
|
LET ifxleng = 4
|
|
END CASE
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvdtpr)
|
|
WHEN msvtype = "DATETIME2" AND msvdtpr == 6
|
|
LET ifxtype = 201
|
|
LET ifxleng = 26
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvdtpr)
|
|
WHEN msvtype = "DATETIME2" AND msvdtpr == 7
|
|
LET ifxtype = 201
|
|
LET ifxleng = 27
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvdtpr)
|
|
WHEN msvtype = "TIME" AND msvdtpr == 0
|
|
LET ifxtype = 10
|
|
LET ifxleng = 1642 -- DATETIME HOUR TO SECOND
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvdtpr)
|
|
WHEN msvtype = "TIME" AND msvdtpr <= 5
|
|
LET ifxtype = 10
|
|
CASE msvdtpr
|
|
WHEN 1 LET ifxleng = 1899 -- DATETIME HOUR TO FRACTION(1)
|
|
WHEN 2 LET ifxleng = 2156 -- DATETIME HOUR TO FRACTION(2)
|
|
WHEN 3 LET ifxleng = 2413 -- DATETIME HOUR TO FRACTION(3)
|
|
WHEN 4 LET ifxleng = 2670 -- DATETIME HOUR TO FRACTION(4)
|
|
WHEN 5 LET ifxleng = 2927 -- DATETIME HOUR TO FRACTION(5)
|
|
END CASE
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvdtpr)
|
|
WHEN msvtype = "TIME" AND msvdtpr == 6
|
|
LET ifxtype = 201
|
|
LET ifxleng = 15
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvdtpr)
|
|
WHEN msvtype = "TIME" AND msvdtpr == 7
|
|
LET ifxtype = 201
|
|
LET ifxleng = 16
|
|
LET nattype = SFMT("%1(%2)",msvtype,msvdtpr)
|
|
END CASE
|
|
|
|
IF ifxtype>-1 AND UPSHIFT(msvnull)=="NO" THEN
|
|
LET ifxtype = ifxtype + 256
|
|
END IF
|
|
|
|
RETURN nattype, ifxtype, ifxleng
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_get_selection_filter_msv()
|
|
DEFINE s STRING
|
|
LET s = " AND T.TABLE_NAME != 'dtproperties'"
|
|
IF params.tabname IS NOT NULL THEN
|
|
LET s = s, " AND UPPER(T.TABLE_NAME) = '",UPSHIFT(params.tabname),"'"
|
|
END IF
|
|
IF params.dbowner IS NOT NULL THEN
|
|
LET s = s, " AND UPPER(T.TABLE_SCHEMA)='",UPSHIFT(params.dbowner),"'"
|
|
END IF
|
|
RETURN s
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_msv_start()
|
|
DEFINE stmt STRING
|
|
|
|
LET stmt = "SELECT",
|
|
" C.TABLE_NAME,",
|
|
" C.COLUMN_NAME,",
|
|
" UPPER(C.DATA_TYPE),",
|
|
" C.CHARACTER_OCTET_LENGTH,",
|
|
" C.NUMERIC_PRECISION,",
|
|
" C.NUMERIC_SCALE,",
|
|
" C.DATETIME_PRECISION,",
|
|
" C.IS_NULLABLE,",
|
|
" C.ORDINAL_POSITION",
|
|
" FROM INFORMATION_SCHEMA.COLUMNS C, INFORMATION_SCHEMA.TABLES T",
|
|
" WHERE T.TABLE_SCHEMA = C.TABLE_SCHEMA",
|
|
" AND T.TABLE_NAME = C.TABLE_NAME",
|
|
" AND T.TABLE_TYPE IN ( 'BASE TABLE', 'VIEW' )",
|
|
_fgldbsch_get_selection_filter_msv(),
|
|
" ORDER BY C.TABLE_NAME, C.ORDINAL_POSITION"
|
|
|
|
WHENEVER ERROR CONTINUE
|
|
DECLARE ctc_msv CURSOR FROM stmt
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
OPEN ctc_msv
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
WHENEVER ERROR STOP
|
|
|
|
RETURN 0
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_msv_next()
|
|
DEFINE tabname VARCHAR(200)
|
|
DEFINE colname VARCHAR(200)
|
|
DEFINE coltype VARCHAR(100)
|
|
DEFINE colcharl INTEGER
|
|
DEFINE coltpprc INTEGER
|
|
DEFINE coltpscl INTEGER
|
|
DEFINE coldtprc INTEGER
|
|
DEFINE colnullc VARCHAR(10)
|
|
DEFINE colident INTEGER
|
|
DEFINE nattype STRING
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
|
|
WHILE TRUE
|
|
WHENEVER ERROR CONTINUE
|
|
FETCH ctc_msv INTO
|
|
tabname,
|
|
colname,
|
|
coltype,
|
|
colcharl,
|
|
coltpprc,
|
|
coltpscl,
|
|
coldtprc,
|
|
colnullc,
|
|
colident
|
|
|
|
WHENEVER ERROR STOP
|
|
IF SQLCA.SQLCODE < 0 THEN RETURN SQLCA.SQLCODE END IF
|
|
|
|
IF SQLCA.SQLCODE == NOTFOUND THEN
|
|
CLOSE ctc_msv
|
|
RETURN ( coldef.getLength() > 0 )
|
|
END IF
|
|
|
|
CALL _fgldbsch_convert_datatype_msv(
|
|
tabname,
|
|
colname,
|
|
coltype,
|
|
colcharl,
|
|
coltpprc,
|
|
coltpscl,
|
|
coldtprc,
|
|
colnullc
|
|
) RETURNING
|
|
nattype,
|
|
ifxtype,
|
|
ifxleng
|
|
|
|
IF ifxtype == -2 THEN
|
|
DISPLAY SFMT("Warning: %1 column \"%2.%3\" is ignored.",
|
|
nattype CLIPPED, tabname CLIPPED, colname CLIPPED)
|
|
CONTINUE WHILE
|
|
END IF
|
|
|
|
IF _fgldbsch_register_column(tabname, colname, nattype, ifxtype, ifxleng) THEN
|
|
EXIT WHILE
|
|
END IF
|
|
|
|
END WHILE
|
|
|
|
RETURN 1
|
|
|
|
END FUNCTION
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
FUNCTION _fgldbsch_convert_datatype_pgs( pgstype, pgsleng, pgstmod, pgsnull )
|
|
DEFINE pgstype VARCHAR(100)
|
|
DEFINE pgsleng INTEGER
|
|
DEFINE pgstmod INTEGER
|
|
DEFINE pgsnull CHAR(1)
|
|
DEFINE tmbase INTEGER
|
|
DEFINE nattype STRING
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
DEFINE tn STRING
|
|
|
|
LET ifxtype = -1
|
|
LET tmbase = pgstmod-4 -- This is atttypmod - sizeof(int4)
|
|
|
|
LET tn = UPSHIFT(pgstype)
|
|
LET nattype = tn
|
|
CASE tn
|
|
WHEN "BOOL"
|
|
LET ifxtype = 0
|
|
LET ifxleng = 1
|
|
WHEN "BPCHAR"
|
|
LET ifxtype = 0
|
|
LET ifxleng = tmbase
|
|
LET nattype = SFMT("%1(%2)",tn,tmbase)
|
|
WHEN "VARCHAR"
|
|
LET ifxtype = 201
|
|
LET ifxleng = tmbase
|
|
LET nattype = SFMT("%1(%2)",tn,tmbase)
|
|
WHEN "NUMERIC"
|
|
LET ifxtype = 5
|
|
LET ifxleng = ( tmbase / 65536 ) * 256 + ( tmbase mod 65536 )
|
|
LET nattype = SFMT("%1(%2,%3)",tn, tmbase / 65536, tmbase mod 65536)
|
|
WHEN "FLOAT4"
|
|
LET ifxtype = 4
|
|
LET ifxleng = 4
|
|
WHEN "FLOAT8"
|
|
LET ifxtype = 3
|
|
LET ifxleng = 8
|
|
WHEN "INT2"
|
|
LET ifxtype = 1
|
|
LET ifxleng = 2
|
|
WHEN "INT4"
|
|
LET ifxtype = 2
|
|
LET ifxleng = 4
|
|
WHEN "DATE"
|
|
LET ifxtype = 7
|
|
LET ifxleng = 4
|
|
WHEN "TIME"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 1642
|
|
WHEN "TIMESTAMP"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 4879
|
|
WHEN "BIGINT"
|
|
LET ifxtype = 5
|
|
LET ifxleng = 19 * 256
|
|
WHEN "INT8"
|
|
LET ifxtype = 5
|
|
LET ifxleng = 19 * 256
|
|
END CASE
|
|
|
|
IF ifxtype>-1 AND pgsnull="t" THEN
|
|
LET ifxtype = ifxtype + 256
|
|
END IF
|
|
|
|
RETURN nattype, ifxtype, ifxleng
|
|
|
|
END FUNCTION
|
|
|
|
|
|
FUNCTION _fgldbsch_get_selection_filter_pgs(p)
|
|
DEFINE p STRING
|
|
DEFINE s STRING
|
|
LET s = " "
|
|
IF params.tabname IS NOT NULL THEN
|
|
LET s = s, " AND UPPER(",p,".RELNAME) = '",UPSHIFT(params.tabname),"'"
|
|
END IF
|
|
IF params.systabs=="N" THEN
|
|
LET s = s, " AND ",p,".RELNAMESPACE IN ",
|
|
" (SELECT OID FROM PG_NAMESPACE ",
|
|
" WHERE NSPNAME NOT LIKE 'pg%' ",
|
|
" AND NSPNAME <> 'information_schema')"
|
|
END IF
|
|
IF params.dbowner IS NOT NULL THEN
|
|
LET s = s, " AND UPPER(PG_GET_USERBYID(",p,".RELOWNER))='",UPSHIFT(params.dbowner),"'"
|
|
END IF
|
|
RETURN s
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_pgs_start()
|
|
DEFINE stmt STRING
|
|
|
|
LET stmt = "SELECT",
|
|
" C.OID,",
|
|
" C.RELNAME,",
|
|
" A.ATTNAME,",
|
|
" T.TYPNAME,",
|
|
" A.ATTLEN,",
|
|
" A.ATTTYPMOD,",
|
|
" A.ATTNOTNULL,",
|
|
" A.ATTNUM",
|
|
" FROM PG_CLASS C, PG_ATTRIBUTE A, PG_TYPE T",
|
|
" WHERE A.ATTRELID = C.OID",
|
|
" AND A.ATTTYPID = T.OID",
|
|
" AND ((C.RELKIND='r') OR (C.RELKIND='s') OR (C.RELKIND='v'))",
|
|
" AND (A.ATTNUM>0)",
|
|
_fgldbsch_get_selection_filter_pgs("C"),
|
|
" ORDER BY C.RELNAME, A.ATTNUM"
|
|
|
|
WHENEVER ERROR CONTINUE
|
|
DECLARE ctc_pgs CURSOR FROM stmt
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
OPEN ctc_pgs
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
WHENEVER ERROR STOP
|
|
|
|
RETURN 0
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_pgs_next()
|
|
DEFINE tabid INTEGER
|
|
DEFINE tabname VARCHAR(200)
|
|
DEFINE colname VARCHAR(200)
|
|
DEFINE coltype VARCHAR(100)
|
|
DEFINE coltplen INTEGER
|
|
DEFINE coltpmod INTEGER
|
|
DEFINE colnullc CHAR(1)
|
|
DEFINE colident INTEGER
|
|
DEFINE nattype STRING
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
|
|
WHILE TRUE
|
|
WHENEVER ERROR CONTINUE
|
|
FETCH ctc_pgs INTO
|
|
tabid,
|
|
tabname,
|
|
colname,
|
|
coltype,
|
|
coltplen,
|
|
coltpmod,
|
|
colnullc,
|
|
colident
|
|
|
|
WHENEVER ERROR STOP
|
|
IF SQLCA.SQLCODE < 0 THEN RETURN SQLCA.SQLCODE END IF
|
|
|
|
IF SQLCA.SQLCODE == NOTFOUND THEN
|
|
CLOSE ctc_pgs
|
|
RETURN ( coldef.getLength() > 0 )
|
|
END IF
|
|
|
|
CALL _fgldbsch_convert_datatype_pgs(
|
|
coltype,
|
|
coltplen,
|
|
coltpmod,
|
|
colnullc
|
|
) RETURNING
|
|
nattype,
|
|
ifxtype,
|
|
ifxleng
|
|
|
|
IF _fgldbsch_register_column(tabname, colname, nattype, ifxtype, ifxleng) THEN
|
|
EXIT WHILE
|
|
END IF
|
|
|
|
END WHILE
|
|
|
|
RETURN 1
|
|
|
|
END FUNCTION
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
FUNCTION _fgldbsch_convert_datatype_mys( coltype, colcharl, coltpprc, coltpscl, colnullc, colextra, coltname )
|
|
DEFINE coltype VARCHAR(100)
|
|
DEFINE colcharl INTEGER
|
|
DEFINE coltpprc INTEGER
|
|
DEFINE coltpscl INTEGER
|
|
DEFINE colnullc VARCHAR(10)
|
|
DEFINE colextra VARCHAR(20)
|
|
DEFINE coltname VARCHAR(100)
|
|
DEFINE qual1 INTEGER
|
|
DEFINE qual2 INTEGER
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
|
|
LET ifxtype = -1
|
|
|
|
CASE
|
|
WHEN coltype == "CHAR"
|
|
LET ifxtype = 0
|
|
LET ifxleng = colcharl
|
|
WHEN coltype == "VARCHAR"
|
|
LET ifxtype = 201
|
|
LET ifxleng = colcharl
|
|
WHEN coltype == "DECIMAL"
|
|
LET ifxtype = 5
|
|
LET ifxleng = coltpprc * 256 + coltpscl
|
|
WHEN coltype == "FLOAT"
|
|
LET ifxtype = 4
|
|
LET ifxleng = 4
|
|
WHEN coltype == "DOUBLE"
|
|
LET ifxtype = 3
|
|
LET ifxleng = 8
|
|
WHEN coltype == "TINYINT"
|
|
LET ifxtype = 1
|
|
LET ifxleng = 2
|
|
WHEN coltype == "SMALLINT"
|
|
LET ifxtype = 1
|
|
LET ifxleng = 2
|
|
WHEN coltype == "MEDIUMINT"
|
|
OR coltype == "INT"
|
|
IF colextra == "auto_increment" THEN
|
|
LET ifxtype = 6
|
|
ELSE
|
|
LET ifxtype = 2
|
|
END IF
|
|
LET ifxleng = 4
|
|
WHEN coltype == "BIGINT"
|
|
LET ifxtype = 5
|
|
LET ifxleng = 19 * 256
|
|
WHEN coltype == "DATE"
|
|
LET ifxtype = 7
|
|
LET ifxleng = 4
|
|
WHEN coltype == "TIME"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 1642
|
|
WHEN coltype == "DATETIME"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 3594
|
|
WHEN coltype == "TIMESTAMP"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 3594
|
|
WHEN coltype == "ENUM"
|
|
CASE params.cvmeth[15,15]
|
|
WHEN "A"
|
|
LET ifxtype = 201
|
|
LET ifxleng = 255
|
|
WHEN "B"
|
|
LET ifxtype = 201
|
|
LET ifxleng = 1024
|
|
END CASE
|
|
WHEN coltype == "TINYTEXT" -- 256c (2^8)
|
|
CASE params.cvmeth[16,16]
|
|
WHEN "A"
|
|
LET ifxtype = 201
|
|
LET ifxleng = 255
|
|
WHEN "B"
|
|
LET ifxtype = 12
|
|
LET ifxleng = 56
|
|
END CASE
|
|
WHEN coltype == "TEXT" -- 65536c (2^16)
|
|
CASE params.cvmeth[17,17]
|
|
WHEN "A"
|
|
LET ifxtype = 201
|
|
LET ifxleng = 65535
|
|
WHEN "B"
|
|
LET ifxtype = 12
|
|
LET ifxleng = 56
|
|
END CASE
|
|
WHEN coltype == "MEDIUMTEXT" -- 16777216c (2^24)
|
|
LET ifxtype = 12
|
|
LET ifxleng = 56
|
|
WHEN coltype == "LONGTEXT" -- 4294967296c (2^32)
|
|
LET ifxtype = 12
|
|
LET ifxleng = 56
|
|
WHEN coltype == "TINYBLOB"
|
|
OR coltype == "BLOB"
|
|
OR coltype == "MEDIUMBLOB"
|
|
OR coltype == "LONGBLOB"
|
|
OR coltype == "BINARY"
|
|
OR coltype == "VARBINARY"
|
|
LET ifxtype = 11
|
|
LET ifxleng = 56
|
|
WHEN coltype == "YEAR"
|
|
CASE params.cvmeth[26,26]
|
|
WHEN "A"
|
|
LET ifxtype = 10 -- DATETIME
|
|
LET ifxleng = 1024 -- YEAR TO YEAR
|
|
WHEN "B"
|
|
LET ifxtype = 1
|
|
LET ifxleng = 2
|
|
END CASE
|
|
WHEN coltype == "BIT"
|
|
LET ifxtype = 1
|
|
LET ifxleng = 2
|
|
END CASE
|
|
|
|
IF ifxtype>-1 AND colnullc = "NO" THEN
|
|
LET ifxtype = ifxtype + 256
|
|
END IF
|
|
|
|
RETURN coltname, ifxtype, ifxleng
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_get_selection_filter_mys()
|
|
DEFINE s STRING
|
|
IF params.tabname IS NOT NULL THEN
|
|
LET s = s, " AND UPPER(T.TABLE_NAME) = '",UPSHIFT(params.tabname),"'"
|
|
END IF
|
|
# Warning:
|
|
# In MySQL (6.0.4), TABLE_CATALOG is NULL: TABLE_SCHEMA is the DB name!!!
|
|
# => We must use TABLE_SCHEMA = DBNAME, and no way to filter by dbowner.
|
|
IF params.systabs=="N" THEN
|
|
LET s = s, " AND T.TABLE_SCHEMA=DATABASE()"
|
|
ELSE
|
|
LET s = s, " AND (T.TABLE_SCHEMA=DATABASE() OR T.TABLE_SCHEMA='mysql')"
|
|
END IF
|
|
RETURN s
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_mys_start()
|
|
DEFINE stmt STRING
|
|
|
|
LET stmt = "SELECT",
|
|
" C.TABLE_NAME,",
|
|
" C.COLUMN_NAME,",
|
|
" UPPER(C.DATA_TYPE),",
|
|
" C.CHARACTER_OCTET_LENGTH,",
|
|
" C.NUMERIC_PRECISION,",
|
|
" C.NUMERIC_SCALE,",
|
|
" C.IS_NULLABLE,",
|
|
" C.EXTRA,",
|
|
-- COLUMN_TYPE is complete type name, must use substring() to not get CLOB!
|
|
" SUBSTRING(C.COLUMN_TYPE,1,100),",
|
|
" C.ORDINAL_POSITION",
|
|
" FROM INFORMATION_SCHEMA.COLUMNS C, INFORMATION_SCHEMA.TABLES T",
|
|
" WHERE T.TABLE_SCHEMA = C.TABLE_SCHEMA",
|
|
" AND T.TABLE_NAME = C.TABLE_NAME",
|
|
" AND T.TABLE_TYPE IN ( 'BASE TABLE', 'VIEW' )",
|
|
_fgldbsch_get_selection_filter_mys(),
|
|
" ORDER BY C.TABLE_NAME, C.ORDINAL_POSITION"
|
|
|
|
WHENEVER ERROR CONTINUE
|
|
DECLARE ctc_mys CURSOR FROM stmt
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
OPEN ctc_mys
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
WHENEVER ERROR STOP
|
|
|
|
RETURN 0
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_mys_next()
|
|
DEFINE tabname VARCHAR(200)
|
|
DEFINE colname VARCHAR(200)
|
|
DEFINE coltype VARCHAR(100)
|
|
DEFINE colcharl INTEGER
|
|
DEFINE coltpprc INTEGER
|
|
DEFINE coltpscl INTEGER
|
|
DEFINE colnullc VARCHAR(10)
|
|
DEFINE colextra VARCHAR(20)
|
|
DEFINE coltname VARCHAR(100)
|
|
DEFINE colident INTEGER
|
|
DEFINE nattype STRING
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
|
|
WHILE TRUE
|
|
WHENEVER ERROR CONTINUE
|
|
FETCH ctc_mys INTO
|
|
tabname,
|
|
colname,
|
|
coltype,
|
|
colcharl,
|
|
coltpprc,
|
|
coltpscl,
|
|
colnullc,
|
|
colextra,
|
|
coltname,
|
|
colident
|
|
|
|
WHENEVER ERROR STOP
|
|
IF SQLCA.SQLCODE < 0 THEN RETURN SQLCA.SQLCODE END IF
|
|
|
|
IF SQLCA.SQLCODE == NOTFOUND THEN
|
|
CLOSE ctc_mys
|
|
RETURN ( coldef.getLength() > 0 )
|
|
END IF
|
|
|
|
CALL _fgldbsch_convert_datatype_mys(
|
|
coltype,
|
|
colcharl,
|
|
coltpprc,
|
|
coltpscl,
|
|
colnullc,
|
|
colextra,
|
|
coltname
|
|
) RETURNING
|
|
nattype,
|
|
ifxtype,
|
|
ifxleng
|
|
|
|
IF ifxtype == -2 THEN
|
|
DISPLAY SFMT("Warning: %1 column \"%2.%3\" is ignored.",
|
|
nattype CLIPPED, tabname CLIPPED, colname CLIPPED)
|
|
CONTINUE WHILE
|
|
END IF
|
|
|
|
IF _fgldbsch_register_column(tabname, colname, nattype, ifxtype, ifxleng) THEN
|
|
EXIT WHILE
|
|
END IF
|
|
|
|
END WHILE
|
|
|
|
RETURN 1
|
|
|
|
END FUNCTION
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
FUNCTION _fgldbsch_ads_encode_datetime(adstype, adsdtpr, adsscal)
|
|
DEFINE adstype STRING, adsdtpr, adsscal INTEGER
|
|
DEFINE tmp STRING
|
|
DEFINE tok base.StringTokenizer
|
|
DEFINE q1, q2 STRING
|
|
DEFINE vq1, vq2, len, x SMALLINT
|
|
DEFINE code INTEGER
|
|
|
|
LET tmp = adstype.subString(10, adstype.getLength()) -- "DATETIME "
|
|
LET tok = base.StringTokenizer.create(tmp," ")
|
|
LET q1 = tok.nextToken() -- qualifier 1
|
|
IF q1 IS NULL THEN RETURN -1, 0 END IF
|
|
LET tmp = tok.nextToken() -- TO
|
|
IF tmp IS NULL THEN RETURN -1, 0 END IF
|
|
LET q2 = tok.nextToken() -- qualifier 2
|
|
IF q2 IS NULL THEN RETURN -1, 0 END IF
|
|
|
|
LET vq1 = _fgldbsch_dtin_qualcode(q1)
|
|
LET x = vq1
|
|
IF q2 == "FRACTION" THEN
|
|
LET vq2 = 10 + adsscal
|
|
IF q1 = "FRACTION" THEN
|
|
LET x = 12
|
|
END IF
|
|
ELSE
|
|
LET vq2 = _fgldbsch_dtin_qualcode(q2)
|
|
END IF
|
|
IF q1 == "YEAR" THEN LET len=4 ELSE LET len=2 END IF
|
|
LET code = ((vq2 - x + len) * 256 ) + (vq1 * 16) + vq2
|
|
|
|
RETURN 10, code
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_ads_encode_interval(adstype, adsivpr, adsscal)
|
|
DEFINE adstype STRING, adsivpr, adsscal INTEGER
|
|
DEFINE tmp STRING
|
|
DEFINE tok base.StringTokenizer
|
|
DEFINE q1, q2 STRING
|
|
DEFINE vq1, vq2, len, x SMALLINT
|
|
DEFINE code INTEGER
|
|
|
|
LET tmp = adstype.subString(10, adstype.getLength()) -- "INTERVAL "
|
|
LET tok = base.StringTokenizer.create(tmp," ")
|
|
LET q1 = tok.nextToken() -- qualifier 1
|
|
IF q1 IS NULL THEN RETURN -1, 0 END IF
|
|
LET tmp = tok.nextToken() -- TO
|
|
IF tmp IS NULL THEN RETURN -1, 0 END IF
|
|
LET q2 = tok.nextToken() -- qualifier 2
|
|
IF q2 IS NULL THEN RETURN -1, 0 END IF
|
|
|
|
LET vq1 = _fgldbsch_dtin_qualcode(q1)
|
|
LET x = vq1
|
|
IF q2 == "FRACTION" THEN
|
|
LET vq2 = 10 + adsscal
|
|
IF q1 = "FRACTION" THEN
|
|
LET x = 10 + adsivpr
|
|
END IF
|
|
ELSE
|
|
LET vq2 = _fgldbsch_dtin_qualcode(q2)
|
|
END IF
|
|
LET len = (vq2 - x + adsivpr)
|
|
LET code = (len * 256 ) + (vq1 * 16) + vq2
|
|
|
|
RETURN 14, code
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_convert_datatype_ads( adstype, adssize, adsprec, adsscal, adsdtpr, adsivpr, adsnull )
|
|
DEFINE adstype VARCHAR(100)
|
|
DEFINE adssize INTEGER
|
|
DEFINE adsprec INTEGER
|
|
DEFINE adsscal INTEGER
|
|
DEFINE adsdtpr INTEGER
|
|
DEFINE adsivpr INTEGER
|
|
DEFINE adsnull CHAR(3)
|
|
DEFINE nattype STRING
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
|
|
LET ifxtype = -1
|
|
|
|
-- ADS 3.61
|
|
CASE adsnull
|
|
WHEN '1' LET adsnull = 'YES'
|
|
WHEN '0' LET adsnull = 'NO'
|
|
END CASE
|
|
|
|
LET nattype = adstype
|
|
CASE
|
|
WHEN adstype == "MONEY"
|
|
OR adstype == "NUMERIC"
|
|
OR adstype == "DECIMAL"
|
|
LET ifxtype = 5
|
|
IF adstype == "MONEY" THEN
|
|
LET ifxtype = 8
|
|
END IF
|
|
LET ifxleng = adsprec * 256 + adsscal
|
|
CASE
|
|
WHEN adsprec IS NOT NULL AND adsscal IS NOT NULL
|
|
LET nattype = SFMT("%1(%2,%3)", adstype, adsprec, adsscal)
|
|
WHEN adsprec IS NOT NULL AND adsscal IS NOT NULL
|
|
LET nattype = SFMT("%1(%2)", adstype, adsprec)
|
|
OTHERWISE
|
|
LET nattype = adstype
|
|
END CASE
|
|
WHEN adstype == "CHAR"
|
|
LET ifxtype = 0
|
|
LET ifxleng = adssize
|
|
LET nattype = SFMT("%1(%2)", adstype, adssize)
|
|
WHEN adstype == "VARCHAR"
|
|
OR adstype == "VARCHAR2"
|
|
LET ifxtype = 201
|
|
LET ifxleng = adssize
|
|
LET nattype = SFMT("%1(%2)", adstype, adssize)
|
|
WHEN adstype == "NCHAR"
|
|
LET ifxtype = 15
|
|
LET ifxleng = adssize
|
|
LET nattype = SFMT("%1(%2)", adstype, adssize)
|
|
WHEN adstype == "NVARCHAR"
|
|
OR adstype == "NVARCHAR2"
|
|
LET ifxtype = 202
|
|
LET ifxleng = adssize
|
|
LET nattype = SFMT("%1(%2)", adstype, adssize)
|
|
WHEN adstype == "DATE"
|
|
LET ifxtype = 7
|
|
LET ifxleng = 4
|
|
WHEN adstype == "TIME"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 1642
|
|
WHEN adstype == "TIMESTAMP"
|
|
OR adstype == "DATETIME"
|
|
LET ifxtype = 10
|
|
LET ifxleng = 4365
|
|
WHEN adstype == "BIGINT"
|
|
LET ifxtype = 5
|
|
LET ifxleng = 19 * 256
|
|
WHEN adstype == "TINYINT"
|
|
OR adstype == "SMALLINT"
|
|
LET ifxtype = 1
|
|
LET ifxleng = 2
|
|
WHEN adstype == "INTEGER"
|
|
LET ifxtype = 2
|
|
LET ifxleng = 4
|
|
WHEN adstype == "SERIAL"
|
|
LET ifxtype = 6
|
|
LET ifxleng = 4
|
|
WHEN adstype == "DOUBLE"
|
|
OR adstype == "REAL"
|
|
OR adstype == "SMALLFLOAT"
|
|
LET ifxtype = 4
|
|
LET ifxleng = 4
|
|
WHEN adstype == "FLOAT"
|
|
OR adstype == "DOUBLE PRECISION"
|
|
LET ifxtype = 3
|
|
LET ifxleng = 8
|
|
WHEN adstype = "BINARY"
|
|
OR adstype = "VARBINARY"
|
|
OR adstype = "LONGVARBINARY"
|
|
OR adstype = "BYTE"
|
|
LET ifxtype = 11
|
|
LET ifxleng = 56
|
|
WHEN adstype = "LONGVARCHAR"
|
|
OR adstype = "TEXT"
|
|
LET ifxtype = 12
|
|
LET ifxleng = 56
|
|
WHEN adstype MATCHES "DATETIME *"
|
|
CALL _fgldbsch_ads_encode_datetime(adstype, adsdtpr, adsscal)
|
|
RETURNING ifxtype, ifxleng
|
|
WHEN adstype MATCHES "INTERVAL *"
|
|
CALL _fgldbsch_ads_encode_interval(adstype, adsivpr, adsscal)
|
|
RETURNING ifxtype, ifxleng
|
|
END CASE
|
|
|
|
IF ifxtype>-1 AND adsnull=="NO" THEN
|
|
LET ifxtype = ifxtype + 256
|
|
END IF
|
|
|
|
RETURN nattype, ifxtype, ifxleng
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_get_selection_filter_ads(t,c)
|
|
DEFINE t,c STRING
|
|
DEFINE s STRING
|
|
LET s = " "
|
|
IF params.tabname IS NOT NULL THEN
|
|
LET s = s, " AND UPPER(",t,") = '",UPSHIFT(params.tabname),"'"
|
|
END IF
|
|
IF params.systabs=="N" THEN
|
|
LET s = s, " AND ", c, " != 'SYSTEM'"
|
|
END IF
|
|
IF params.dbowner IS NULL THEN
|
|
CALL _fgldbsch_owner_warning()
|
|
LET params.dbowner = params.username
|
|
END IF
|
|
IF params.dbowner IS NOT NULL THEN
|
|
LET s = s, " AND UPPER(",c,")='",UPSHIFT(params.dbowner),"'"
|
|
END IF
|
|
RETURN s
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_ads_start()
|
|
DEFINE stmt STRING
|
|
DEFINE dum CHAR(100)
|
|
|
|
WHENEVER ERROR CONTINUE
|
|
SELECT ORIGINAL_TYPE_NAME INTO dum FROM SYSTEM.TABLE_OF_COLUMNS WHERE 1=0
|
|
WHENEVER ERROR STOP
|
|
IF sqlca.sqlcode == 100 THEN
|
|
-- Since ADS 3.80 only!
|
|
LET stmt = "SELECT",
|
|
" TABLE_NAME,",
|
|
" COLUMN_NAME,",
|
|
" ORIGINAL_TYPE_NAME,",
|
|
" CHARACTER_MAXIMUM_LENGTH,",
|
|
" NUMERIC_PRECISION,",
|
|
" NUMERIC_SCALE,",
|
|
" DATETIME_PRECISION,",
|
|
" INTERVAL_PRECISION,",
|
|
" IS_NULLABLE,",
|
|
" ORDINAL_POSITION",
|
|
" FROM INFORMATION_SCHEMA.COLUMNS",
|
|
" WHERE COLUMN_NAME NOT LIKE '$%'",
|
|
_fgldbsch_get_selection_filter_ads("TABLE_NAME","TABLE_SCHEMA"),
|
|
" ORDER BY TABLE_NAME, ORDINAL_POSITION"
|
|
ELSE
|
|
LET stmt = "SELECT",
|
|
" TABLE_NAME,",
|
|
" COLUMN_NAME,",
|
|
" TYPE_NAME,",
|
|
" COLUMN_SIZE,",
|
|
" COLUMN_SIZE,",
|
|
" DECIMAL_DIGITS,",
|
|
" -1,",
|
|
" -1,",
|
|
" NULLABLE,",
|
|
" ORDINAL_POSITION",
|
|
" FROM SYSTEM.TABLE_OF_COLUMNS",
|
|
" WHERE COLUMN_NAME NOT LIKE '$%'",
|
|
_fgldbsch_get_selection_filter_ads("TABLE_NAME","TABLE_SCHEM"),
|
|
" ORDER BY TABLE_NAME, ORDINAL_POSITION"
|
|
END IF
|
|
|
|
WHENEVER ERROR CONTINUE
|
|
DECLARE ctc_ads CURSOR FROM stmt
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
OPEN ctc_ads
|
|
IF SQLCA.SQLCODE<0 THEN RETURN SQLCA.SQLCODE END IF
|
|
WHENEVER ERROR STOP
|
|
|
|
RETURN 0
|
|
|
|
END FUNCTION
|
|
|
|
FUNCTION _fgldbsch_extract_ads_next()
|
|
DEFINE tabname VARCHAR(200)
|
|
DEFINE colname VARCHAR(200)
|
|
DEFINE coltype VARCHAR(100)
|
|
DEFINE colchsze INTEGER
|
|
DEFINE colnmpre INTEGER
|
|
DEFINE colnmscl INTEGER
|
|
DEFINE coldtpre INTEGER
|
|
DEFINE colivpre INTEGER
|
|
DEFINE colnullc CHAR(3)
|
|
DEFINE colident INTEGER
|
|
DEFINE nattype STRING
|
|
DEFINE ifxtype INTEGER
|
|
DEFINE ifxleng INTEGER
|
|
|
|
WHILE TRUE
|
|
WHENEVER ERROR CONTINUE
|
|
FETCH ctc_ads INTO
|
|
tabname,
|
|
colname,
|
|
coltype,
|
|
colchsze,
|
|
colnmpre,
|
|
colnmscl,
|
|
coldtpre,
|
|
colivpre,
|
|
colnullc,
|
|
colident
|
|
|
|
WHENEVER ERROR STOP
|
|
IF SQLCA.SQLCODE < 0 THEN RETURN SQLCA.SQLCODE END IF
|
|
|
|
IF SQLCA.SQLCODE == NOTFOUND THEN
|
|
CLOSE ctc_ads
|
|
RETURN ( coldef.getLength() > 0 )
|
|
END IF
|
|
|
|
CALL _fgldbsch_convert_datatype_ads(
|
|
coltype,
|
|
colchsze,
|
|
colnmpre,
|
|
colnmscl,
|
|
coldtpre,
|
|
colivpre,
|
|
colnullc
|
|
) RETURNING
|
|
nattype,
|
|
ifxtype,
|
|
ifxleng
|
|
|
|
IF _fgldbsch_register_column(tabname, colname, nattype, ifxtype, ifxleng) THEN
|
|
EXIT WHILE
|
|
END IF
|
|
|
|
END WHILE
|
|
|
|
RETURN 1
|
|
|
|
END FUNCTION
|
|
|