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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8b1e4a24637a3f453ed612d37238b171e9bfc2cbbfd779a0675f06c049a61a2
4
- data.tar.gz: 5b0ec67d1aab2d2b73bfe27559853f9267388fa39160bcdd318920bbade17d2e
3
+ metadata.gz: d4cad8cd91b4afba6c7a8722f9f0dfd6092552d2f4ce735c6880425241122b43
4
+ data.tar.gz: b8be652b46ee03e081ec2d8bc3bcc2321e26e2b7fcd55dcbf2a2bb288ddac139
5
5
  SHA512:
6
- metadata.gz: 78a50bcda5bb70dc61f3604e2071b97a06f09866eca3d701dad42be054ead0d2db18a2fe103f33b87f9954c143d5f2a501d10329703de82d6369739fb0e830c3
7
- data.tar.gz: 0c7b14bfe915227caa8b6c518b99a12f0cd3a45ababc41fe07515460fd70473687183bfb9a85ba1250f2fcde2db0380dd2815ee6d6ce2f318a721dd248d59c8b
6
+ metadata.gz: 4dc794c44484b4fcc8815fa866023c6cf5d2f4b82d4f2c45c6de7e86082eaa3ba838c55e750e3f2fd53b0312b4be699c7ddc900400c8445c377fd7c6d1139190
7
+ data.tar.gz: 88b860a5ce91655366f9d73336b522678a8f709938881e1ff150a13565b57cd12b65c753531ecfb886528d162405c36ca9036c1c3cba52a62aa2e3e3993e76fb
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ spec/minimalpg/log/*
2
+ spec/minimalmysql/log/*
3
+ spec/minimalpg/db/*
4
+ spec/minimalmysql/db/*
5
+
6
+ *.un~
7
+ *.swp
data/.rubocop.yml ADDED
@@ -0,0 +1,20 @@
1
+ require: rubocop-rspec
2
+
3
+ Metrics/BlockLength:
4
+ Exclude:
5
+ - spec/**/*_spec.rb
6
+ - spec/spec_helper.rb
7
+ - spec/yesql/shared/*
8
+
9
+ RSpec/FilePath:
10
+ Exclude:
11
+ - spec/**/*_spec.rb
12
+
13
+ RSpec/NestedGroups:
14
+ Enabled: False
15
+
16
+ RSpec/ExampleLength:
17
+ Enabled: False
18
+
19
+ RSpec/BeforeAfterAll:
20
+ Enabled: False
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gemspec
6
+
7
+ group :docs do
8
+ gem "yard"
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,63 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ yesql (0.2.2)
5
+ activerecord (>= 4.0.0.beta1)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activemodel (6.1.3.1)
11
+ activesupport (= 6.1.3.1)
12
+ activerecord (6.1.3.1)
13
+ activemodel (= 6.1.3.1)
14
+ activesupport (= 6.1.3.1)
15
+ activesupport (6.1.3.1)
16
+ concurrent-ruby (~> 1.0, >= 1.0.2)
17
+ i18n (>= 1.6, < 2)
18
+ minitest (>= 5.1)
19
+ tzinfo (~> 2.0)
20
+ zeitwerk (~> 2.3)
21
+ coderay (1.1.3)
22
+ concurrent-ruby (1.1.8)
23
+ diff-lcs (1.4.4)
24
+ i18n (1.8.10)
25
+ concurrent-ruby (~> 1.0)
26
+ method_source (1.0.0)
27
+ minitest (5.14.4)
28
+ mysql2 (0.5.3)
29
+ pg (1.2.3)
30
+ pry (0.13.1)
31
+ coderay (~> 1.1)
32
+ method_source (~> 1.0)
33
+ rspec (3.9.0)
34
+ rspec-core (~> 3.9.0)
35
+ rspec-expectations (~> 3.9.0)
36
+ rspec-mocks (~> 3.9.0)
37
+ rspec-core (3.9.3)
38
+ rspec-support (~> 3.9.3)
39
+ rspec-expectations (3.9.4)
40
+ diff-lcs (>= 1.2.0, < 2.0)
41
+ rspec-support (~> 3.9.0)
42
+ rspec-mocks (3.9.1)
43
+ diff-lcs (>= 1.2.0, < 2.0)
44
+ rspec-support (~> 3.9.0)
45
+ rspec-support (3.9.4)
46
+ tzinfo (2.0.4)
47
+ concurrent-ruby (~> 1.0)
48
+ yard (0.9.26)
49
+ zeitwerk (2.4.2)
50
+
51
+ PLATFORMS
52
+ x86_64-linux
53
+
54
+ DEPENDENCIES
55
+ mysql2 (~> 0.5.3)
56
+ pg (>= 0.18)
57
+ pry (~> 0.13.1)
58
+ rspec (~> 3.9.0)
59
+ yard
60
+ yesql!
61
+
62
+ BUNDLED WITH
63
+ 2.2.3
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "standard/rake"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "yesql"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lib/yesql.rb CHANGED
@@ -1,10 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "backports/2.0"
4
- require "ruby-next/language/setup"
5
-
6
- RubyNext::Language.setup_gem_load_path
7
-
8
3
  require "yesql/statement"
9
4
  require "yesql/version"
10
5
  require "yesql/config/configuration"
@@ -13,33 +8,36 @@ require "yesql/errors/file_path_does_not_exist_error"
13
8
  require "yesql/errors/no_bindings_provided_error"
14
9
  require "yesql/errors/output_argument_error"
15
10
 
16
- module ::YeSQL
11
+ module YeSQL
17
12
  include ::YeSQL::Config
13
+ include ::YeSQL::Errors::FilePathDoesNotExistError
14
+ include ::YeSQL::Errors::NoBindingsProvidedError
15
+ include ::YeSQL::Errors::OutputArgumentError
18
16
 
19
17
  BIND_REGEX = /(?<!:):(\w+)(?=\b)/
20
18
 
21
- def YeSQL(file_path, binds = {}, options = {})
19
+ def YeSQL(file_path, bindings = {}, options = {})
22
20
  output = options[:output] || :rows
23
21
 
24
- validate(binds, file_path, output)
25
- execute(binds, file_path, output, options[:prepare])
22
+ validate(bindings, file_path, output)
23
+ execute(bindings, file_path, output, options)
26
24
  end
27
25
 
28
26
  private
29
27
 
30
- def validate(binds, file_path, output)
31
- ::YeSQL::Errors::FilePathDoesNotExistError.new(file_path).validate_file_path_existence
32
- ::YeSQL::Errors::NoBindingsProvidedError.new(binds, file_path).validate_statement_bindings
33
- ::YeSQL::Errors::OutputArgumentError.new(output).validate_output_options
28
+ def validate(bindings, file_path, output)
29
+ validate_file_path_existence(file_path)
30
+ validate_statement_bindings(bindings, file_path)
31
+ validate_output_options(output)
34
32
  end
35
33
 
36
- def execute(binds, file_path, output, prepare)
34
+ def execute(bindings, file_path, output, options)
37
35
  ::YeSQL::Query::Performer.new(
38
- bindings: binds,
39
- bind_statement: ::YeSQL::Statement.new(binds, file_path),
36
+ bindings: bindings,
37
+ bind_statement: ::YeSQL::Statement.new(bindings, file_path),
40
38
  file_path: file_path,
41
39
  output: output,
42
- prepare: prepare
40
+ prepare: options[:prepare]
43
41
  ).call
44
42
  end
45
43
  end
@@ -8,7 +8,7 @@ module ::YeSQL
8
8
  class Extract
9
9
  include ::YeSQL::Common::Adapter
10
10
 
11
- def initialize(hash, indexed_bindings, index, value)
11
+ def initialize(indexed_bindings, hash, index, value)
12
12
  @hash = hash
13
13
  @index = index
14
14
  @indexed_bindings = indexed_bindings
@@ -18,35 +18,37 @@ module ::YeSQL
18
18
  def bind_vals
19
19
  return [nil, value] unless array?
20
20
 
21
- value.map { [nil, _1] }
21
+ value.map { |bind| [nil, bind] }
22
22
  end
23
23
 
24
24
  def bind_vars
25
25
  if mysql?
26
26
  return "?" unless array?
27
27
 
28
- Array.new(size, "?").join(", ")
28
+ Array.new(value.size, "?").join(", ")
29
29
  elsif pg?
30
30
  return "$#{last_val}" unless array?
31
31
 
32
- value.map.with_index(bind_index) { "$#{_2}" }.join(", ")
32
+ value.map.with_index(bind_index) { |_, i| "$#{i}" }.join(", ")
33
33
  end
34
34
  end
35
35
 
36
+ def last_val
37
+ prev_last_val + current_val_size
38
+ end
39
+
36
40
  def prev
37
41
  return if first?
38
42
 
39
43
  indexed_bindings[index - 2].first
40
44
  end
41
45
 
42
- def last_val = prev_last_val + current_val_size
43
-
44
46
  private
45
47
 
46
48
  attr_reader :hash, :index, :indexed_bindings, :value
47
49
 
48
50
  def current_val_size
49
- return size if array?
51
+ return value.size if array?
50
52
 
51
53
  1
52
54
  end
@@ -57,15 +59,19 @@ module ::YeSQL
57
59
  hash[prev][:last_val]
58
60
  end
59
61
 
62
+ def first?
63
+ index == 1
64
+ end
65
+
66
+ def array?
67
+ value.is_a?(Array)
68
+ end
69
+
60
70
  def bind_index
61
71
  return 1 if first?
62
72
 
63
73
  prev_last_val + 1
64
74
  end
65
-
66
- def size = value.size
67
- def first? = index == 1
68
- def array? = value.is_a?(Array)
69
75
  end
70
76
  end
71
77
  end
@@ -2,37 +2,35 @@
2
2
 
3
3
  require "yesql/bindings/extract"
4
4
 
5
- module ::YeSQL
5
+ module YeSQL
6
6
  module Bindings
7
7
  class Extractor
8
- def initialize(bindings: {})
8
+ def initialize(bindings:)
9
9
  @bindings = bindings
10
- @indexed_bindings = bindings.to_a
10
+ @indexed_bindings = (bindings || {}).to_a
11
11
  end
12
12
 
13
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
14
+ bindings.each_with_object({}).with_index(1) do |((key, value), hash), index|
15
+ hash[key] =
16
+ ::YeSQL::Bindings::Extract.new(indexed_bindings, hash, index, value).tap do |extract|
17
+ break {
18
+ bind: {
19
+ vals: extract.bind_vals,
20
+ vars: extract.bind_vars
21
+ },
22
+ last_val: extract.last_val,
23
+ match: key,
24
+ prev: extract.prev,
25
+ value: value
26
+ }
27
+ end
28
+ end
19
29
  end
20
30
 
21
31
  private
22
32
 
23
33
  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
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
34
  end
37
35
  end
38
36
  end
@@ -23,16 +23,18 @@ module ::YeSQL
23
23
 
24
24
  attr_reader :statement_binds
25
25
 
26
- def rails5? = ::ActiveRecord::VERSION::MAJOR == 5
26
+ def rails5?
27
+ ::ActiveRecord::VERSION::MAJOR == 5
28
+ end
27
29
 
28
30
  def mysql_rails5_binds
29
31
  statement_binds
30
32
  .flat_map(&:first)
31
33
  .each_slice(2)
32
- .flat_map do
33
- next [_1, _2].compact.map(&:last) if _1.is_a?(Array)
34
+ .flat_map do |first, last|
35
+ next [first, last].compact.map(&:last) if first.is_a?(Array)
34
36
 
35
- _2
37
+ last
36
38
  end
37
39
  end
38
40
 
@@ -46,7 +48,7 @@ module ::YeSQL
46
48
 
47
49
  def pg_binds
48
50
  statement_binds
49
- .sort_by { _2.to_s.tr("$", "").to_i }
51
+ .sort_by { |_, position| position.to_s.tr("$", "").to_i }
50
52
  .uniq
51
53
  .map(&:first)
52
54
  .flatten
@@ -1,15 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ::YeSQL
3
+ module YeSQL
4
4
  module Bindings
5
5
  module Utils
6
- include ::YeSQL::Utils::Read
7
-
8
6
  def statement_binds(extractor)
9
- statement(readable: true)
10
- .scan(::YeSQL::BIND_REGEX)
11
- .map(&:first)
12
- .map { extractor[_1.to_sym][:bind].values_at(:vals, :vars) }
7
+ ::YeSQL::Utils::Read
8
+ .statement(file_path, readable: true)
9
+ .scan(::YeSQL::BIND_REGEX).map do |(bind)|
10
+ extractor[bind.to_sym][:bind].values_at(:vals, :vars)
11
+ end
13
12
  end
14
13
  end
15
14
  end
@@ -7,12 +7,19 @@ module ::YeSQL
7
7
  module Adapter
8
8
  extend ::Forwardable
9
9
 
10
- def mysql? = adapter == "Mysql2"
11
- def pg? = adapter == "PostgreSQL"
10
+ # `adapter` might be a complex object, but
11
+ # for the sake of brevity it's just a string
12
+ def adapter
13
+ ::ActiveRecord::Base.connection.adapter_name
14
+ end
12
15
 
13
- private
16
+ def mysql?
17
+ adapter == "Mysql2"
18
+ end
14
19
 
15
- def adapter = ::ActiveRecord::Base.connection.adapter_name
20
+ def pg?
21
+ adapter == "PostgreSQL"
22
+ end
16
23
  end
17
24
  end
18
25
  end
@@ -15,7 +15,9 @@ module ::YeSQL
15
15
  end
16
16
 
17
17
  class << self
18
- def config = @config ||= ::YeSQL::Configuration.new
18
+ def config
19
+ @config ||= ::YeSQL::Configuration.new
20
+ end
19
21
 
20
22
  def configure
21
23
  yield config if block_given?
@@ -1,30 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module ::YeSQL
3
+ module YeSQL
4
4
  module Errors
5
- class FilePathDoesNotExistError
6
- def initialize(file_path)
7
- @file_path = file_path
8
- end
5
+ module FilePathDoesNotExistError
6
+ def validate_file_path_existence(file_path)
7
+ return if file_exists?(file_path)
9
8
 
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
- )
9
+ raise NotImplementedError, format(MESSAGE, available_files: available_files,
10
+ file_path: file_path, path: ::YeSQL.config.path)
22
11
  end
23
12
 
24
13
  private
25
14
 
26
- attr_reader :file_path
27
-
28
15
  MESSAGE = <<~MSG
29
16
 
30
17
  SQL file "%<file_path>s" does not exist in %<path>s.
@@ -35,9 +22,17 @@ module ::YeSQL
35
22
  MSG
36
23
  private_constant :MESSAGE
37
24
 
38
- def file_exists? = path_files.any? { _1.include?("#{file_path}.sql") }
39
- def path_files = @path_files ||= Dir["#{::YeSQL.config.path}/**/*.sql"]
40
- def available_files = path_files.map { "- #{_1}\n" }.join
25
+ def file_exists?(file_path)
26
+ path_files.any? { |filename| filename.include?("#{file_path}.sql") }
27
+ end
28
+
29
+ def available_files
30
+ path_files.map { |file| "- #{file}\n" }.join
31
+ end
32
+
33
+ def path_files
34
+ @path_files ||= Dir["#{::YeSQL.config.path}/**/*.sql"]
35
+ end
41
36
  end
42
37
  end
43
38
  end