activefacts-compositions 1.9.17 → 1.9.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/activefacts-compositions.gemspec +2 -2
  3. data/lib/activefacts/compositions/binary.rb +1 -1
  4. data/lib/activefacts/compositions/compositor.rb +16 -12
  5. data/lib/activefacts/compositions/datavault.rb +110 -115
  6. data/lib/activefacts/compositions/relational.rb +137 -94
  7. data/lib/activefacts/compositions/staging.rb +89 -27
  8. data/lib/activefacts/compositions/traits/datavault.rb +116 -49
  9. data/lib/activefacts/compositions/traits/rails.rb +2 -2
  10. data/lib/activefacts/compositions/version.rb +1 -1
  11. data/lib/activefacts/generator/doc/cwm.rb +6 -18
  12. data/lib/activefacts/generator/doc/ldm.rb +1 -1
  13. data/lib/activefacts/generator/etl/unidex.rb +341 -0
  14. data/lib/activefacts/generator/oo.rb +31 -14
  15. data/lib/activefacts/generator/rails/models.rb +6 -5
  16. data/lib/activefacts/generator/rails/schema.rb +5 -9
  17. data/lib/activefacts/generator/ruby.rb +2 -2
  18. data/lib/activefacts/generator/sql/mysql.rb +3 -184
  19. data/lib/activefacts/generator/sql/oracle.rb +3 -152
  20. data/lib/activefacts/generator/sql/postgres.rb +3 -145
  21. data/lib/activefacts/generator/sql/server.rb +3 -126
  22. data/lib/activefacts/generator/sql.rb +54 -422
  23. data/lib/activefacts/generator/summary.rb +15 -6
  24. data/lib/activefacts/generator/traits/expr.rb +41 -0
  25. data/lib/activefacts/generator/traits/sql/mysql.rb +280 -0
  26. data/lib/activefacts/generator/traits/sql/oracle.rb +265 -0
  27. data/lib/activefacts/generator/traits/sql/postgres.rb +287 -0
  28. data/lib/activefacts/generator/traits/sql/server.rb +262 -0
  29. data/lib/activefacts/generator/traits/sql.rb +538 -0
  30. metadata +13 -8
  31. data/lib/activefacts/compositions/docgraph.rb +0 -798
  32. data/lib/activefacts/compositions/staging/persistent.rb +0 -107
@@ -0,0 +1,280 @@
1
+ #
2
+ # ActiveFacts MySQL Traits
3
+ #
4
+ # Copyright (c) 2009-2016 Clifford Heath. Read the LICENSE file.
5
+ #
6
+ # Reserved words gathered from:
7
+ # https://dev.mysql.com/doc/refman/5.7/en/keywords.html
8
+ #
9
+ require 'digest/sha1'
10
+ require 'activefacts/metamodel'
11
+ require 'activefacts/compositions'
12
+ require 'activefacts/generator/traits/sql'
13
+
14
+ module ActiveFacts
15
+ module Generators
16
+ module Traits
17
+ # Options are comma or space separated:
18
+ # * underscore
19
+ module SQL
20
+ module MySQL
21
+ include Traits::SQL
22
+
23
+ def options
24
+ super.merge({
25
+ # no: [String, "no new options defined here"]
26
+ })
27
+ end
28
+
29
+ def defaults_and_options options
30
+ super
31
+ end
32
+
33
+ def process_options options
34
+ super
35
+ end
36
+
37
+ def data_type_context_class
38
+ MySQLDataTypeContext
39
+ end
40
+
41
+ # See https://dev.mysql.com/doc/refman/5.7/en/identifiers.html
42
+ def table_name_max
43
+ 64
44
+ end
45
+
46
+ def column_name_max
47
+ 64
48
+ end
49
+
50
+ def index_name_max
51
+ 64
52
+ end
53
+
54
+ def schema_name_max
55
+ 64
56
+ end
57
+
58
+ def schema_prefix
59
+ ''
60
+ end
61
+
62
+ def index_kind(index)
63
+ super
64
+ end
65
+
66
+ def choose_sql_type(type_name, value_constraint, component, options)
67
+ case MM::DataType.intrinsic_type(type_name)
68
+ when MM::DataType::TYPE_Integer
69
+ # The :auto_assign key is set for auto-assigned types, but with a nil value in foreign keys
70
+ if options.has_key?(:auto_assign)
71
+ options[:default] = ' AUTO_INCREMENT' if options[:auto_assign]
72
+ 'BIGINT'
73
+ else
74
+ super
75
+ end
76
+
77
+ when MM::DataType::TYPE_Money
78
+ 'DECIMAL'
79
+
80
+ when MM::DataType::TYPE_DateTime
81
+ 'DATETIME'
82
+
83
+ when MM::DataType::TYPE_Timestamp
84
+ 'DATETIME'
85
+
86
+ when MM::DataType::TYPE_Binary
87
+ case binary_surrogate(type_name, value_constraint, options)
88
+ when :guid_fk # A GUID surrogate that's auto-assigned elsewhere
89
+ options[:length] = 16
90
+ when :guid # A GUID
91
+ options[:length] = 16
92
+ options[:default] = " DEFAULT UNHEX(REPLACE(UUID(),'-',''))"
93
+ when :hash # A hash of the natural key
94
+ options[:length] = 20 # Assuming SHA-1. SHA-256 would need 32 bytes
95
+ leaves = component.root.natural_index.all_index_field.map(&:component)
96
+ # NDB Only, not InnoDB:
97
+ # options[:default] = " GENERATED ALWAYS AS (#{hash(concatenate(coalesce(as_text(safe_column_exprs(leaves)))))}) STORED"
98
+ options[:delayed] = trigger_hash_assignment(component, component.root.natural_index.all_index_field.map(&:component))
99
+ else # Not a surrogate
100
+ # MySQL has various non-standard blob types also
101
+ end
102
+ 'BINARY'
103
+
104
+ else
105
+ super
106
+ end
107
+ end
108
+
109
+ # Return an array of SQL statements that arrange for the hash_field
110
+ # to be populated with a hash of the values of the leaves.
111
+ def trigger_hash_assignment hash_field, leaves
112
+ table_name = safe_table_name(hash_field.root)
113
+ trigger_function = escape('assign_'+column_name(hash_field), 128)
114
+ [
115
+ %Q{
116
+ CREATE TRIGGER #{trigger_function} BEFORE INSERT ON #{table_name}
117
+ FOR EACH ROW SET #{safe_column_name(hash_field)} = #{
118
+ hash(concatenate(coalesce(as_text(safe_column_exprs(leaves, 'NEW')))))
119
+ }}.unindent
120
+ ]
121
+ end
122
+
123
+ # Some or all of the SQL expressions may have non-text values.
124
+ # Return an SQL expression that coerces them to text.
125
+ def as_text exprs
126
+ return exprs.map{|e| as_text(e)} if Array === exprs
127
+
128
+ Expression.new("CAST(#{exprs} AS CHAR)", MM::DataType::TYPE_String, exprs.is_mandatory)
129
+ end
130
+
131
+ # Return an SQL expression that concatenates the given expressions (which must yield a string type)
132
+ def concatenate expressions
133
+ Expression.new(
134
+ "CONCAT('|', #{expressions.map(&:to_s)*', '})",
135
+ MM::DataType::TYPE_String,
136
+ true
137
+ )
138
+ end
139
+
140
+ # Return an expression that yields a hash of the given expression
141
+ # SHA1 produces 40 hexadecimal digits
142
+ def hash expr, algo = nil
143
+ Expression.new("UNHEX(SHA1(#{expr}))", MM::DataType::TYPE_Binary, expr.is_mandatory)
144
+ end
145
+
146
+ # Reserved words cannot be used anywhere without quoting.
147
+ # Keywords have existing definitions, so should not be used without quoting.
148
+ # Both lists here are added to the supertype's lists
149
+ def reserved_words
150
+ @mysql_reserved_words ||= %w{
151
+ ACCESSIBLE ANALYZE CHANGE DATABASE DATABASES DAY_HOUR
152
+ DAY_MICROSECOND DAY_MINUTE DAY_SECOND DELAYED DISTINCTROW
153
+ DIV DUAL ENCLOSED ESCAPED EXPLAIN FLOAT4 FLOAT8 FORCE
154
+ FULLTEXT HIGH_PRIORITY HOUR_MICROSECOND HOUR_MINUTE
155
+ HOUR_SECOND INDEX INFILE INT1 INT2 INT3 INT4 INT8
156
+ IO_AFTER_GTIDS IO_BEFORE_GTIDS KEYS KILL LINEAR LINES
157
+ LOAD LOCK LONG LONGBLOB LONGTEXT LOW_PRIORITY MASTER_BIND
158
+ MASTER_SSL_VERIFY_SERVER_CERT MEDIUMBLOB MEDIUMINT
159
+ MEDIUMTEXT MIDDLEINT MINUTE_MICROSECOND MINUTE_SECOND
160
+ NO_WRITE_TO_BINLOG OPTIMIZE OPTIMIZER_COSTS OPTIONALLY
161
+ OUTFILE PURGE READ_WRITE REGEXP RENAME REPLACE REQUIRE
162
+ RLIKE SCHEMAS SECOND_MICROSECOND SEPARATOR SHOW SPATIAL
163
+ SQL_BIG_RESULT SQL_CALC_FOUND_ROWS SQL_SMALL_RESULT SSL
164
+ STARTING STORED STRAIGHT_JOIN TERMINATED TINYBLOB TINYINT
165
+ TINYTEXT UNLOCK UNSIGNED USE UTC_DATE UTC_TIME UTC_TIMESTAMP
166
+ VARCHARACTER VIRTUAL XOR YEAR_MONTH ZEROFILL _FILENAME
167
+ }
168
+ super + @mysql_reserved_words
169
+ end
170
+
171
+ def key_words
172
+ # These keywords should not be used for columns or tables:
173
+ @mysql_key_words ||= %w{
174
+ ACCOUNT AGAINST AGGREGATE ALGORITHM ANALYSE ASCII
175
+ AUTOEXTEND_SIZE AUTO_INCREMENT AVG_ROW_LENGTH BACKUP
176
+ BINLOG BLOCK BOOL BTREE BYTE CACHE CHANGED CHANNEL
177
+ CHARSET CHECKSUM CIPHER CLIENT CODE COLUMN_FORMAT COMMENT
178
+ COMPACT COMPLETION COMPRESSED COMPRESSION CONCURRENT
179
+ CONSISTENT CONTEXT CPU DATAFILE DATETIME DEFAULT_AUTH
180
+ DELAY_KEY_WRITE DES_KEY_FILE DIRECTORY DISABLE DISCARD
181
+ DISK DUMPFILE DUPLICATE ENABLE ENCRYPTION ENDS ENGINE
182
+ ENGINES ENUM ERROR ERRORS EVENT EVENTS EXCHANGE EXPANSION
183
+ EXPIRE EXPORT EXTENDED EXTENT_SIZE FAST FAULTS FIELDS
184
+ FILE_BLOCK_SIZE FIXED FLUSH FOLLOWS FORMAT GEOMETRY
185
+ GEOMETRYCOLLECTION GET_FORMAT GRANTS GROUP_REPLICATION
186
+ HASH HELP HOST HOSTS IDENTIFIED IGNORE_SERVER_IDS INDEXES
187
+ INITIAL_SIZE INSERT_METHOD INSTALL IO IO_THREAD IPC
188
+ ISSUER JSON KEY_BLOCK_SIZE LEAVES LESS LINESTRING LIST
189
+ LOCKS LOGFILE LOGS MASTER MASTER_AUTO_POSITION
190
+ MASTER_CONNECT_RETRY MASTER_DELAY MASTER_HEARTBEAT_PERIOD
191
+ MASTER_HOST MASTER_LOG_FILE MASTER_LOG_POS MASTER_PASSWORD
192
+ MASTER_PORT MASTER_RETRY_COUNT MASTER_SERVER_ID MASTER_SSL
193
+ MASTER_SSL_CA MASTER_SSL_CAPATH MASTER_SSL_CERT
194
+ MASTER_SSL_CIPHER MASTER_SSL_CRL MASTER_SSL_CRLPATH
195
+ MASTER_SSL_KEY MASTER_TLS_VERSION MASTER_USER
196
+ MAX_CONNECTIONS_PER_HOUR MAX_QUERIES_PER_HOUR MAX_ROWS
197
+ MAX_SIZE MAX_STATEMENT_TIME MAX_UPDATES_PER_HOUR
198
+ MAX_USER_CONNECTIONS MEDIUM MEMORY MICROSECOND MIGRATE
199
+ MIN_ROWS MODE MODIFY MULTILINESTRING MULTIPOINT
200
+ MULTIPOLYGON MUTEX MYSQL_ERRNO NDB NDBCLUSTER NEVER
201
+ NODEGROUP NONBLOCKING NO_WAIT NVARCHAR OLD_PASSWORD ONE
202
+ OWNER PACK_KEYS PAGE PARSER PARSE_GCOL_EXPR PARTITIONING
203
+ PARTITIONS PASSWORD PHASE PLUGIN PLUGINS PLUGIN_DIR
204
+ POINT POLYGON PORT PREV PROCESSLIST PROFILE PROFILES
205
+ PROXY QUARTER QUERY QUICK READ_ONLY REBUILD RECOVER
206
+ REDOFILE REDO_BUFFER_SIZE REDUNDANT RELAY RELAYLOG
207
+ RELAY_LOG_FILE RELAY_LOG_POS RELAY_THREAD RELOAD REMOVE
208
+ REORGANIZE REPAIR REPLICATE_DO_DB REPLICATE_DO_TABLE
209
+ REPLICATE_IGNORE_DB REPLICATE_IGNORE_TABLE REPLICATE_REWRITE_DB
210
+ REPLICATE_WILD_DO_TABLE REPLICATE_WILD_IGNORE_TABLE
211
+ REPLICATION RESET RESUME REVERSE ROTATE ROW_FORMAT RTREE
212
+ SCHEDULE SERIAL SHARE SHUTDOWN SIGNED SLAVE SLOW SNAPSHOT
213
+ SOCKET SONAME SOUNDS SQL_AFTER_GTIDS SQL_AFTER_MTS_GAPS
214
+ SQL_BEFORE_GTIDS SQL_BUFFER_RESULT SQL_CACHE SQL_NO_CACHE
215
+ SQL_THREAD SQL_TSI_DAY SQL_TSI_HOUR SQL_TSI_MINUTE
216
+ SQL_TSI_MONTH SQL_TSI_QUARTER SQL_TSI_SECOND SQL_TSI_WEEK
217
+ SQL_TSI_YEAR STACKED STARTS STATS_AUTO_RECALC
218
+ STATS_PERSISTENT STATS_SAMPLE_PAGES STATUS STOP STORAGE
219
+ STRING SUBJECT SUBPARTITION SUBPARTITIONS SUPER SUSPEND
220
+ SWAPS SWITCHES TABLES TABLESPACE TABLE_CHECKSUM TEMPTABLE
221
+ TEXT THAN TIMESTAMPADD TIMESTAMPDIFF TRIGGERS TYPES
222
+ UNDEFINED UNDOFILE UNDO_BUFFER_SIZE UNICODE UNINSTALL
223
+ UPGRADE USER_RESOURCES USE_FRM VALIDATION VARIABLES
224
+ WAIT WARNINGS WEEK WEIGHT_STRING X509 XA XID
225
+ }
226
+ super + @mysql_key_words
227
+ end
228
+
229
+ def open_escape
230
+ '`'
231
+ end
232
+
233
+ def close_escape
234
+ '`'
235
+ end
236
+
237
+ def index_kind(index)
238
+ ''
239
+ end
240
+
241
+ class MySQLDataTypeContext < SQLDataTypeContext
242
+ def integer_ranges
243
+ [
244
+ ['TINYINT', -2**7, 2**7-1],
245
+ ['TINYINT UNSIGNED', 0, 2**8-1],
246
+ ['MEDIUMINT', -2**23, 2**23-1],
247
+ ] + super
248
+ end
249
+
250
+ # MySQL also has a BIT type, but you can specify a size up to BIT(64). This is better.
251
+ def boolean_type
252
+ 'BOOLEAN' # Which is a synonym for TINYINT(1), stores 0 or 1
253
+ end
254
+
255
+ def boolean_expr safe_column_name
256
+ "#{safe_column_name} = 1"
257
+ end
258
+
259
+ def default_char_type
260
+ (@unicode ? 'N' : '') +
261
+ 'CHAR'
262
+ end
263
+
264
+ def default_varchar_type
265
+ (@unicode ? 'N' : '') +
266
+ 'VARCHAR'
267
+ end
268
+
269
+ def date_time_type
270
+ # MySQL also has TIMESTAMP values, but those run from 1970/01/01 through 2038/01/19
271
+ # DATETIME runs from 1000/01/01 through 9999/01/01
272
+ 'DATETIME'
273
+ end
274
+ end
275
+ end
276
+
277
+ end
278
+ end
279
+ end
280
+ end
@@ -0,0 +1,265 @@
1
+ #
2
+ # ActiveFacts Oracle SQL Traits
3
+ #
4
+ # Copyright (c) 2009-2016 Clifford Heath. Read the LICENSE file.
5
+ #
6
+ # Reserved words gathered from:
7
+ # https://docs.oracle.com/cd/B28359_01/appdev.111/b31231/appb.htm
8
+ #
9
+ require 'digest/sha1'
10
+ require 'activefacts/metamodel'
11
+ require 'activefacts/compositions'
12
+ require 'activefacts/generator/traits/sql'
13
+
14
+ module ActiveFacts
15
+ module Generators
16
+ module Traits
17
+ # Options are comma or space separated:
18
+ # * underscore
19
+ module SQL
20
+ module Oracle
21
+ include Traits::SQL
22
+
23
+ # Options available in this flavour of SQL
24
+ def options
25
+ super.merge({
26
+ # no: [String, "no new options defined here"]
27
+ })
28
+ end
29
+
30
+ # The options parameter overrides any default options set by sub-traits
31
+ def defaults_and_options options
32
+ {'tables' => 'shout', 'columns' => 'shout'}.merge(options)
33
+ end
34
+
35
+ def process_options options
36
+ super
37
+ end
38
+
39
+ def data_type_context_class
40
+ OracleDataTypeContext
41
+ end
42
+
43
+ # See https://docs.oracle.com/database/122/NEWFT/new-features.htm
44
+ # Identifier lengths were 30 *bytes* prior to Oracle 12C
45
+ def table_name_max
46
+ 128
47
+ end
48
+
49
+ def column_name_max
50
+ 128
51
+ end
52
+
53
+ def index_name_max
54
+ 128
55
+ end
56
+
57
+ def schema_name_max
58
+ 128 # Was 8 characters
59
+ end
60
+
61
+ def schema_prefix
62
+ ''
63
+ end
64
+
65
+ def index_kind(index)
66
+ super
67
+ end
68
+
69
+ def choose_sql_type(type_name, value_constraint, component, options)
70
+ type = MM::DataType.intrinsic_type(type_name)
71
+ case type
72
+ when MM::DataType::TYPE_Integer
73
+ # The :auto_assign key is set for auto-assigned types, but with a nil value in foreign keys
74
+ if options.has_key?(:auto_assign)
75
+ options[:default] = ' GENERATED BY DEFAULT ON NULL AS IDENTITY' if options[:auto_assign]
76
+ 'LONGINTEGER'
77
+ else
78
+ super
79
+ end
80
+
81
+ when MM::DataType::TYPE_Money
82
+ 'MONEY'
83
+
84
+ when MM::DataType::TYPE_DateTime
85
+ 'DATETIME'
86
+
87
+ when MM::DataType::TYPE_Timestamp
88
+ 'DATETIME'
89
+
90
+ when MM::DataType::TYPE_Binary
91
+ case binary_surrogate(type_name, value_constraint, options)
92
+ when :guid_fk # A surrogate that's auto-assigned elsewhere
93
+ options[:length] = 16 # This will display as 32 hex digits
94
+ 'RAW'
95
+ when :guid # A GUID
96
+ options[:length] = 16
97
+ options[:default] = " DEFAULT SYS_GUID()"
98
+ 'RAW'
99
+ when :hash # A hash of the natural key
100
+ options[:length] = 20 # Assuming SHA-1. SHA-256 would need 32 bytes
101
+ leaves = component.root.natural_index.all_index_field.map(&:component)
102
+ options[:default] = " GENERATED ALWAYS AS #{hash(concatenate(coalesce(as_text(safe_column_exprs(leaves)))))}"
103
+ 'RAW'
104
+ else
105
+ 'LOB' # Not a surrogate, just use the type
106
+ end
107
+ else
108
+ super
109
+ end
110
+ end
111
+
112
+ =begin
113
+ # Return an array of SQL statements that arrange for the hash_field
114
+ # to be populated with a hash of the values of the leaves.
115
+ def trigger_hash_assignment hash_field, leaves
116
+ table_name = safe_table_name(hash_field.root)
117
+ trigger_function = escape('assign_'+column_name(hash_field), 128)
118
+ [
119
+ %Q{
120
+ CREATE OR REPLACE
121
+ FUNCTION #{trigger_function}() RETURN RAW DETERMINISTIC
122
+ AS
123
+ PRAGMA UDF;
124
+ BEGIN
125
+ RETURN #{hash(concatenate(coalesce(as_text(safe_column_exprs(leaves, 'NEW')))))};
126
+ END #{trigger_function}}.
127
+ unindent,
128
+ %Q{ -- This is the Postgres syntax
129
+ CREATE TRIGGER trig_#{trigger_function}
130
+ BEFORE INSERT OR UPDATE ON #{table_name}
131
+ FOR EACH ROW EXECUTE PROCEDURE #{trigger_function}()}.
132
+ unindent
133
+ ]
134
+ end
135
+ =end
136
+
137
+ # Some or all of the SQL expressions may have non-text values.
138
+ # Return an SQL expression that coerces them to text.
139
+ def as_text exprs
140
+ return exprs.map{|e| as_text(e)} if Array === exprs
141
+
142
+ Expression.new("#{exprs}", MM::DataType::TYPE_String, exprs.is_mandatory)
143
+ end
144
+
145
+ # Return an SQL expression that concatenates the given expressions (which must yield a string type)
146
+ def concatenate expressions
147
+ Expression.new(
148
+ "'|' || " +
149
+ expressions.map(&:to_s) * " || '|' || " +
150
+ " || '|'",
151
+ MM::DataType::TYPE_String,
152
+ true
153
+ )
154
+ end
155
+
156
+ # Return an expression that yields a hash of the given expression
157
+ def hash expr, algo = 'SHA-1'
158
+ # Since Oracle 12.1:
159
+ Expression.new("STANDARD_HASH(#{expr}, '#{algo}')", MM::DataType::TYPE_Binary, expr.is_mandatory)
160
+
161
+ # Expression.new("utl_raw.cast_to_raw(dbms_crypto.hash(#{expr}, dbms_crypto.hash_#{algo}))", MM::DataType::TYPE_Binary, expr.is_mandatory)
162
+ end
163
+
164
+ # Reserved words cannot be used anywhere without quoting.
165
+ # Keywords have existing definitions, so should not be used without quoting.
166
+ # Both lists here are added to the supertype's lists
167
+ def reserved_words
168
+ @oracle_reserved_words ||= %w{
169
+ ACCESS ARRAYLEN AUDIT CLUSTER COMMENT COMPRESS EXCLUSIVE
170
+ IDENTIFIED INDEX INITIAL LOCK LONG MAXEXTENTS MINUS
171
+ MODE MODIFY NOAUDIT NOCOMPRESS NOTFOUND NOWAIT OFFLINE
172
+ ONLINE PCTFREE RAW RENAME RESOURCE ROWID ROWLABEL ROWNUM
173
+ SHARE SQLBUF SUCCESSFUL SYNONYM SYSDATE UID VALIDATE
174
+ VARCHAR2
175
+ }
176
+ @oracle_plsql_reserved_words ||= %w{
177
+ ABORT ACCEPT ACCESS ARRAYLEN ASSERT ASSIGN BASE_TABLE
178
+ BINARY_INTEGER BODY CHAR_BASE CLUSTER CLUSTERS COLAUTH
179
+ COMPRESS CONSTANT CRASH CURRVAL DATABASE DATA_BASE DBA
180
+ DEBUGOFF DEBUGON DEFINITION DELAY DELTA DIGITS DISPOSE
181
+ ELSIF ENTRY EXCEPTION_INIT FORM GENERIC IDENTIFIED INDEX
182
+ INDEXES LIMITED MINUS MLSLABEL MODE NEXTVAL NOCOMPRESS
183
+ NUMBER_BASE PACKAGE PCTFREE POSITIVE PRAGMA PRIVATE
184
+ RAISE RECORD REMR RENAME RESOURCE REVERSE ROWID ROWLABEL
185
+ ROWNUM ROWTYPE RUN SEPARATE SQLERRM STDDEV SUBTYPE
186
+ TABAUTH TABLES TASK TERMINATE USE VARCHAR2 VARIANCE
187
+ VIEWS XOR
188
+ }
189
+ super + @oracle_reserved_words
190
+ end
191
+
192
+ def key_words
193
+ # These keywords should not be used for columns or tables:
194
+ @oracle_key_words ||= %w{
195
+ ANALYZE ARCHIVE ARCHIVELOG BACKUP BECOME BLOCK BODY
196
+ CACHE CANCEL CHANGE CHECKPOINT COMPILE CONTENTS CONTROLFILE
197
+ DATABASE DATAFILE DBA DISABLE DISMOUNT DUMP ENABLE
198
+ EVENTS EXCEPTIONS EXPLAIN EXTENT EXTERNALLY FLUSH FORCE
199
+ FREELIST FREELISTS INITRANS LAYER LISTS LOGFILE MANAGE
200
+ MANUAL MAXDATAFILES MAXINSTANCES MAXLOGFILES MAXLOGHISTORY
201
+ MAXLOGMEMBERS MAXTRANS MINEXTENTS MOUNT NOARCHIVELOG
202
+ NOCACHE NOCYCLE NOMAXVALUE NOMINVALUE NOORDER NORESETLOGS
203
+ NORMAL NOSORT OPTIMAL OWN PACKAGE PARALLEL PCTINCREASE
204
+ PCTUSED PLAN PRIVATE PROFILE QUOTA RECOVER RESETLOGS
205
+ RESTRICTED REUSE ROLES SCN SEGMENT SHARED SNAPSHOT SORT
206
+ STATEMENT_ID STATISTICS STOP STORAGE SWITCH TABLES
207
+ TABLESPACE THREAD TRACING TRIGGERS UNLIMITED USE
208
+ }
209
+ super + @oracle_key_words
210
+ end
211
+
212
+ def open_escape
213
+ '"'
214
+ end
215
+
216
+ def close_escape
217
+ '"'
218
+ end
219
+
220
+ def index_kind(index)
221
+ ''
222
+ end
223
+
224
+ class OracleDataTypeContext < SQLDataTypeContext
225
+ def integer_ranges
226
+ [
227
+ ['SHORTINTEGER', -2**15, 2**15-1], # The standard says -10^5..10^5 (less than 16 bits)
228
+ ['INTEGER', -2**31, 2**31-1], # The standard says -10^10..10^10 (more than 32 bits!)
229
+ ['LONGINTEGER', -2**63, 2**63-1], # The standard says -10^19..10^19 (less than 64 bits)
230
+ ]
231
+ end
232
+
233
+ # PL/SQL has a BOOLEAN type, but Oracle databases do not, see
234
+ # https://docs.oracle.com/database/121/LNPLS/datatypes.htm#LNPLS348
235
+ def boolean_type
236
+ 'CHAR(1)' # Probably should put a CHECK '0' or '1' here
237
+ end
238
+
239
+ # Ugly, but safe (Oracle's internal schema tables use 'Y' and 'N'):
240
+ def boolean_expr safe_column_name
241
+ "(#{safe_column_name} = '1' OR #{safe_column_name} = 'Y')"
242
+ end
243
+
244
+ # There is no performance benefit in using fixed-length CHAR fields,
245
+ # and an added burden of trimming the implicitly added white-space
246
+ def default_char_type
247
+ (@unicode ? 'N' : '') +
248
+ 'VARCHAR'
249
+ end
250
+
251
+ def default_varchar_type
252
+ (@unicode ? 'N' : '') +
253
+ 'VARCHAR'
254
+ end
255
+
256
+ def date_time_type
257
+ 'TIMESTAMP'
258
+ end
259
+ end
260
+ end
261
+
262
+ end
263
+ end
264
+ end
265
+ end