yesql 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -0
  3. data/.rubocop.yml +20 -0
  4. data/Gemfile +9 -0
  5. data/Gemfile.lock +63 -0
  6. data/Rakefile +3 -0
  7. data/bin/console +14 -0
  8. data/bin/setup +8 -0
  9. data/lib/yesql.rb +15 -17
  10. data/lib/yesql/bindings/extract.rb +17 -11
  11. data/lib/yesql/bindings/extractor.rb +18 -20
  12. data/lib/yesql/bindings/transformed.rb +7 -5
  13. data/lib/yesql/bindings/utils.rb +6 -7
  14. data/lib/yesql/common/adapter.rb +11 -4
  15. data/lib/yesql/config/configuration.rb +3 -1
  16. data/lib/yesql/errors/file_path_does_not_exist_error.rb +17 -22
  17. data/lib/yesql/errors/no_bindings_provided_error.rb +18 -17
  18. data/lib/yesql/errors/output_argument_error.rb +4 -13
  19. data/lib/yesql/params/output.rb +12 -4
  20. data/lib/yesql/query/performer.rb +8 -4
  21. data/lib/yesql/query/result.rb +11 -5
  22. data/lib/yesql/query/transform_result.rb +19 -8
  23. data/lib/yesql/statement.rb +16 -10
  24. data/lib/yesql/utils/read.rb +8 -11
  25. data/lib/yesql/version.rb +1 -1
  26. data/yesql.gemspec +28 -0
  27. metadata +9 -54
  28. data/lib/.rbnext/2.3/yesql/errors/file_path_does_not_exist_error.rb +0 -40
  29. data/lib/.rbnext/2.3/yesql/errors/no_bindings_provided_error.rb +0 -38
  30. data/lib/.rbnext/2.3/yesql/errors/output_argument_error.rb +0 -31
  31. data/lib/.rbnext/2.3/yesql/query/transform_result.rb +0 -48
  32. data/lib/.rbnext/2.7/yesql/bindings/extract.rb +0 -71
  33. data/lib/.rbnext/2.7/yesql/bindings/extractor.rb +0 -38
  34. data/lib/.rbnext/2.7/yesql/bindings/transformed.rb +0 -58
  35. data/lib/.rbnext/2.7/yesql/bindings/utils.rb +0 -16
  36. data/lib/.rbnext/2.7/yesql/errors/file_path_does_not_exist_error.rb +0 -43
  37. data/lib/.rbnext/2.7/yesql/errors/no_bindings_provided_error.rb +0 -41
  38. data/lib/.rbnext/2.7/yesql/query/transform_result.rb +0 -48
  39. data/lib/.rbnext/2.7/yesql/statement.rb +0 -44
  40. data/lib/.rbnext/2.7/yesql/utils/read.rb +0 -20
  41. data/lib/.rbnext/3.0/yesql/bindings/extract.rb +0 -71
  42. data/lib/.rbnext/3.0/yesql/bindings/transformed.rb +0 -58
  43. data/lib/.rbnext/3.0/yesql/common/adapter.rb +0 -18
  44. data/lib/.rbnext/3.0/yesql/config/configuration.rb +0 -32
  45. data/lib/.rbnext/3.0/yesql/errors/file_path_does_not_exist_error.rb +0 -43
  46. data/lib/.rbnext/3.0/yesql/errors/no_bindings_provided_error.rb +0 -41
  47. data/lib/.rbnext/3.0/yesql/params/output.rb +0 -26
  48. data/lib/.rbnext/3.0/yesql/query/performer.rb +0 -44
  49. data/lib/.rbnext/3.0/yesql/query/result.rb +0 -41
  50. data/lib/.rbnext/3.0/yesql/query/transform_result.rb +0 -48
  51. data/lib/.rbnext/3.0/yesql/statement.rb +0 -44
  52. data/lib/.rbnext/3.0/yesql/utils/read.rb +0 -20
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ::YeSQL
4
- module Errors
5
- class FilePathDoesNotExistError
6
- def initialize(file_path)
7
- @file_path = file_path
8
- end
9
-
10
- def validate_file_path_existence
11
- return if file_exists?
12
-
13
- raise(
14
- ::NotImplementedError,
15
- format(
16
- MESSAGE,
17
- available_files: available_files,
18
- file_path: file_path,
19
- path: ::YeSQL.config.path
20
- )
21
- )
22
- end
23
-
24
- private
25
-
26
- attr_reader :file_path
27
-
28
- MESSAGE = <<-MSG
29
- SQL file "%<file_path>s" does not exist in %<path>s.
30
- Available SQL files are:
31
- %<available_files>s
32
- MSG
33
- private_constant :MESSAGE
34
-
35
- def file_exists? ; path_files.any? { |_1| _1.include?("#{file_path}.sql") }; end
36
- def path_files ; @path_files ||= Dir["#{::YeSQL.config.path}/**/*.sql"]; end
37
- def available_files ; path_files.map { |_1| "- #{_1}\n" }.join; end
38
- end
39
- end
40
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "yesql/utils/read"
4
-
5
- module ::YeSQL
6
- module Errors
7
- class NoBindingsProvidedError
8
- include ::YeSQL::Utils::Read
9
-
10
- def initialize(binds, file_path)
11
- @binds = binds
12
- @file_path = file_path
13
- end
14
-
15
- def validate_statement_bindings
16
- return unless statement_binds.size.positive?
17
- return if expected_binds?
18
-
19
- raise ::ArgumentError, format(MESSAGE, renderable_statement_binds)
20
- end
21
-
22
- private
23
-
24
- attr_reader :binds, :file_path
25
-
26
- MESSAGE = <<-MSG
27
- YeSQL invoked without bindings.
28
- Expected bindings are:
29
- %s
30
- MSG
31
- private_constant :MESSAGE
32
-
33
- def statement_binds ; statement.scan(::YeSQL::BIND_REGEX).tap { |_1| break (_1 || []).sort }; end
34
- def renderable_statement_binds ; statement_binds.flatten.map { |_1| "- `#{_1}`\n" }.join; end
35
- def expected_binds? ; binds.is_a?(::Hash) && !binds.empty?; end
36
- end
37
- end
38
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ::YeSQL
4
- module Errors
5
- class OutputArgumentError
6
- def initialize(output)
7
- @output = output
8
- end
9
-
10
- def validate_output_options
11
- return if output.nil?
12
- return if OPTIONS.include?(output.to_sym)
13
-
14
- raise ArgumentError, format(MESSAGE, output)
15
- end
16
-
17
- private
18
-
19
- attr_reader :output
20
-
21
- MESSAGE = <<-MSG
22
- Unsupported `output` option given `%s`. Possible values are:
23
- - `columns`: returns an array with the columns from the result.
24
- - `hash`: returns an array of hashes combining both, the columns and rows from the statement result.
25
- - `rows`: returns an array of arrays for each row from the given SQL statement.
26
- MSG
27
- OPTIONS = %i[columns hash rows].freeze
28
- private_constant :MESSAGE, :OPTIONS
29
- end
30
- end
31
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "yesql"
4
- require "yesql/common/adapter"
5
- require "forwardable"
6
-
7
- module ::YeSQL
8
- module Query
9
- class TransformResult
10
- extend ::Forwardable
11
-
12
- include ::YeSQL::Common::Adapter
13
-
14
- def initialize(output:, result:)
15
- @output = output
16
- @result = result
17
- end
18
-
19
- def call
20
- if rails_5? && mysql?
21
- return columns if columns?
22
- return rows_values if rows?
23
- return array_of_symbol_hashes if hash?
24
- end
25
-
26
- return result.public_send(output.to_sym) if columns? || rows?
27
-
28
- to_a.map(&:symbolize_keys)
29
- end
30
-
31
- private
32
-
33
- attr_reader :output, :result
34
-
35
- def_delegators(:result, :fields, :rows, :to_a)
36
- def_delegators(:output, :columns?, :hash?, :rows?)
37
-
38
- def array_of_symbol_hashes
39
- to_a.tap { break hashed_rows(_1) if rails_5? }.map { |_1| ((((__safe_lvar__ = _1) || true) && (!__safe_lvar__.nil? || nil)) && __safe_lvar__.symbolize_keys) || _1 }
40
- end
41
-
42
- def columns ; fields || result.columns; end
43
- def rows_values ; to_a.map { |_1| _1.respond_to?(:values) ? _1.values : _1 }; end
44
- def hashed_rows(rows) ; rows.map { |_1| columns.zip(_1).to_h }; end
45
- def rails_5? ; ::ActiveRecord::VERSION::MAJOR == 5; end
46
- end
47
- end
48
- end
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "yesql"
4
- require "yesql/common/adapter"
5
-
6
- module ::YeSQL
7
- module Bindings
8
- class Extract
9
- include ::YeSQL::Common::Adapter
10
-
11
- def initialize(hash, indexed_bindings, index, value)
12
- @hash = hash
13
- @index = index
14
- @indexed_bindings = indexed_bindings
15
- @value = value
16
- end
17
-
18
- def bind_vals
19
- return [nil, value] unless array?
20
-
21
- value.map { |_1| [nil, _1] }
22
- end
23
-
24
- def bind_vars
25
- if mysql?
26
- return "?" unless array?
27
-
28
- Array.new(size, "?").join(", ")
29
- elsif pg?
30
- return "$#{last_val}" unless array?
31
-
32
- value.map.with_index(bind_index) { |_1, _2| "$#{_2}" }.join(", ")
33
- end
34
- end
35
-
36
- def prev
37
- return if first?
38
-
39
- indexed_bindings[index - 2].first
40
- end
41
-
42
- def last_val ; prev_last_val + current_val_size; end
43
-
44
- private
45
-
46
- attr_reader :hash, :index, :indexed_bindings, :value
47
-
48
- def current_val_size
49
- return size if array?
50
-
51
- 1
52
- end
53
-
54
- def prev_last_val
55
- return 0 if first?
56
-
57
- hash[prev][:last_val]
58
- end
59
-
60
- def bind_index
61
- return 1 if first?
62
-
63
- prev_last_val + 1
64
- end
65
-
66
- def size ; value.size; end
67
- def first? ; index == 1; end
68
- def array? ; value.is_a?(Array); end
69
- end
70
- end
71
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "yesql/bindings/extract"
4
-
5
- module ::YeSQL
6
- module Bindings
7
- class Extractor
8
- def initialize(bindings: {})
9
- @bindings = bindings
10
- @indexed_bindings = bindings.to_a
11
- end
12
-
13
- def call
14
- bindings
15
- .each_with_object({})
16
- .with_index(1) do |((key, value), hash), index|
17
- hash[key] = binding_extracts(hash, indexed_bindings, index, key, value)
18
- end
19
- end
20
-
21
- private
22
-
23
- attr_reader :bindings, :indexed_bindings
24
-
25
- def binding_extracts(hash, indexed_bindings, index, key, value)
26
- ::YeSQL::Bindings::Extract.new(hash, indexed_bindings, index, value).tap do |_1|
27
- break {
28
- bind: { vals: _1.bind_vals, vars: _1.bind_vars },
29
- last_val: _1.last_val,
30
- match: key,
31
- prev: _1.prev,
32
- value: value
33
- }
34
- end
35
- end
36
- end
37
- end
38
- end
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "yesql"
4
- require "yesql/common/adapter"
5
-
6
- module ::YeSQL
7
- module Bindings
8
- class Transformed
9
- include ::YeSQL::Common::Adapter
10
-
11
- def initialize(statement_binds:)
12
- @statement_binds = statement_binds
13
- end
14
-
15
- def call
16
- return mysql_rails5_binds if rails5? && mysql?
17
- return mysql_binds if !rails5? && mysql?
18
-
19
- pg_binds
20
- end
21
-
22
- private
23
-
24
- attr_reader :statement_binds
25
-
26
- def rails5? ; ::ActiveRecord::VERSION::MAJOR == 5; end
27
-
28
- def mysql_rails5_binds
29
- statement_binds
30
- .flat_map(&:first)
31
- .each_slice(2)
32
- .flat_map do |_1, _2|
33
- next [_1, _2].compact.map(&:last) if _1.is_a?(Array)
34
-
35
- _2
36
- end
37
- end
38
-
39
- def mysql_binds
40
- statement_binds
41
- .map(&:first)
42
- .flatten
43
- .each_slice(2)
44
- .to_a
45
- end
46
-
47
- def pg_binds
48
- statement_binds
49
- .sort_by { |_1, _2| _2.to_s.tr("$", "").to_i }
50
- .uniq
51
- .map(&:first)
52
- .flatten
53
- .each_slice(2)
54
- .to_a
55
- end
56
- end
57
- end
58
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ::YeSQL
4
- module Bindings
5
- module Utils
6
- include ::YeSQL::Utils::Read
7
-
8
- def statement_binds(extractor)
9
- statement(readable: true)
10
- .scan(::YeSQL::BIND_REGEX)
11
- .map(&:first)
12
- .map { |_1| extractor[_1.to_sym][:bind].values_at(:vals, :vars) }
13
- end
14
- end
15
- end
16
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ::YeSQL
4
- module Errors
5
- class FilePathDoesNotExistError
6
- def initialize(file_path)
7
- @file_path = file_path
8
- end
9
-
10
- def validate_file_path_existence
11
- return if file_exists?
12
-
13
- raise(
14
- ::NotImplementedError,
15
- format(
16
- MESSAGE,
17
- available_files: available_files,
18
- file_path: file_path,
19
- path: ::YeSQL.config.path
20
- )
21
- )
22
- end
23
-
24
- private
25
-
26
- attr_reader :file_path
27
-
28
- MESSAGE = <<~MSG
29
-
30
- SQL file "%<file_path>s" does not exist in %<path>s.
31
-
32
- Available SQL files are:
33
-
34
- %<available_files>s
35
- MSG
36
- private_constant :MESSAGE
37
-
38
- def file_exists? ; path_files.any? { |_1| _1.include?("#{file_path}.sql") }; end
39
- def path_files ; @path_files ||= Dir["#{::YeSQL.config.path}/**/*.sql"]; end
40
- def available_files ; path_files.map { |_1| "- #{_1}\n" }.join; end
41
- end
42
- end
43
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "yesql/utils/read"
4
-
5
- module ::YeSQL
6
- module Errors
7
- class NoBindingsProvidedError
8
- include ::YeSQL::Utils::Read
9
-
10
- def initialize(binds, file_path)
11
- @binds = binds
12
- @file_path = file_path
13
- end
14
-
15
- def validate_statement_bindings
16
- return unless statement_binds.size.positive?
17
- return if expected_binds?
18
-
19
- raise ::ArgumentError, format(MESSAGE, renderable_statement_binds)
20
- end
21
-
22
- private
23
-
24
- attr_reader :binds, :file_path
25
-
26
- MESSAGE = <<~MSG
27
-
28
- YeSQL invoked without bindings.
29
-
30
- Expected bindings are:
31
-
32
- %s
33
- MSG
34
- private_constant :MESSAGE
35
-
36
- def statement_binds ; statement.scan(::YeSQL::BIND_REGEX).tap { |_1| break (_1 || []).sort }; end
37
- def renderable_statement_binds ; statement_binds.flatten.map { |_1| "- `#{_1}`\n" }.join; end
38
- def expected_binds? ; binds.is_a?(::Hash) && !binds.empty?; end
39
- end
40
- end
41
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "yesql"
4
- require "yesql/common/adapter"
5
- require "forwardable"
6
-
7
- module ::YeSQL
8
- module Query
9
- class TransformResult
10
- extend ::Forwardable
11
-
12
- include ::YeSQL::Common::Adapter
13
-
14
- def initialize(output:, result:)
15
- @output = output
16
- @result = result
17
- end
18
-
19
- def call
20
- if rails_5? && mysql?
21
- return columns if columns?
22
- return rows_values if rows?
23
- return array_of_symbol_hashes if hash?
24
- end
25
-
26
- return result.public_send(output.to_sym) if columns? || rows?
27
-
28
- to_a.map(&:symbolize_keys)
29
- end
30
-
31
- private
32
-
33
- attr_reader :output, :result
34
-
35
- def_delegators(:result, :fields, :rows, :to_a)
36
- def_delegators(:output, :columns?, :hash?, :rows?)
37
-
38
- def array_of_symbol_hashes
39
- to_a.tap { break hashed_rows(_1) if rails_5? }.map { |_1| _1&.symbolize_keys || _1 }
40
- end
41
-
42
- def columns ; fields || result.columns; end
43
- def rows_values ; to_a.map { |_1| _1.respond_to?(:values) ? _1.values : _1 }; end
44
- def hashed_rows(rows) ; rows.map { |_1| columns.zip(_1).to_h }; end
45
- def rails_5? ; ::ActiveRecord::VERSION::MAJOR == 5; end
46
- end
47
- end
48
- end