sneaql 0.0.8-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,224 @@
1
+ require 'zip/zip'
2
+ require 'fileutils'
3
+ require 'logger'
4
+
5
+ #top level namespace for sneaql objects
6
+ module Sneaql
7
+ # contains the base classes for the extendable parts of sneaql:
8
+ # commands (the actual commands specified in sneaql tags)
9
+ # repo_managers (used to pull the sql files from a remote or local source)
10
+ # metadata managers (to get information about each step)
11
+ # in addition to the base classes, the mapped class/class_map
12
+ # utilities are used to provide a dynamic class system
13
+ # this class system allows you to register a class under a type
14
+ # you can later look up the class by type and a text identifier
15
+ # then instantiate a new instance from there
16
+ module Core
17
+ # global map of all classes
18
+ @@class_map = {}
19
+
20
+ # allows external access to class_map for testing purposes
21
+ def self.class_map
22
+ @@class_map
23
+ end
24
+
25
+ # adds a new class to the map
26
+ # @param [Symbol] type class type (user settable, can be :command, :repo_manager, etc)
27
+ # @param [Hash] mapped_class_hash in the format { text: text, mapped_class: mapped_class }
28
+ def self.add_mapped_class(type, mapped_class_hash)
29
+ @@class_map[type] == [] unless @@class_map.keys.include?(type)
30
+ @@class_map[type] << mapped_class_hash
31
+ end
32
+
33
+ # makes sure that the type exists before appending the class information
34
+ # @param [Symbol] type class type (user settable, can be :command, :repo_manager, etc)
35
+ def self.insure_type_exists(type)
36
+ @@class_map[type] = [] unless @@class_map.key?(type)
37
+ end
38
+
39
+ # returns the class referenced by the type/text combination
40
+ # @param [Symbol] type class type (user settable, can be :command, :repo_manager, etc)
41
+ # @param [String] text to when searching within this type
42
+ # @return [Class] returns the class you are searching for
43
+ def self.find_class(type, text)
44
+ @@class_map[type].each do |t|
45
+ return t[:mapped_class] if t[:text] == text
46
+ end
47
+ end
48
+
49
+ # Handles registration of a class to the class_map
50
+ # Ignores duplicate definitions if they occur
51
+ class RegisterMappedClass
52
+ # Registers the class into the class_map.
53
+ # @param [Symbol] type class type (user settable, can be :command, :repo_manager, etc)
54
+ # @param [String] text to when searching within this type
55
+ # @param [Class] mapped_class class to be returned when search matches type and text
56
+ def initialize(type, text, mapped_class)
57
+ Sneaql::Core.insure_type_exists(type)
58
+ # check to see if the reference text is already being used by this type
59
+ unless Sneaql::Core.class_map[type].map { |c| c[:text] }.include?(text)
60
+ Sneaql::Core.add_mapped_class(
61
+ type,
62
+ { text: text, mapped_class: mapped_class }
63
+ )
64
+ end
65
+ end
66
+ end
67
+
68
+ # Base class for SneaQL command tags
69
+ class SneaqlCommand
70
+ # this is the base object for a sneaql command
71
+ # subclass this and override the action method
72
+ # @param [Object] jdbc_connection JDBC connection object to database
73
+ # @param [Sneaql::Core::ExpressionHandler] expression_handler
74
+ # @param [Sneaql::Core::RecordsetManager] recordset_manager
75
+ # @param [String] statement SQL statement provided in body, with all variables resolved
76
+ # @param [Logger] logger object otherwise will default to new Logger
77
+ def initialize(jdbc_connection, expression_handler, recordset_manager, statement, logger = nil)
78
+ @logger = logger ? logger : Logger.new(STDOUT)
79
+
80
+ @jdbc_connection = jdbc_connection
81
+ @expression_handler = expression_handler
82
+ @statement = statement
83
+ @recordset_manager = recordset_manager
84
+ end
85
+
86
+ # override this method with the actual code for your command
87
+ def action
88
+ nil
89
+ end
90
+
91
+ # override with an array in the form [:expression, :operator]
92
+ def arg_definition
93
+ []
94
+ end
95
+
96
+ # override this if you have a complex tag structure
97
+ # @param [Array] args argument array to validate
98
+ # @return [Boolean] true if all arguments are valid
99
+ def validate_args(args)
100
+ return false if args.length != arg_definition.length
101
+ return true if (arg_definition == []) and (args == [])
102
+ valid = []
103
+ args.each_with_index do |a, i|
104
+ case
105
+ when arg_definition[i] == :variable then
106
+ valid << valid_variable?(a)
107
+ when arg_definition[i] == :expression then
108
+ valid << valid_expression?(a)
109
+ when arg_definition[i] == :operator then
110
+ valid << valid_operator?(a)
111
+ when arg_definition[i] == :recordset then
112
+ valid << valid_recordset?(a)
113
+ else valid << false end
114
+ end
115
+ @logger.debug(valid)
116
+ !valid.include?(false)
117
+ end
118
+
119
+ # validates that the value is a valid variable name
120
+ # @param [String] a value to test
121
+ # @return [Boolean]
122
+ def valid_variable?(a)
123
+ @expression_handler.valid_session_variable_name?(a.to_s.strip)
124
+ end
125
+
126
+ # validates that the value is a valid expression
127
+ # @param [String, Float, Fixnum] a value to test
128
+ # @return [Boolean]
129
+ def valid_expression?(a)
130
+ @expression_handler.valid_expression_reference?(a.to_s.strip)
131
+ end
132
+
133
+ # validates that the value is a valid operator
134
+ # @param [String] a value to test
135
+ # @return [Boolean]
136
+ def valid_operator?(a)
137
+ @expression_handler.valid_operators.include?(a.to_s.strip)
138
+ end
139
+
140
+ # validates that the value is a valid recordset name
141
+ # @param [String] a value to test
142
+ # @return [Boolean]
143
+ def valid_recordset?(a)
144
+ @recordset_manager.valid_recordset_name?(a.to_s.strip)
145
+ end
146
+
147
+ private
148
+
149
+ # these are set during initialize
150
+ # reference to jdbc connection object
151
+ attr_accessor :jdbc_connection
152
+
153
+ # reference to expression handler object for this transform
154
+ attr_accessor :expression_handler
155
+
156
+ # actual sql statement with all variables dereferenced
157
+ attr_accessor :statement
158
+ end # class
159
+
160
+ # base class for repo managers
161
+ class RepoDownloadManager
162
+ # this is the directory that the repo operates in
163
+ attr_reader :repo_base_dir
164
+
165
+ # @param [Hash] params parameters passed to transform will be passed here
166
+ # @param [Logger] logger object otherwise will default to new Logger
167
+ def initialize(params, logger = nil)
168
+ @logger = logger ? logger : Logger.new(STDOUT)
169
+
170
+ @repo_base_dir = "#{params[:repo_base_dir]}/#{params[:transform_name]}"
171
+ @params = params
172
+
173
+ # perform the actual actions of managing the repo
174
+ manage_repo
175
+ end
176
+
177
+ # method to drop and rebuild the specified directory
178
+ # all files and subdirectories will be destroyed
179
+ # @param [String] directory
180
+ def drop_and_rebuild_directory(directory)
181
+ @logger.info("dropping and recreating repo directory #{directory}")
182
+ FileUtils.remove_dir(directory) if Dir.exist?(directory)
183
+ FileUtils.mkdir_p(directory)
184
+ end
185
+
186
+ # override in your implementation
187
+ def manage_repo
188
+ nil
189
+ end
190
+
191
+ # copied this from the internet
192
+ # http://www.markhneedham.com/blog/2008/10/02/ruby-unzipping-a-file-using-rubyzip/
193
+ def unzip_file(file, destination)
194
+ ::Zip::ZipFile.open(file) do |zip_file|
195
+ zip_file.each do |f|
196
+ f_path = File.join(destination, f.name)
197
+ FileUtils.mkdir_p(File.dirname(f_path))
198
+ zip_file.extract(f, f_path) unless File.exist?(f_path)
199
+ end
200
+ end
201
+ end
202
+ end
203
+
204
+ # abstracted to allow this metadata to come from any source
205
+ class StepMetadataManager
206
+ # value should be array of metadata hashes in the form `{ step_number: j['step_number'], step_file: j['step_file'] }`
207
+ attr_reader :steps
208
+
209
+ # @param [Hash] params parameters passed to transform will be passed here
210
+ # @param [Logger] logger object otherwise will default to new Logger
211
+ def initialize(params, logger = nil)
212
+ @logger = logger ? logger : Logger.new(STDOUT)
213
+ @params = params
214
+ manage_steps
215
+ end
216
+
217
+ # override with a method that will override steps with an array of
218
+ # steps in the format :step_number, :step_file
219
+ def manage_steps
220
+ nil
221
+ end
222
+ end
223
+ end
224
+ end
@@ -0,0 +1,346 @@
1
+ require 'jdbc_helpers'
2
+ require_relative 'base.rb'
3
+ require_relative 'exceptions.rb'
4
+
5
+ module Sneaql
6
+ module Core
7
+ # Core Sneaql language command tags.
8
+ # You can create your own tags by extending
9
+ # Sneaql::Core::SneaqlCommand and overriding the
10
+ # action method. You should also override arg_definition
11
+ # and potentially validate_args if have a complex argument
12
+ # structure.
13
+ module Commands
14
+ # assigns a session variable to a provided value
15
+ class SneaqlAssign < Sneaql::Core::SneaqlCommand
16
+ Sneaql::Core::RegisterMappedClass.new(
17
+ :command,
18
+ 'assign',
19
+ Sneaql::Core::Commands::SneaqlAssign
20
+ )
21
+
22
+ # @param [String] var_name
23
+ # @param [String] value expression (must be a string)
24
+ def action(var_name, value)
25
+ @expression_handler.set_session_variable(var_name, value)
26
+ end
27
+
28
+ # argument types
29
+ def arg_definition
30
+ [:variable, :expression]
31
+ end
32
+ end
33
+
34
+ # assigns a session variable to a value returned from a sql query
35
+ class SneaqlAssignResult < Sneaql::Core::SneaqlCommand
36
+ Sneaql::Core::RegisterMappedClass.new(
37
+ :command,
38
+ 'assign_result',
39
+ Sneaql::Core::Commands::SneaqlAssignResult
40
+ )
41
+
42
+ # run the query... then assign the result to a session variable
43
+ # @param [String] target_var_name
44
+ def action(target_var_name)
45
+ @expression_handler.set_session_variable(
46
+ target_var_name,
47
+ sql_result
48
+ )
49
+ end
50
+
51
+ # argument types
52
+ def arg_definition
53
+ [:variable]
54
+ end
55
+
56
+ # returns value at first row/field in result set
57
+ def sql_result
58
+ JDBCHelpers::SingleValueFromQuery.new(
59
+ @jdbc_connection,
60
+ @statement,
61
+ @logger
62
+ ).result
63
+ end
64
+ end
65
+
66
+ # executes a sql statement
67
+ class SneaqlExecute < Sneaql::Core::SneaqlCommand
68
+ Sneaql::Core::RegisterMappedClass.new(
69
+ :command,
70
+ 'execute',
71
+ Sneaql::Core::Commands::SneaqlExecute
72
+ )
73
+
74
+ # execute sql statement
75
+ # last_statement_rows_affected is always set...
76
+ def action
77
+ @expression_handler.set_session_variable(
78
+ 'last_statement_rows_affected',
79
+ rows_affected
80
+ )
81
+ end
82
+
83
+ # @return [Fixnum] rows affected by SQL statement
84
+ def rows_affected
85
+ JDBCHelpers::Execute.new(
86
+ @jdbc_connection,
87
+ @statement,
88
+ @logger
89
+ ).rows_affected
90
+ end
91
+ end
92
+
93
+ # executes a sql statement if the condition evaluates to true
94
+ class SneaqlExecuteIf < Sneaql::Core::SneaqlCommand
95
+ Sneaql::Core::RegisterMappedClass.new(
96
+ :command,
97
+ 'execute_if',
98
+ Sneaql::Core::Commands::SneaqlExecuteIf
99
+ )
100
+
101
+ # @param [String] left_value expression as left operand
102
+ # @param [String] operator comparison operator supported by expression handler
103
+ # @param [String] right_value expression as right operand
104
+ def action(left_value, operator, right_value)
105
+ if @expression_handler.compare_expressions(operator, left_value, right_value)
106
+ @expression_handler.set_session_variable(
107
+ 'last_statement_rows_affected',
108
+ rows_affected
109
+ )
110
+ end
111
+ end
112
+
113
+ # argument types
114
+ def arg_definition
115
+ [:expression, :operator, :expression]
116
+ end
117
+
118
+ # @return [Fixnum] rows affected by SQL statement
119
+ def rows_affected
120
+ JDBCHelpers::Execute.new(
121
+ @jdbc_connection,
122
+ @statement,
123
+ @logger
124
+ ).rows_affected
125
+ end
126
+ end
127
+
128
+ # compares the result of a sql statement against an argument
129
+ # raises error if the comparison does not evaluate to true
130
+ # the first field of the first record is used for the comparison
131
+ class SneaqlTest < Sneaql::Core::SneaqlCommand
132
+ Sneaql::Core::RegisterMappedClass.new(
133
+ :command,
134
+ 'test',
135
+ Sneaql::Core::Commands::SneaqlTest
136
+ )
137
+
138
+ # @param [String] operator comparison operator supported by expression handler
139
+ # @param [String] value_to_test expression as right operand
140
+ def action(operator, value_to_test)
141
+ unless @expression_handler.compare_expressions(
142
+ operator,
143
+ sql_result,
144
+ value_to_test
145
+ )
146
+ raise Sneaql::Exceptions::SQLTestExitCondition
147
+ end
148
+ end
149
+
150
+ # argument types
151
+ def arg_definition
152
+ [:operator, :expression]
153
+ end
154
+
155
+ # returns value at first row/field in result set
156
+ def sql_result
157
+ JDBCHelpers::SingleValueFromQuery.new(
158
+ @jdbc_connection,
159
+ @statement,
160
+ @logger
161
+ ).result
162
+ end
163
+ end
164
+
165
+ # raises an error to exit the transform if the condition evaluates to true
166
+ class SneaqlExitIf < Sneaql::Core::SneaqlCommand
167
+ Sneaql::Core::RegisterMappedClass.new(
168
+ :command,
169
+ 'exit_if',
170
+ Sneaql::Core::Commands::SneaqlExitIf
171
+ )
172
+
173
+ # @param [String] operand1 expression as left operand
174
+ # @param [String] operator comparison operator supported by expression handler
175
+ # @param [String] operand2 expression as right operand
176
+ def action(operand1, operator, operand2)
177
+ if @expression_handler.compare_expressions(operator, operand1, operand2)
178
+ raise Sneaql::Exceptions::SQLTestExitCondition
179
+ end
180
+ end
181
+
182
+ # argument types
183
+ def arg_definition
184
+ [:expression, :operator, :expression]
185
+ end
186
+ end
187
+
188
+ # raises an error to exit the transform step if the comdition evaluates to true
189
+ # note that this error needs to be handled accordingly in the calling
190
+ # procedure as all other errors will end the transform
191
+ class SneaqlExitStepIf < Sneaql::Core::SneaqlCommand
192
+ Sneaql::Core::RegisterMappedClass.new(
193
+ :command,
194
+ 'exit_step_if',
195
+ Sneaql::Core::Commands::SneaqlExitStepIf
196
+ )
197
+
198
+ # @param [String] operand1 expression as left operand
199
+ # @param [String] operator comparison operator supported by expression handler
200
+ # @param [String] operand2 expression as right operand
201
+ def action(operand1, operator, operand2)
202
+ if @expression_handler.compare_expressions(operator, operand1, operand2)
203
+ raise Sneaql::Exceptions::SQLTestStepExitCondition
204
+ end
205
+ end
206
+
207
+ # argument types
208
+ def arg_definition
209
+ [:expression, :operator, :expression]
210
+ end
211
+ end
212
+
213
+ # runs the query then stores the array of hashes into the recordset hash
214
+ class SneaqlRecordsetFromQuery < Sneaql::Core::SneaqlCommand
215
+ Sneaql::Core::RegisterMappedClass.new(
216
+ :command,
217
+ 'recordset',
218
+ Sneaql::Core::Commands::SneaqlRecordsetFromQuery
219
+ )
220
+
221
+ # @param [String] recordset_name name of the recordset in which to store the results
222
+ def action(recordset_name)
223
+ r = query_results
224
+ @logger.debug "adding #{r.length} recs as #{recordset_name}"
225
+ @recordset_manager.store_recordset(recordset_name, r)
226
+ end
227
+
228
+ # argument types
229
+ def arg_definition
230
+ [:recordset]
231
+ end
232
+
233
+ # @return [Array] returns array of hashes from SQL results
234
+ def query_results
235
+ JDBCHelpers::QueryResultsToArray.new(
236
+ @jdbc_connection,
237
+ @statement,
238
+ @logger
239
+ ).results
240
+ end
241
+ end
242
+
243
+ # iterates a recordset and runs the sql statement for each record
244
+ class SneaqlIterateRecordset < Sneaql::Core::SneaqlCommand
245
+ Sneaql::Core::RegisterMappedClass.new(
246
+ :command,
247
+ 'iterate',
248
+ Sneaql::Core::Commands::SneaqlIterateRecordset
249
+ )
250
+
251
+ # @param [*Array] args parameters for recordset expression in the format
252
+ def action(*args)
253
+ if args.size == 1
254
+ iterate_all_records(*args)
255
+ elsif ((args.size - 1) % 4) == 0
256
+ iterate_records_conditionally(*args)
257
+ end
258
+ end
259
+
260
+ # custom method for argument validation
261
+ # @param [Array] args
262
+ # @return [Boolean]
263
+ def validate_args(args)
264
+ if args.size == 1
265
+ return valid_recordset?(args[0])
266
+ elsif ((args.size - 1) % 4) == 0
267
+ valid = []
268
+ valid << valid_recordset?(args[0])
269
+ args[1..args.length - 1].each_slice(4) do |s|
270
+ if ['include', 'exclude'].include?(s[0])
271
+ valid << true
272
+ else
273
+ valid << false
274
+ end
275
+ # field names have the same rules as recordset names for now
276
+ valid << valid_recordset?(s[1])
277
+ valid << valid_operator?(s[2])
278
+ valid << valid_expression?(s[3])
279
+ end
280
+ !valid.include?(false)
281
+ else
282
+ return false
283
+ end
284
+ end
285
+
286
+ # @param [String] recordset recordset to iterate
287
+ def iterate_all_records(recordset)
288
+ @logger.info "iterating recordset #{recordset}..."
289
+ @recordset_manager.recordset[recordset].each_with_index do |i, n|
290
+ @logger.debug("#{n + 1} of #{recordset}: #{i}")
291
+ tmp = @statement
292
+ i.keys.each { |k| tmp = tmp.gsub(":#{recordset}.#{k}", i[k].to_s) }
293
+ @expression_handler.set_session_variable(
294
+ 'last_statement_rows_affected',
295
+ rows_affected_current_statement(tmp)
296
+ )
297
+ end
298
+ end
299
+
300
+ # @param [*Array] args all the arguments passed to the calling function
301
+ def iterate_records_conditionally(*args)
302
+ recordset = args.to_a[0]
303
+ @logger.info "iterating recordset #{recordset}..."
304
+ conditions = @recordset_manager.parse_recordset_expression(args.to_a)
305
+ @recordset_manager.recordset[recordset].each_with_index do |i, n|
306
+ @logger.debug("#{n + 1} of #{recordset}: #{i}")
307
+ next unless @recordset_manager.evaluate_expression_against_record(i, conditions)
308
+ tmp = @statement
309
+ i.keys.each { |k| tmp = tmp.gsub(":#{recordset}.#{k}", i[k].to_s) }
310
+ @expression_handler.set_session_variable(
311
+ 'last_statement_rows_affected',
312
+ rows_affected_current_statement(tmp)
313
+ )
314
+ end
315
+ end
316
+
317
+ # @return [Fixnum] rows affected by the SQL statement
318
+ def rows_affected_current_statement(stmt)
319
+ JDBCHelpers::Execute.new(
320
+ @jdbc_connection,
321
+ stmt,
322
+ @logger
323
+ ).rows_affected
324
+ end
325
+ end
326
+
327
+ # stores all the file paths matching the dir glob into a recordset
328
+ class SneaqlRecordsetFromDirGlob < Sneaql::Core::SneaqlCommand
329
+ Sneaql::Core::RegisterMappedClass.new(
330
+ :command,
331
+ 'rs_from_local_dir',
332
+ Sneaql::Core::Commands::SneaqlRecordsetFromDirGlob
333
+ )
334
+
335
+ # @param [String] recordset_name
336
+ # @param [String] dirglob directory glob with optional wildcards
337
+ def action(recordset_name, dirglob)
338
+ r = Dir.glob(dirglob)
339
+ r.map! { |d| { 'path_name' => d.to_s } }
340
+ @logger.debug "adding #{r.length} recs as #{recordset_name}"
341
+ @recordset_manager.store_recordset(recordset_name, r)
342
+ end
343
+ end
344
+ end
345
+ end
346
+ end
@@ -0,0 +1,79 @@
1
+ module Sneaql
2
+ module Core
3
+ # returns the database type based upon the jdbc url
4
+ # @param [String]
5
+ def self.database_type(jdbc_url)
6
+ Sneaql::Core.class_map[:database].each do |d|
7
+ return d[:text] if jdbc_url.match(d[:text])
8
+ end
9
+ end
10
+
11
+ # Manages preferences for a specific RDBMS implementation.
12
+ class DatabaseManager
13
+ attr_reader(
14
+ :has_boolean,
15
+ :autocommit_off_statement,
16
+ :supports_transactions,
17
+ :supports_table_locking,
18
+ :begin_statement,
19
+ :commit_statement,
20
+ :rollback_statement
21
+ )
22
+
23
+ # @param [Hash] options values to override defaults
24
+ def initialize(options = {})
25
+ @has_boolean = options.fetch(:has_boolean, default_has_boolean)
26
+ @autocommit_off_statement = options.fetch(:autocommit_off_statement, default_autocommit_off_statement)
27
+ @supports_transactions = options.fetch(:supports_transactions, default_supports_transactions)
28
+ @supports_table_locking = options.fetch(:supports_table_locking, default_supports_table_locking)
29
+ @begin_statement = options.fetch(:begin_statement, default_begin_statement)
30
+ @commit_statement = options.fetch(:commit_statement, default_commit_statement)
31
+ @rollback_statement = options.fetch(:rollback_statement, default_rollback_statement)
32
+ end
33
+
34
+ # @return [Boolean]
35
+ def default_has_boolean
36
+ false
37
+ end
38
+
39
+ # @return [String]
40
+ def default_autocommit_off_statement
41
+ nil
42
+ end
43
+
44
+ # @return [Boolean]
45
+ def default_supports_transactions
46
+ true
47
+ end
48
+
49
+ # @return [Boolean]
50
+ def default_supports_table_locking
51
+ false
52
+ end
53
+
54
+ # @return [String] begin statement
55
+ def default_begin_statement
56
+ "begin;"
57
+ end
58
+
59
+ # @return [String] commit statement
60
+ def default_commit_statement
61
+ "commit;"
62
+ end
63
+
64
+ # @return [String] rollback statement
65
+ def default_rollback_statement
66
+ "rollback;"
67
+ end
68
+
69
+ # @param [String] table_name
70
+ # @return [String] rollback statement
71
+ def lock_table_statement(table_name)
72
+ "lock table #{table_name};"
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ # Require all tested RDBMS
79
+ Dir.glob("#{File.dirname(__FILE__)}/database_prefs/*.rb").each { |f| require File.expand_path(f) }
@@ -0,0 +1,22 @@
1
+ module Sneaql
2
+ module Core
3
+ # Settings for interaction with Amazon Redshift
4
+ class RedshiftDatabaseManager < Sneaql::Core::DatabaseManager
5
+ Sneaql::Core::RegisterMappedClass.new(
6
+ :database,
7
+ 'redshift',
8
+ Sneaql::Core::RedshiftDatabaseManager
9
+ )
10
+
11
+ def initialize()
12
+ super(
13
+ {
14
+ has_boolean: true,
15
+ autocommit_off_statement: 'set autocommit=off;'
16
+ }
17
+ )
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ module Sneaql
2
+ module Core
3
+ # Settings for interacting with SQLite
4
+ class SqliteDatabaseManager < Sneaql::Core::DatabaseManager
5
+ Sneaql::Core::RegisterMappedClass.new(
6
+ :database,
7
+ 'sqlite',
8
+ Sneaql::Core::SqliteDatabaseManager
9
+ )
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,21 @@
1
+ module Sneaql
2
+ module Core
3
+ # Settings for interacting with HP Vertica
4
+ class VerticaDatabaseManager < Sneaql::Core::DatabaseManager
5
+ Sneaql::Core::RegisterMappedClass.new(
6
+ :database,
7
+ 'vertica',
8
+ Sneaql::Core::VerticaDatabaseManager
9
+ )
10
+
11
+ def initialize
12
+ super(
13
+ {
14
+ has_boolean: true,
15
+ autocommit_off_statement: 'set session autocommit to off;'
16
+ }
17
+ )
18
+ end
19
+ end
20
+ end
21
+ end