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