yesql 0.2.1 → 0.2.2

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.
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