db2_query 0.1.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Db2Query
4
- module ConnectionHandling
5
- extend ActiveSupport::Concern
6
-
7
- DEFAULT_DB = "primary"
8
-
9
- included do |base|
10
- def base.inherited(child)
11
- child.connection = @connection
12
- end
13
-
14
- base.extend ClassMethods
15
- base.connection = nil
16
- end
17
-
18
- module ClassMethods
19
- attr_reader :connection
20
-
21
- def connection=(connection)
22
- @connection = connection
23
- update_descendants_connection unless self.descendants.empty?
24
- end
25
-
26
- def update_descendants_connection
27
- self.descendants.each { |child| child.connection = @connection }
28
- end
29
-
30
- def establish_connection(db_name = nil)
31
- clear_connection unless self.connection.nil?
32
- db_name = db_name.nil? ? DEFAULT_DB : db_name.to_s
33
-
34
- self.load_database_configurations if self.configurations.nil?
35
-
36
- if self.configurations[db_name].nil?
37
- raise Error, "Database (:#{db_name}) not found at database configurations."
38
- end
39
-
40
- conn_type, conn_config = extract_configuration(db_name)
41
-
42
- connector = ODBCConnector.new(conn_type, conn_config)
43
- self.connection = Connection.new(connector, db_name)
44
- end
45
-
46
- def current_database
47
- @connection.db_name
48
- end
49
-
50
- def clear_connection
51
- @connection.disconnect!
52
- @connection = nil
53
- end
54
- end
55
- end
56
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Db2Query
4
- module DatabaseConfigurations
5
- extend ActiveSupport::Concern
6
-
7
- DEFAULT_ENV = -> { (Rails.env if defined?(Rails.env)) || ENV["RAILS_ENV"].presence || ENV["RACK_ENV"].presence }
8
-
9
- included do |base|
10
- @@configurations = Hash.new
11
-
12
- base.extend ClassMethods
13
- end
14
-
15
- module ClassMethods
16
- def configurations
17
- @@configurations
18
- end
19
-
20
- def load_database_configurations(path = nil)
21
- file_path = path.nil? ? Path.database_config_file : path
22
-
23
- if File.exist?(file_path)
24
- file = File.read(file_path)
25
- @@configurations = YAML.load(ERB.new(file).result)[DEFAULT_ENV.call]
26
- else
27
- raise Error, "Could not load db2query database configuration. No such file - #{file_path}"
28
- end
29
- end
30
-
31
- def configurations_databases
32
- self.load_database_configurations if self.configurations.nil?
33
- @@configurations.keys
34
- end
35
-
36
- private
37
- def extract_configuration(db_name)
38
- configs = @@configurations[db_name.to_s]
39
- conn_config = configs.nil? ? configs : configs.transform_keys(&:to_sym)
40
- conn_type = (conn_config.keys & ODBCConnector::CONNECTION_TYPES).first
41
-
42
- if conn_type.nil?
43
- raise Error, "No data source name (:dsn) or connection string (:conn_str) provided."
44
- end
45
-
46
- [conn_type, conn_config]
47
- end
48
- end
49
- end
50
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Db2Query
4
- module DatabaseStatements
5
- def query_value(sql) # :nodoc:
6
- single_value_from_rows(query(sql))
7
- end
8
-
9
- def query(sql)
10
- exec_query(sql).last
11
- end
12
-
13
- def query_values(sql)
14
- query(sql).map(&:first)
15
- end
16
-
17
- def current_database
18
- db_name.to_s
19
- end
20
-
21
- def current_schema
22
- query_value("select current_schema from sysibm.sysdummy1").strip
23
- end
24
- alias library current_schema
25
-
26
- private
27
- def single_value_from_rows(rows)
28
- row = rows.first
29
- row && row.first
30
- end
31
- end
32
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Db2Query
4
- class LogSubscriber < ActiveSupport::LogSubscriber
5
- # Embed in a String to clear all previous ANSI sequences.
6
- CLEAR = "\e[0m"
7
- BOLD = "\e[1m"
8
-
9
- # Colors
10
- BLACK = "\e[30m"
11
- RED = "\e[31m"
12
- GREEN = "\e[32m"
13
- YELLOW = "\e[33m"
14
- BLUE = "\e[34m"
15
- MAGENTA = "\e[35m"
16
- CYAN = "\e[36m"
17
- WHITE = "\e[37m"
18
-
19
- def sql(event)
20
- class_load_duration = color("#{event.payload[:name]} Load (#{event.duration.round(2)}ms)", :cyan, true)
21
- sql_statement = color("#{event.payload[:sql]}", :blue, true)
22
- message = " #{class_load_duration} #{sql_statement}"
23
-
24
- if event.payload[:binds].size > 0
25
- binds = color("#{event.payload[:binds]}", :white)
26
- message = "#{message} [#{binds}]"
27
- end
28
-
29
- puts message
30
- end
31
-
32
- def schema_task(event)
33
- puts color(" Done (#{(event.duration).round(2)}ms)", :green, true)
34
- end
35
-
36
- def schema_task_perform(event)
37
- task_name = color(":#{event.payload[:task_name]}", :white, true)
38
- schema = color("#{event.payload[:schema]}", :white, true)
39
- puts "- Performing #{task_name} in #{schema} ..."
40
- end
41
-
42
- private
43
- def color(text, color, bold = false) # :doc:
44
- return text unless colorize_logging
45
- color = self.class.const_get(color.upcase) if color.is_a?(Symbol)
46
- bold = bold ? BOLD : ""
47
- "#{bold}#{color}#{text}#{CLEAR}"
48
- end
49
- end
50
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Db2Query
4
- class ODBCConnector
5
- attr_reader :connector, :conn_type, :conn_config
6
-
7
- CONNECTION_TYPES = %i[dsn conn_string].freeze
8
-
9
- def initialize(type, config)
10
- @conn_type, @conn_config = type, config.transform_keys(&:to_sym)
11
- @connector = Db2Query.const_get("#{conn_type.to_s.camelize}Connector").new
12
- end
13
-
14
- def connect
15
- connector.connect(conn_config)
16
- end
17
- end
18
-
19
- class DsnConnector
20
- def connect(config)
21
- ::ODBC.connect(config[:dsn], config[:uid], config[:pwd])
22
- rescue ::ODBC::Error => e
23
- raise Error, "Unable to activate ODBC DSN connection #{e}"
24
- end
25
- end
26
-
27
- class ConnStringConnector
28
- def connect(config)
29
- driver = ::ODBC::Driver.new.tap do |d|
30
- d.attrs = config[:conn_string].transform_keys(&:to_s)
31
- d.name = "odbc"
32
- end
33
- ::ODBC::Database.new.drvconnect(driver)
34
- rescue ::ODBC::Error => e
35
- raise Error, "Unable to activate ODBC Conn String connection #{e}"
36
- end
37
- end
38
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Db2Query
4
- module Path
5
- def self.database_config_file
6
- @@database_config_file ||= nil
7
- end
8
-
9
- def self.database_config_file=(file_path)
10
- @@database_config_file ||= file_path
11
- end
12
-
13
- def self.database_config_file_exists?
14
- File.exist?(self.database_config_file)
15
- end
16
- end
17
- end
@@ -1,113 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Db2Query
4
- class Schema
5
- include SQLValidator
6
-
7
- attr_accessor :config, :current_schema
8
-
9
- def initialize
10
- @config = Config.new
11
- end
12
-
13
- def connection
14
- Base.connection
15
- end
16
-
17
- def schema
18
- config.schema
19
- end
20
-
21
- def sql_files_dir(path)
22
- config.sql_files_dir = path
23
- end
24
-
25
- def is_valid_schema?
26
- connection.current_schema == config.schema
27
- end
28
-
29
- def perform_tasks(&block)
30
- raise Error, "#{config.main_library} is not connection's current schema" unless is_valid_schema?
31
-
32
- if Base.connection.nil? && config.init_connection
33
- Base.establish_connection
34
- end
35
-
36
- puts "\n# Perform Schema Tasks: \n\n"
37
-
38
- instance_eval(&block)
39
-
40
- puts "\n"
41
- end
42
-
43
- def sql(sql_statement)
44
- raise Error, "Task only for SQL execute commands." if query_command?(sql_statement)
45
- sql_statement
46
- end
47
-
48
- def file(file_name)
49
- sql(File.read("#{config.sql_files_dir}/#{file_name}"))
50
- end
51
-
52
- def task(task_name, sql = nil, *args)
53
- Task.new(schema, task_name).perform do
54
- if block_given?
55
- yield(sql)
56
- else
57
- execute(sql, *args)
58
- end
59
- end
60
- end
61
-
62
- def execute(sql, *args)
63
- connection.execute(sql, *args)
64
- rescue ::ODBC::Error => e
65
- raise Error, "Unable to execute SQL - #{e}"
66
- end
67
-
68
- def tables_in_schema
69
- connection.query_values <<-SQL
70
- SELECT table_name FROM SYSIBM.SQLTABLES
71
- WHERE table_schem='#{schema}' AND table_type='TABLE'
72
- SQL
73
- end
74
-
75
- def self.initiation(&block)
76
- new.initiation(&block)
77
- end
78
-
79
- def initiation(&block)
80
- instance_eval(&block)
81
- end
82
-
83
- class Task
84
- attr_reader :instrumenter, :schema, :task_name, :start_time, :finish_time
85
-
86
- def initialize(schema, task_name)
87
- @schema = schema
88
- @task_name = task_name
89
- @instrumenter = ActiveSupport::Notifications.instrumenter
90
- end
91
-
92
- def perform
93
- instrumenter.instrument("schema_task_perform.db2_query", payload)
94
- instrumenter.start("schema_task.db2_query", payload)
95
- yield
96
- instrumenter.finish("schema_task.db2_query", payload)
97
- end
98
-
99
- private
100
- def payload
101
- { task_name: task_name, schema: schema }
102
- end
103
- end
104
-
105
- class Config
106
- attr_accessor :initial_tasks, :init_connection, :schema, :sql_files_dir
107
-
108
- def initialize
109
- @init_connection = false
110
- end
111
- end
112
- end
113
- end
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Db2Query
4
- module SQLValidator
5
- DEFAULT_TASK_COMMANDS = [:create, :drop, :delete, :insert, :set, :update]
6
- COMMENT_REGEX = %r{/\*(?:[^\*]|\*[^/])*\*/}m
7
-
8
- def task_command?(sql_statement)
9
- sql_statement.match?(task_commands_regexp)
10
- end
11
-
12
- def query_command?(sql_statement)
13
- sql_statement.match?(/select/i)
14
- end
15
-
16
- def is_query?(sql_statement)
17
- query_command?(sql_statement) && !task_command?(sql_statement)
18
- end
19
-
20
- private
21
- def task_commands_regexp
22
- parts = DEFAULT_TASK_COMMANDS.map { |part| /#{part}/i }
23
- /\A(?:[\(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/i
24
- end
25
- end
26
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- DB2_QUERY_DATABASE_TEMPLATE ||= <<-EOF
4
- # frozen_string_literal: true
5
-
6
- # Database configuration example
7
- development:
8
- primary:
9
- conn_string:
10
- driver: DB2
11
- database: SAMPLE
12
- dbalias: SAMPLE
13
- hostname: LOCALHOST
14
- currentschema: LIBTEST
15
- port: "0"
16
- protocol: IPC
17
- uid: <%= ENV["DB2EC_UID"] %>
18
- pwd: <%= ENV["DB2EC_PWD"] %>
19
- secondary:
20
- dsn: SAMPLE
21
- uid: <%= ENV["DB2EC_UID"] %>
22
- pwd: <%= ENV["DB2EC_PWD"] %>
23
-
24
- test:
25
- primary:
26
- conn_string:
27
- driver: DB2
28
- database: SAMPLE
29
- dbalias: SAMPLE
30
- hostname: LOCALHOST
31
- currentschema: LIBTEST
32
- port: "0"
33
- protocol: IPC
34
- uid: <%= ENV["DB2EC_UID"] %>
35
- pwd: <%= ENV["DB2EC_PWD"] %>
36
- secondary:
37
- dsn: SAMPLE
38
- uid: <%= ENV["DB2EC_UID"] %>
39
- pwd: <%= ENV["DB2EC_PWD"] %>
40
- EOF
41
-
42
- namespace :db2query do
43
- desc "Create Database configuration file"
44
- task :database do
45
- database_path = "#{Rails.root}/config/db2query_database.yml"
46
- if File.exist?(database_path)
47
- raise ArgumentError, "File exists."
48
- else
49
- puts " Creating database config file ..."
50
- File.open(database_path, "w") do |file|
51
- file.puts DB2_QUERY_DATABASE_TEMPLATE
52
- end
53
- puts " File '#{database_path}' created."
54
- end
55
- end
56
- end