db2_query 0.2.2 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +453 -110
  4. data/Rakefile +3 -2
  5. data/lib/db2_query.rb +41 -15
  6. data/lib/db2_query/base.rb +16 -5
  7. data/lib/db2_query/config.rb +20 -17
  8. data/lib/db2_query/core.rb +68 -55
  9. data/lib/db2_query/db_client.rb +56 -0
  10. data/lib/db2_query/db_connection.rb +67 -0
  11. data/lib/db2_query/db_statements.rb +87 -0
  12. data/lib/db2_query/definitions.rb +79 -0
  13. data/lib/db2_query/error.rb +81 -0
  14. data/lib/db2_query/field_type.rb +31 -0
  15. data/lib/db2_query/helper.rb +49 -0
  16. data/lib/db2_query/logger.rb +52 -0
  17. data/lib/db2_query/query.rb +117 -0
  18. data/lib/db2_query/quoting.rb +102 -0
  19. data/lib/db2_query/railtie.rb +5 -7
  20. data/lib/db2_query/result.rb +51 -31
  21. data/lib/db2_query/sql_statement.rb +34 -0
  22. data/lib/db2_query/tasks.rb +29 -0
  23. data/lib/db2_query/tasks/database.rake +2 -50
  24. data/lib/db2_query/tasks/init.rake +1 -1
  25. data/lib/db2_query/tasks/initializer.rake +2 -34
  26. data/lib/db2_query/tasks/templates/database.rb.tt +19 -0
  27. data/lib/db2_query/tasks/templates/initializer.rb.tt +8 -0
  28. data/lib/db2_query/type/binary.rb +19 -0
  29. data/lib/db2_query/type/boolean.rb +41 -0
  30. data/lib/db2_query/type/date.rb +34 -0
  31. data/lib/db2_query/type/decimal.rb +15 -0
  32. data/lib/db2_query/type/integer.rb +15 -0
  33. data/lib/db2_query/type/string.rb +30 -0
  34. data/lib/db2_query/type/text.rb +11 -0
  35. data/lib/db2_query/type/time.rb +30 -0
  36. data/lib/db2_query/type/timestamp.rb +30 -0
  37. data/lib/db2_query/type/value.rb +29 -0
  38. data/lib/db2_query/version.rb +2 -2
  39. data/lib/rails/generators/query/USAGE +15 -0
  40. data/lib/rails/generators/query/query_generator.rb +70 -0
  41. data/lib/rails/generators/query/templates/query.rb.tt +26 -0
  42. data/lib/rails/generators/query/templates/query_definitions.rb.tt +12 -0
  43. data/lib/rails/generators/query/templates/unit_test.rb.tt +9 -0
  44. metadata +62 -49
  45. data/lib/db2_query/connection.rb +0 -163
  46. data/lib/db2_query/connection_handling.rb +0 -112
  47. data/lib/db2_query/database_statements.rb +0 -93
  48. data/lib/db2_query/formatter.rb +0 -27
  49. data/lib/db2_query/odbc_connector.rb +0 -40
@@ -3,18 +3,16 @@
3
3
  require "db2_query"
4
4
  require "rails"
5
5
 
6
- module DB2Query
7
- class Railtie < Rails::Railtie
6
+ module Db2Query
7
+ class Railtie < ::Rails::Railtie
8
8
  railtie_name :db2_query
9
9
 
10
10
  rake_tasks do
11
- path = File.expand_path(__dir__)
12
- Dir.glob("#{path}/tasks/*.rake").each { |f| load f }
11
+ Dir.glob("#{Db2Query.root}/db2_query/tasks/*.rake").each { |f| load f }
13
12
  end
14
13
 
15
- initializer "db2_query.database_initialization" do
16
- DB2Query::Base.configurations = DB2Query.config
17
- DB2Query::Base.establish_connection :primary
14
+ config.app_generators do
15
+ require "#{Db2Query.root}/rails/generators/query/query_generator.rb"
18
16
  end
19
17
  end
20
18
  end
@@ -1,69 +1,89 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module DB2Query
3
+ module Db2Query
4
4
  class Result < ActiveRecord::Result
5
- attr_reader :formatters
5
+ attr_reader :definition
6
6
 
7
- def initialize(columns, rows, formatters = {}, column_types = {})
8
- @formatters = formatters
9
- super(columns, rows, column_types)
7
+ alias query definition
8
+
9
+ delegate :data_type, :validate_result_columns, to: :definition
10
+
11
+ def initialize(columns, rows, definition)
12
+ @definition = definition
13
+ validate_result_columns(columns)
14
+ super(columns, rows, {})
15
+ end
16
+
17
+ def record
18
+ records.first
10
19
  end
11
20
 
12
21
  def records
13
- @records ||= rows.map do |row|
14
- Record.new(row, columns, formatters)
15
- end
22
+ @records ||= rows.map { |row| new_record(row) }
16
23
  end
17
24
 
18
25
  def to_h
19
26
  rows.map do |row|
20
- columns.zip(row).each_with_object({}) { |cr, h| h[cr[0].to_sym] = cr[1] }
27
+ index, hash = [0, {}]
28
+ while index < columns.length
29
+ attr_name = columns[index].to_sym
30
+ hash[attr_name] = data_type(attr_name).deserialize(row[index])
31
+ index += 1
32
+ end
33
+ hash
21
34
  end
22
35
  end
23
36
 
24
37
  def inspect
25
38
  entries = records.take(11).map!(&:inspect)
26
-
27
39
  entries[10] = "..." if entries.size == 11
28
-
29
- "#<#{self.class.name} @records=[#{entries.join(', ')}]>"
40
+ "#<#{self.class.name} [#{entries.join(', ')}]>"
30
41
  end
31
42
 
32
43
  class Record
33
- attr_reader :formatters
44
+ attr_reader :definition
34
45
 
35
- def initialize(row, columns, formatters)
36
- @formatters = formatters
37
- columns.zip(row) do |col, val|
38
- column, value = format(col, val)
39
- singleton_class.class_eval { attr_accessor "#{column}" }
40
- send("#{column}=", value)
41
- end
46
+ delegate :data_type, to: :definition
47
+
48
+ def initialize(row, columns, definition)
49
+ @definition = definition
50
+ add_attributes(columns, row)
42
51
  end
43
52
 
44
53
  def inspect
45
54
  inspection = if defined?(instance_variables) && instance_variables
46
- instance_variables.reject { |var| var == :@formatters }.map do |attr|
47
- value = instance_variable_get(attr)
48
- "#{attr[1..-1]}: #{(value.kind_of? String) ? %Q{"#{value}"} : value}"
55
+ instance_variables.reject { |var| var == :@definition }.map do |attribute|
56
+ "#{attribute[1..-1]}: #{instance_variable_get(attribute)}"
49
57
  end.compact.join(", ")
50
58
  else
51
59
  "not initialized"
52
60
  end
53
-
54
61
  "#<Record #{inspection}>"
55
62
  end
56
63
 
57
64
  private
58
- def format(col, val)
59
- column = col.downcase
60
- format_name = formatters[column.to_sym]
61
- unless format_name.nil?
62
- formatter = DB2Query::Formatter.lookup(format_name)
63
- val = formatter.format(val)
65
+ def add_attributes(columns, row)
66
+ index = 0
67
+ while index < columns.length
68
+ column, value = [columns[index], row[index]]
69
+ class_eval { attr_accessor "#{column}" }
70
+ send("#{column}=", data_type(column).deserialize(value))
71
+ index += 1
64
72
  end
65
- [column, val]
66
73
  end
67
74
  end
75
+
76
+ private
77
+ def new_record(row)
78
+ Record.new(row, columns, definition)
79
+ end
80
+
81
+ def method_missing(method_name, *args, &block)
82
+ if record.respond_to?(method_name)
83
+ record.send(method_name)
84
+ else
85
+ super
86
+ end
87
+ end
68
88
  end
69
89
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Db2Query
4
+ module SqlStatement
5
+ def delete_sql?
6
+ sql.match?(/delete/i)
7
+ end
8
+
9
+ def insert_sql?
10
+ sql.match?(/insert/i)
11
+ end
12
+
13
+ def iud_sql?
14
+ sql.match?(/insert into|update|delete/i)
15
+ end
16
+
17
+ def db2_spec_sql
18
+ iud_sql? ? iud_spec_sql : sql
19
+ end
20
+
21
+ def table_name
22
+ insert_sql? ? sql.split("INTO ").last.split(" ").first : nil
23
+ end
24
+
25
+ private
26
+ def new_keys(raw_sql)
27
+ raw_sql.scan(/\$\S+/).map { |key| key.gsub!(/[$=,)]/, "").to_sym }
28
+ end
29
+
30
+ def iud_spec_sql
31
+ "SELECT * FROM #{delete_sql? ? "OLD" : "NEW"} TABLE (#{sql})"
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "thor"
4
+
5
+ module Db2Query
6
+ class Tasks < Thor::Group
7
+ include Thor::Actions
8
+
9
+ class << self
10
+ alias generate_file start
11
+ end
12
+ end
13
+
14
+ class DatabaseTask < Tasks
15
+ source_root File.expand_path("../tasks/templates", __FILE__)
16
+
17
+ def create_database_config_file
18
+ template "database.rb", File.join("config/db2query.yml")
19
+ end
20
+ end
21
+
22
+ class InitializerTask < Tasks
23
+ source_root File.expand_path("../tasks/templates", __FILE__)
24
+
25
+ def create_initializer_file
26
+ template "initializer.rb", File.join("config/initializers/db2query.rb")
27
+ end
28
+ end
29
+ end
@@ -1,58 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- DB2_QUERY_DATABASE_TEMPLATE ||= <<-EOF
4
- # frozen_string_literal: true
5
- # Database configuration example
6
- development:
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
14
- conn_string:
15
- driver: DB2
16
- database: ARUNIT2
17
- dbalias: ARUNIT2
18
- hostname: LOCALHOST
19
- currentschema: LIBTEST
20
- port: "0"
21
- protocol: IPC
22
- uid: <%= ENV["DB2EC_UID"] %>
23
- pwd: <%= ENV["DB2EC_PWD"] %>
24
- test:
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
32
- conn_string:
33
- driver: DB2
34
- database: ARUNIT2
35
- dbalias: ARUNIT2
36
- hostname: LOCALHOST
37
- currentschema: LIBTEST
38
- port: "0"
39
- protocol: IPC
40
- uid: <%= ENV["DB2EC_UID"] %>
41
- pwd: <%= ENV["DB2EC_PWD"] %>
42
- EOF
3
+ require "db2_query/tasks"
43
4
 
44
5
  namespace :db2query do
45
6
  desc "Create Database configuration file"
46
7
  task :database do
47
- database_path = "#{Rails.root}/config/db2query_database.yml"
48
- if File.exist?(database_path)
49
- raise ArgumentError, "File exists."
50
- else
51
- puts " Creating database config file ..."
52
- File.open(database_path, "w") do |file|
53
- file.puts DB2_QUERY_DATABASE_TEMPLATE
54
- end
55
- puts " File '#{database_path}' created."
56
- end
8
+ Db2Query::DatabaseTask.generate_file
57
9
  end
58
10
  end
@@ -3,7 +3,7 @@
3
3
  namespace :db2query do
4
4
  desc "Create Initializer and Database configuration file"
5
5
  task :init do
6
- Rake::Task["db2query:initializer"].invoke
7
6
  Rake::Task["db2query:database"].invoke
7
+ Rake::Task["db2query:initializer"].invoke
8
8
  end
9
9
  end
@@ -1,42 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- DB2_QUERY_INITIALIZER_TEMPLATE ||= <<-EOF
4
- # frozen_string_literal: true
5
-
6
- require "db2_query"
7
- require "db2_query/formatter"
8
-
9
- DB2Query::Base.initiation do |base|
10
- base.configurations = base.parent.config
11
- base.establish_connection ENV['RAILS_ENV'].to_sym
12
- end
13
-
14
- # Example
15
-
16
- class FirstNameFormatter < DB2Query::AbstractFormatter
17
- def format(value)
18
- "Dr." + value
19
- end
20
- end
21
-
22
- DB2Query::Formatter.registration do |format|
23
- format.register(:first_name_formatter, FirstNameFormatter)
24
- end
25
- EOF
3
+ require "db2_query/tasks"
26
4
 
27
5
  namespace :db2query do
28
6
  desc "Create Initializer file"
29
7
  task :initializer do
30
- # Create initializer file
31
- initializer_path = "#{Rails.root}/config/initializers/db2query.rb"
32
- if File.exist?(initializer_path)
33
- raise ArgumentError, "File exists."
34
- else
35
- puts " Creating initializer file ..."
36
- File.open(initializer_path, "w") do |file|
37
- file.puts DB2_QUERY_INITIALIZER_TEMPLATE
38
- end
39
- puts " File '#{initializer_path}' created."
40
- end
8
+ Db2Query::InitializerTask.generate_file
41
9
  end
42
10
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ development:
4
+ dsn: TODO
5
+ idle: 5
6
+ pool: 5
7
+ timeout: 5
8
+
9
+ test:
10
+ dsn: TODO
11
+ idle: 5
12
+ pool: 5
13
+ timeout: 5
14
+
15
+ production:
16
+ dsn: TODO
17
+ idle: 5
18
+ pool: 5
19
+ timeout: 5
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "db2_query"
4
+
5
+ Db2Query::Base.initiation do |base|
6
+ base.set_field_types
7
+ base.establish_connection
8
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Db2Query
4
+ module Type
5
+ class Binary
6
+ def type
7
+ :binary
8
+ end
9
+
10
+ def serialize(value)
11
+ value.unpack1("H*")
12
+ end
13
+
14
+ def deserialize(value)
15
+ [value].pack("H*")
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Db2Query
4
+ module Type
5
+ class Boolean < Value
6
+ TRUE_VALUES = [
7
+ true, 1, "1", "t", "T",
8
+ "true", "TRUE", "on", "ON",
9
+ :"1", :t, :T, :true, :TRUE, :on, :ON
10
+ ].freeze
11
+
12
+ DEFAULT = { true: true, false: false }
13
+
14
+ def initialize(options = DEFAULT)
15
+ super(options)
16
+ end
17
+
18
+ def name
19
+ :boolean
20
+ end
21
+
22
+ def serialize(value)
23
+ case value
24
+ when *TRUE_VALUES
25
+ 1
26
+ else
27
+ 0
28
+ end
29
+ end
30
+
31
+ def deserialize(value)
32
+ case value
33
+ when 1
34
+ options[:true]
35
+ else
36
+ options[:false]
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Db2Query
4
+ module Type
5
+ class Date < Value
6
+ def type
7
+ :string
8
+ end
9
+
10
+ YMD_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
11
+ DMY_DATE = /\A(\d\d)-(\d\d)-(\d{4})\z/
12
+
13
+ def serialize(value)
14
+ if value.is_a?(::String)
15
+ value = value.tr("/", "-")
16
+ case value
17
+ when YMD_DATE, DMY_DATE
18
+ quote(::Date.parse(value))
19
+ else
20
+ nil
21
+ end
22
+ elsif value.is_a?(::Date)
23
+ quote(value.strftime("%F"))
24
+ else
25
+ nil
26
+ end
27
+ end
28
+
29
+ def deserialize(value)
30
+ ::Date.parse(value.to_s)
31
+ end
32
+ end
33
+ end
34
+ end