yesql 0.1.8 → 0.2.0
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.
- checksums.yaml +4 -4
- data/README.md +6 -22
- data/lib/.rbnext/2.3/yesql/errors/file_path_does_not_exist_error.rb +40 -0
- data/lib/.rbnext/2.3/yesql/errors/no_bindings_provided_error.rb +38 -0
- data/lib/.rbnext/2.3/yesql/errors/output_argument_error.rb +31 -0
- data/lib/.rbnext/2.3/yesql/query/transform_result.rb +48 -0
- data/lib/.rbnext/2.7/yesql/bindings/extract.rb +71 -0
- data/lib/.rbnext/2.7/yesql/bindings/extractor.rb +38 -0
- data/lib/.rbnext/2.7/yesql/bindings/transformed.rb +58 -0
- data/lib/.rbnext/2.7/yesql/bindings/utils.rb +16 -0
- data/lib/.rbnext/2.7/yesql/errors/file_path_does_not_exist_error.rb +43 -0
- data/lib/.rbnext/2.7/yesql/errors/no_bindings_provided_error.rb +41 -0
- data/lib/.rbnext/2.7/yesql/query/transform_result.rb +48 -0
- data/lib/.rbnext/2.7/yesql/statement.rb +44 -0
- data/lib/.rbnext/2.7/yesql/utils/read.rb +20 -0
- data/lib/.rbnext/3.0/yesql/bindings/extract.rb +71 -0
- data/lib/.rbnext/3.0/yesql/bindings/transformed.rb +58 -0
- data/lib/.rbnext/3.0/yesql/common/adapter.rb +18 -0
- data/lib/.rbnext/3.0/yesql/config/configuration.rb +32 -0
- data/lib/.rbnext/3.0/yesql/errors/file_path_does_not_exist_error.rb +43 -0
- data/lib/.rbnext/3.0/yesql/errors/no_bindings_provided_error.rb +41 -0
- data/lib/.rbnext/3.0/yesql/params/output.rb +26 -0
- data/lib/.rbnext/3.0/yesql/query/performer.rb +44 -0
- data/lib/.rbnext/3.0/yesql/query/result.rb +41 -0
- data/lib/.rbnext/3.0/yesql/query/transform_result.rb +48 -0
- data/lib/.rbnext/3.0/yesql/statement.rb +44 -0
- data/lib/.rbnext/3.0/yesql/utils/read.rb +20 -0
- data/lib/yesql.rb +25 -31
- data/lib/yesql/bindings/extract.rb +15 -21
- data/lib/yesql/bindings/extractor.rb +21 -21
- data/lib/yesql/bindings/transformed.rb +8 -11
- data/lib/yesql/bindings/utils.rb +7 -5
- data/lib/yesql/common/adapter.rb +6 -13
- data/lib/yesql/config/configuration.rb +4 -5
- data/lib/yesql/errors/file_path_does_not_exist_error.rb +22 -17
- data/lib/yesql/errors/no_bindings_provided_error.rb +18 -19
- data/lib/yesql/errors/output_argument_error.rb +13 -4
- data/lib/yesql/params/output.rb +6 -14
- data/lib/yesql/query/performer.rb +13 -42
- data/lib/yesql/query/result.rb +12 -17
- data/lib/yesql/query/transform_result.rb +11 -21
- data/lib/yesql/statement.rb +19 -24
- data/lib/yesql/utils/read.rb +11 -8
- data/lib/yesql/version.rb +1 -1
- metadata +47 -17
- data/.gitignore +0 -4
- data/.rubocop.yml +0 -20
- data/Gemfile +0 -9
- data/Gemfile.lock +0 -167
- data/Rakefile +0 -1
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/lib/yesql/errors/cache_expiration_error.rb +0 -18
- data/yesql.gemspec +0 -28
data/lib/yesql/bindings/utils.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
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
|
+
|
6
8
|
def statement_binds(extractor)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
statement(readable: true)
|
10
|
+
.scan(::YeSQL::BIND_REGEX)
|
11
|
+
.map(&:first)
|
12
|
+
.map { extractor[_1.to_sym][:bind].values_at(:vals, :vars) }
|
11
13
|
end
|
12
14
|
end
|
13
15
|
end
|
data/lib/yesql/common/adapter.rb
CHANGED
@@ -1,25 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "forwardable"
|
4
4
|
|
5
5
|
module ::YeSQL
|
6
6
|
module Common
|
7
7
|
module Adapter
|
8
|
-
extend Forwardable
|
8
|
+
extend ::Forwardable
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
def adapter
|
13
|
-
::ActiveRecord::Base.connection.adapter_name
|
14
|
-
end
|
10
|
+
def mysql? = adapter == "Mysql2"
|
11
|
+
def pg? = adapter == "PostgreSQL"
|
15
12
|
|
16
|
-
|
17
|
-
adapter == 'Mysql2'
|
18
|
-
end
|
13
|
+
private
|
19
14
|
|
20
|
-
def
|
21
|
-
adapter == 'PostgreSQL'
|
22
|
-
end
|
15
|
+
def adapter = ::ActiveRecord::Base.connection.adapter_name
|
23
16
|
end
|
24
17
|
end
|
25
18
|
end
|
@@ -3,20 +3,19 @@
|
|
3
3
|
module ::YeSQL
|
4
4
|
module Config
|
5
5
|
class Configuration
|
6
|
-
attr_accessor :path
|
6
|
+
attr_accessor :connection, :path
|
7
7
|
|
8
|
-
DEFAULT_PATH =
|
8
|
+
DEFAULT_PATH = "app/yesql"
|
9
9
|
|
10
10
|
def initialize
|
11
|
+
@connection = ""
|
11
12
|
@path = DEFAULT_PATH
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
15
16
|
|
16
17
|
class << self
|
17
|
-
def config
|
18
|
-
@config ||= ::YeSQL::Configuration.new
|
19
|
-
end
|
18
|
+
def config = @config ||= ::YeSQL::Configuration.new
|
20
19
|
|
21
20
|
def configure
|
22
21
|
yield config if block_given?
|
@@ -1,17 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module YeSQL
|
3
|
+
module ::YeSQL
|
4
4
|
module Errors
|
5
|
-
|
6
|
-
def
|
7
|
-
|
5
|
+
class FilePathDoesNotExistError
|
6
|
+
def initialize(file_path)
|
7
|
+
@file_path = file_path
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
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
|
+
)
|
11
22
|
end
|
12
23
|
|
13
24
|
private
|
14
25
|
|
26
|
+
attr_reader :file_path
|
27
|
+
|
15
28
|
MESSAGE = <<~MSG
|
16
29
|
|
17
30
|
SQL file "%<file_path>s" does not exist in %<path>s.
|
@@ -22,17 +35,9 @@ module YeSQL
|
|
22
35
|
MSG
|
23
36
|
private_constant :MESSAGE
|
24
37
|
|
25
|
-
def file_exists?(file_path)
|
26
|
-
|
27
|
-
|
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
|
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
|
36
41
|
end
|
37
42
|
end
|
38
43
|
end
|
@@ -1,20 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "yesql/utils/read"
|
4
4
|
|
5
5
|
module ::YeSQL
|
6
6
|
module Errors
|
7
|
-
|
8
|
-
|
9
|
-
return unless statement_binds(file_path).size.positive?
|
7
|
+
class NoBindingsProvidedError
|
8
|
+
include ::YeSQL::Utils::Read
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
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)
|
14
20
|
end
|
15
21
|
|
16
22
|
private
|
17
23
|
|
24
|
+
attr_reader :binds, :file_path
|
25
|
+
|
18
26
|
MESSAGE = <<~MSG
|
19
27
|
|
20
28
|
YeSQL invoked without bindings.
|
@@ -25,18 +33,9 @@ module ::YeSQL
|
|
25
33
|
MSG
|
26
34
|
private_constant :MESSAGE
|
27
35
|
|
28
|
-
def statement_binds(
|
29
|
-
|
30
|
-
|
31
|
-
break [] if scanned_binds.size.zero?
|
32
|
-
|
33
|
-
break scanned_binds.sort
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def renderable_statement_binds(file_path)
|
38
|
-
statement_binds(file_path).flatten.map { |bind| "- `#{bind}`\n" }.join
|
39
|
-
end
|
36
|
+
def statement_binds = statement.scan(::YeSQL::BIND_REGEX).tap { break (_1 || []).sort }
|
37
|
+
def renderable_statement_binds = statement_binds.flatten.map { "- `#{_1}`\n" }.join
|
38
|
+
def expected_binds? = binds.is_a?(::Hash) && !binds.empty?
|
40
39
|
end
|
41
40
|
end
|
42
41
|
end
|
@@ -1,14 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module YeSQL
|
3
|
+
module ::YeSQL
|
4
4
|
module Errors
|
5
|
-
|
6
|
-
def
|
5
|
+
class OutputArgumentError
|
6
|
+
def initialize(output)
|
7
|
+
@output = output
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate_output_options
|
7
11
|
return if output.nil?
|
12
|
+
return if OPTIONS.include?(output.to_sym)
|
8
13
|
|
9
|
-
raise ArgumentError, format(MESSAGE, output)
|
14
|
+
raise ArgumentError, format(MESSAGE, output)
|
10
15
|
end
|
11
16
|
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :output
|
20
|
+
|
12
21
|
MESSAGE = <<~MSG
|
13
22
|
Unsupported `output` option given `%s`. Possible values are:
|
14
23
|
- `columns`: returns an array with the columns from the result.
|
data/lib/yesql/params/output.rb
CHANGED
@@ -1,28 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "yesql"
|
4
|
+
require "forwardable"
|
5
5
|
|
6
6
|
module ::YeSQL
|
7
7
|
module Params
|
8
8
|
class Output
|
9
|
-
extend Forwardable
|
9
|
+
extend ::Forwardable
|
10
10
|
|
11
11
|
def initialize(output)
|
12
12
|
@output = output.to_s
|
13
13
|
end
|
14
14
|
|
15
|
-
def columns?
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
def rows?
|
20
|
-
output == 'rows'
|
21
|
-
end
|
22
|
-
|
23
|
-
def hash?
|
24
|
-
output == 'hash'
|
25
|
-
end
|
15
|
+
def columns? = output == "columns"
|
16
|
+
def rows? = output == "rows"
|
17
|
+
def hash? = output == "hash"
|
26
18
|
|
27
19
|
def_delegator(:output, :to_sym)
|
28
20
|
|
@@ -1,58 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
|
11
|
-
module YeSQL
|
3
|
+
require "yesql"
|
4
|
+
require "yesql/bindings/utils"
|
5
|
+
require "yesql/common/adapter"
|
6
|
+
require "yesql/bindings/transformed"
|
7
|
+
require "yesql/query/result"
|
8
|
+
require "yesql/query/transform_result"
|
9
|
+
require "yesql/params/output"
|
10
|
+
|
11
|
+
module ::YeSQL
|
12
12
|
module Query
|
13
13
|
class Performer
|
14
14
|
include ::YeSQL::Bindings::Utils
|
15
15
|
|
16
|
-
|
17
|
-
def initialize(bind_statement:,
|
18
|
-
bindings: {},
|
19
|
-
cache: {},
|
20
|
-
file_path:,
|
21
|
-
output: :rows,
|
22
|
-
prepare: false)
|
16
|
+
def initialize(bind_statement:, file_path:, bindings: {}, output: :rows, prepare: false)
|
23
17
|
@bind_statement = bind_statement
|
24
|
-
@cache = cache
|
25
|
-
@cache_key = cache[:key] || file_path
|
26
|
-
@expires_in = cache[:expires_in]
|
27
18
|
@file_path = file_path
|
28
19
|
@named_bindings = bindings.transform_keys(&:to_sym)
|
29
20
|
@output = ::YeSQL::Params::Output.new(output)
|
30
21
|
@prepare = prepare
|
31
22
|
end
|
32
|
-
# rubocop:enable Metrics/ParameterLists
|
33
|
-
|
34
|
-
def call
|
35
|
-
return transformed_result if cache.empty?
|
36
23
|
|
37
|
-
|
38
|
-
end
|
24
|
+
def call = ::YeSQL::Query::TransformResult.new(output: output, result: query_result).call
|
39
25
|
|
40
26
|
private
|
41
27
|
|
42
|
-
attr_reader :bind_statement,
|
43
|
-
:cache,
|
44
|
-
:cache_key,
|
45
|
-
:expires_in,
|
46
|
-
:file_path,
|
47
|
-
:named_bindings,
|
48
|
-
:output,
|
49
|
-
:prepare,
|
50
|
-
:rows
|
51
|
-
|
52
|
-
def transformed_result
|
53
|
-
@transformed_result ||=
|
54
|
-
::YeSQL::Query::TransformResult.new(output: output, result: query_result).call
|
55
|
-
end
|
28
|
+
attr_reader :bind_statement, :file_path, :named_bindings, :output, :prepare
|
56
29
|
|
57
30
|
def query_result
|
58
31
|
@query_result ||= ::YeSQL::Query::Result.new(binds: binds,
|
@@ -65,9 +38,7 @@ module YeSQL
|
|
65
38
|
::YeSQL::Bindings::Transformed.new(statement_binds: statement_binds(extractor)).call
|
66
39
|
end
|
67
40
|
|
68
|
-
def extractor
|
69
|
-
::YeSQL::Bindings::Extractor.new(bindings: named_bindings).call
|
70
|
-
end
|
41
|
+
def extractor = ::YeSQL::Bindings::Extractor.new(bindings: named_bindings).call
|
71
42
|
end
|
72
43
|
end
|
73
44
|
end
|
data/lib/yesql/query/result.rb
CHANGED
@@ -1,46 +1,41 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "yesql"
|
4
|
+
require "forwardable"
|
5
|
+
require "yesql/common/adapter"
|
6
6
|
|
7
7
|
module ::YeSQL
|
8
8
|
module Query
|
9
9
|
class Result
|
10
|
-
extend Forwardable
|
10
|
+
extend ::Forwardable
|
11
11
|
|
12
12
|
include ::YeSQL::Common::Adapter
|
13
13
|
|
14
|
-
def initialize(
|
14
|
+
def initialize(bind_statement:, file_path:, prepare:, binds: [])
|
15
15
|
@binds = binds
|
16
16
|
@bind_statement = bind_statement
|
17
|
-
@connection = ActiveRecord::Base.connection
|
18
17
|
@file_path = file_path
|
19
18
|
@prepare_option = prepare
|
20
19
|
end
|
21
20
|
|
22
21
|
def call
|
23
|
-
return view_result
|
24
|
-
return rails5_result if ::
|
22
|
+
return view_result if view?
|
23
|
+
return rails5_result if ::ActiveRecord::VERSION::MAJOR == 5 && mysql?
|
25
24
|
|
26
25
|
exec_query(bound, file_path, binds, prepare: prepare_option)
|
27
26
|
end
|
28
27
|
|
29
28
|
private
|
30
29
|
|
31
|
-
attr_reader :binds, :bind_statement, :
|
30
|
+
attr_reader :binds, :bind_statement, :file_path, :prepare_option
|
32
31
|
|
33
32
|
def_delegators(:bind_statement, :bound, :to_s, :view?)
|
34
|
-
def_delegators(:connection,
|
33
|
+
def_delegators(:connection, :exec_query, :raw_connection)
|
35
34
|
def_delegators(:raw_connection, :prepare)
|
36
35
|
|
37
|
-
def view_result
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
def rails5_result
|
42
|
-
prepare(bound).execute(*binds)
|
43
|
-
end
|
36
|
+
def view_result = exec_query(bound)
|
37
|
+
def rails5_result = prepare(bound).execute(*binds)
|
38
|
+
def connection = @connection ||= ActiveRecord::Base.connection
|
44
39
|
end
|
45
40
|
end
|
46
41
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "yesql"
|
4
|
+
require "yesql/common/adapter"
|
5
|
+
require "forwardable"
|
6
6
|
|
7
7
|
module ::YeSQL
|
8
8
|
module Query
|
9
9
|
class TransformResult
|
10
|
-
extend Forwardable
|
10
|
+
extend ::Forwardable
|
11
11
|
|
12
12
|
include ::YeSQL::Common::Adapter
|
13
13
|
|
@@ -17,7 +17,7 @@ module ::YeSQL
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def call
|
20
|
-
if
|
20
|
+
if rails_5? && mysql?
|
21
21
|
return columns if columns?
|
22
22
|
return rows_values if rows?
|
23
23
|
return array_of_symbol_hashes if hash?
|
@@ -32,27 +32,17 @@ module ::YeSQL
|
|
32
32
|
|
33
33
|
attr_reader :output, :result
|
34
34
|
|
35
|
-
def_delegators(:result, :rows, :to_a)
|
35
|
+
def_delegators(:result, :fields, :rows, :to_a)
|
36
36
|
def_delegators(:output, :columns?, :hash?, :rows?)
|
37
37
|
|
38
|
-
def rows_values
|
39
|
-
to_a.map { |e| e.respond_to?(:values) ? e.values : e }
|
40
|
-
end
|
41
|
-
|
42
38
|
def array_of_symbol_hashes
|
43
|
-
to_a.tap {
|
44
|
-
.map { |e| e.respond_to?(:symbolize_keys) ? e.symbolize_keys : e }
|
45
|
-
end
|
46
|
-
|
47
|
-
def hashed_rows(rows)
|
48
|
-
rows.map { |row| columns.zip(row).to_h }
|
39
|
+
to_a.tap { break hashed_rows(_1) if rails_5? }.map { _1&.symbolize_keys || _1 }
|
49
40
|
end
|
50
41
|
|
51
|
-
def columns
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
42
|
+
def columns = fields || result.columns
|
43
|
+
def rows_values = to_a.map { _1.respond_to?(:values) ? _1.values : _1 }
|
44
|
+
def hashed_rows(rows) = rows.map { columns.zip(_1).to_h }
|
45
|
+
def rails_5? = ::ActiveRecord::VERSION::MAJOR == 5
|
56
46
|
end
|
57
47
|
end
|
58
48
|
end
|