db2_query 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +38 -37
- data/Rakefile +2 -19
- data/lib/active_record/connection_adapters/db2_query_adapter.rb +203 -0
- data/lib/db2_query.rb +8 -14
- data/lib/db2_query/base.rb +6 -79
- data/lib/db2_query/config.rb +30 -0
- data/lib/db2_query/connection_handling.rb +20 -43
- data/lib/db2_query/core.rb +88 -0
- data/lib/db2_query/database_statements.rb +71 -15
- data/lib/db2_query/formatter.rb +5 -23
- data/lib/db2_query/odbc_connector.rb +7 -7
- data/lib/db2_query/railtie.rb +9 -11
- data/lib/db2_query/result.rb +41 -73
- data/lib/{tasks → db2_query/tasks}/database.rake +16 -14
- data/lib/{tasks → db2_query/tasks}/init.rake +1 -1
- data/lib/{tasks → db2_query/tasks}/initializer.rake +2 -3
- data/lib/db2_query/version.rb +2 -2
- metadata +32 -17
- data/lib/db2_query/column.rb +0 -42
- data/lib/db2_query/connection.rb +0 -50
- data/lib/db2_query/database_configurations.rb +0 -50
- data/lib/db2_query/error.rb +0 -5
- data/lib/db2_query/log_subscriber.rb +0 -50
- data/lib/db2_query/path.rb +0 -17
- data/lib/db2_query/schema.rb +0 -113
- data/lib/db2_query/sql_validator.rb +0 -26
@@ -2,41 +2,43 @@
|
|
2
2
|
|
3
3
|
DB2_QUERY_DATABASE_TEMPLATE ||= <<-EOF
|
4
4
|
# frozen_string_literal: true
|
5
|
-
|
6
5
|
# Database configuration example
|
7
6
|
development:
|
8
7
|
primary:
|
8
|
+
adapter: db2_query
|
9
|
+
dsn: iseries
|
10
|
+
uid: <%= ENV["ISERIES_UID"] %>
|
11
|
+
pwd: <%= ENV["ISERIES_PWD"] %>
|
12
|
+
secondary:
|
13
|
+
adapter: db2_query
|
9
14
|
conn_string:
|
10
15
|
driver: DB2
|
11
|
-
database:
|
12
|
-
dbalias:
|
16
|
+
database: ARUNIT2
|
17
|
+
dbalias: ARUNIT2
|
13
18
|
hostname: LOCALHOST
|
14
19
|
currentschema: LIBTEST
|
15
20
|
port: "0"
|
16
21
|
protocol: IPC
|
17
22
|
uid: <%= ENV["DB2EC_UID"] %>
|
18
23
|
pwd: <%= ENV["DB2EC_PWD"] %>
|
19
|
-
secondary:
|
20
|
-
dsn: SAMPLE
|
21
|
-
uid: <%= ENV["DB2EC_UID"] %>
|
22
|
-
pwd: <%= ENV["DB2EC_PWD"] %>
|
23
|
-
|
24
24
|
test:
|
25
25
|
primary:
|
26
|
+
adapter: db2_query
|
27
|
+
dsn: iseries
|
28
|
+
uid: <%= ENV["ISERIES_UID"] %>
|
29
|
+
pwd: <%= ENV["ISERIES_PWD"] %>
|
30
|
+
secondary:
|
31
|
+
adapter: db2_query
|
26
32
|
conn_string:
|
27
33
|
driver: DB2
|
28
|
-
database:
|
29
|
-
dbalias:
|
34
|
+
database: ARUNIT2
|
35
|
+
dbalias: ARUNIT2
|
30
36
|
hostname: LOCALHOST
|
31
37
|
currentschema: LIBTEST
|
32
38
|
port: "0"
|
33
39
|
protocol: IPC
|
34
40
|
uid: <%= ENV["DB2EC_UID"] %>
|
35
41
|
pwd: <%= ENV["DB2EC_PWD"] %>
|
36
|
-
secondary:
|
37
|
-
dsn: SAMPLE
|
38
|
-
uid: <%= ENV["DB2EC_UID"] %>
|
39
|
-
pwd: <%= ENV["DB2EC_PWD"] %>
|
40
42
|
EOF
|
41
43
|
|
42
44
|
namespace :db2query do
|
@@ -5,10 +5,9 @@ DB2_QUERY_INITIALIZER_TEMPLATE ||= <<-EOF
|
|
5
5
|
|
6
6
|
# Example
|
7
7
|
require "db2_query/formatter"
|
8
|
-
|
9
8
|
class FirstNameFormatter < Db2Query::AbstractFormatter
|
10
9
|
def format(value)
|
11
|
-
"
|
10
|
+
"Dr." + value
|
12
11
|
end
|
13
12
|
end
|
14
13
|
|
@@ -32,4 +31,4 @@ namespace :db2query do
|
|
32
31
|
puts " File '#{initializer_path}' created."
|
33
32
|
end
|
34
33
|
end
|
35
|
-
end
|
34
|
+
end
|
data/lib/db2_query/version.rb
CHANGED
metadata
CHANGED
@@ -1,17 +1,31 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: db2_query
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yohanes_l
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: ruby-odbc
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.99999'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.99999'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
16
30
|
requirements:
|
17
31
|
- - "~>"
|
@@ -31,19 +45,25 @@ dependencies:
|
|
31
45
|
- !ruby/object:Gem::Version
|
32
46
|
version: 6.0.3.1
|
33
47
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
48
|
+
name: activerecord
|
35
49
|
requirement: !ruby/object:Gem::Requirement
|
36
50
|
requirements:
|
37
51
|
- - "~>"
|
38
52
|
- !ruby/object:Gem::Version
|
39
|
-
version:
|
53
|
+
version: 6.0.3
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 6.0.3.1
|
40
57
|
type: :runtime
|
41
58
|
prerelease: false
|
42
59
|
version_requirements: !ruby/object:Gem::Requirement
|
43
60
|
requirements:
|
44
61
|
- - "~>"
|
45
62
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
63
|
+
version: 6.0.3
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 6.0.3.1
|
47
67
|
- !ruby/object:Gem::Dependency
|
48
68
|
name: rubocop
|
49
69
|
requirement: !ruby/object:Gem::Requirement
|
@@ -152,26 +172,21 @@ files:
|
|
152
172
|
- MIT-LICENSE
|
153
173
|
- README.md
|
154
174
|
- Rakefile
|
175
|
+
- lib/active_record/connection_adapters/db2_query_adapter.rb
|
155
176
|
- lib/db2_query.rb
|
156
177
|
- lib/db2_query/base.rb
|
157
|
-
- lib/db2_query/
|
158
|
-
- lib/db2_query/connection.rb
|
178
|
+
- lib/db2_query/config.rb
|
159
179
|
- lib/db2_query/connection_handling.rb
|
160
|
-
- lib/db2_query/
|
180
|
+
- lib/db2_query/core.rb
|
161
181
|
- lib/db2_query/database_statements.rb
|
162
|
-
- lib/db2_query/error.rb
|
163
182
|
- lib/db2_query/formatter.rb
|
164
|
-
- lib/db2_query/log_subscriber.rb
|
165
183
|
- lib/db2_query/odbc_connector.rb
|
166
|
-
- lib/db2_query/path.rb
|
167
184
|
- lib/db2_query/railtie.rb
|
168
185
|
- lib/db2_query/result.rb
|
169
|
-
- lib/db2_query/
|
170
|
-
- lib/db2_query/
|
186
|
+
- lib/db2_query/tasks/database.rake
|
187
|
+
- lib/db2_query/tasks/init.rake
|
188
|
+
- lib/db2_query/tasks/initializer.rake
|
171
189
|
- lib/db2_query/version.rb
|
172
|
-
- lib/tasks/database.rake
|
173
|
-
- lib/tasks/init.rake
|
174
|
-
- lib/tasks/initializer.rake
|
175
190
|
homepage: https://github.com/yohaneslumentut/db2_query
|
176
191
|
licenses:
|
177
192
|
- MIT
|
data/lib/db2_query/column.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Db2Query
|
4
|
-
class Column
|
5
|
-
attr_reader :name, :type, :formatter
|
6
|
-
|
7
|
-
FLOAT_TYPES = [ODBC::SQL_FLOAT, ODBC::SQL_DOUBLE, ODBC::SQL_DECIMAL, ODBC::SQL_REAL]
|
8
|
-
INTEGER_TYPES = [ODBC::SQL_TINYINT, ODBC::SQL_SMALLINT, ODBC::SQL_INTEGER, ODBC::SQL_BIGINT, ODBC::SQL_NUMERIC]
|
9
|
-
|
10
|
-
def initialize(name, type, format = nil)
|
11
|
-
@name = name
|
12
|
-
@type = type.to_i
|
13
|
-
|
14
|
-
@formatter = if custom_format?(format)
|
15
|
-
Formatter.lookup(format)
|
16
|
-
elsif float_type?
|
17
|
-
FloatFormatter.new
|
18
|
-
elsif integer_type?
|
19
|
-
IntegerFormatter.new
|
20
|
-
else
|
21
|
-
BareFormatter.new
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def format(value)
|
26
|
-
formatter.format(value)
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
def custom_format?(format)
|
31
|
-
Formatter.registry.key?(format)
|
32
|
-
end
|
33
|
-
|
34
|
-
def float_type?
|
35
|
-
FLOAT_TYPES.include?(type)
|
36
|
-
end
|
37
|
-
|
38
|
-
def integer_type?
|
39
|
-
INTEGER_TYPES.include?(type)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
data/lib/db2_query/connection.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Db2Query
|
4
|
-
class Connection
|
5
|
-
include DatabaseStatements
|
6
|
-
|
7
|
-
attr_reader :connector, :db_name, :odbc_conn
|
8
|
-
|
9
|
-
def initialize(connector, db_name)
|
10
|
-
@connector = connector
|
11
|
-
@db_name = db_name.to_sym
|
12
|
-
connect
|
13
|
-
end
|
14
|
-
|
15
|
-
def connect
|
16
|
-
@odbc_conn = connector.connect
|
17
|
-
@odbc_conn.use_time = true
|
18
|
-
end
|
19
|
-
|
20
|
-
def active?
|
21
|
-
@odbc_conn.connected?
|
22
|
-
end
|
23
|
-
|
24
|
-
def disconnect!
|
25
|
-
@odbc_conn.drop_all
|
26
|
-
@odbc_conn.disconnect if active?
|
27
|
-
end
|
28
|
-
|
29
|
-
def reconnect!
|
30
|
-
disconnect!
|
31
|
-
connect
|
32
|
-
end
|
33
|
-
alias reset! reconnect!
|
34
|
-
|
35
|
-
def execute(sql, *args)
|
36
|
-
reset! unless active?
|
37
|
-
@odbc_conn.do(sql, *args)
|
38
|
-
end
|
39
|
-
|
40
|
-
def exec_query(sql, *args)
|
41
|
-
reset! unless active?
|
42
|
-
statement = @odbc_conn.run(sql, *args)
|
43
|
-
columns = statement.columns.values
|
44
|
-
rows = statement.to_a
|
45
|
-
[columns, rows]
|
46
|
-
ensure
|
47
|
-
statement.drop if statement
|
48
|
-
end
|
49
|
-
end
|
50
|
-
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
|
data/lib/db2_query/error.rb
DELETED
@@ -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
|
data/lib/db2_query/path.rb
DELETED
@@ -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
|
data/lib/db2_query/schema.rb
DELETED
@@ -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
|