mini_sql 0.1.2 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e88eaeeb85de88eed3c83b12481b9682a1de4327ee433098a46932866884c1d3
4
- data.tar.gz: eac737d3b6281392099675b6d3bcd25d6493d836d66204fa7de229583c2a3be8
3
+ metadata.gz: '00878f2e4f4b73c65e00aa20314193a4cd6626ff1cd43aa41d28aba5ccaa3d2f'
4
+ data.tar.gz: 48a868434abfc2aad3da5b5d40e74fca0763a0b712e43f4a606b0d8401329ac4
5
5
  SHA512:
6
- metadata.gz: 166faf87640bb2a07fe7d2f4e146274f7229f8c56f61e4160c1296a7f5d9587a5e11be09168abd792807f3bc5a08cec21b835e2ae81dc978c175bec6e155d607
7
- data.tar.gz: d43a73fa9abb29de17005b4e361c607509c7a34a82b88e07ad2a344820c3c1efe7bfced0358310c2286d1bf9cc63977c2159c8bbdc3df6233d028a3ca45dadec
6
+ metadata.gz: 9d25ce207be807b6b73d97df610a4a2a52ec442a2b3505709000ee551c9ccafc0a8131e05fc4f9320c6230d644137615fad2ca5138ce5d88590d9fa6f7400bf6
7
+ data.tar.gz: bc007f60d567966b17fae84e6b5b5275b39a8f6dde1e25ab2f7302a241f16cbf8397f10ab1ad365adacba6e60355f311c6b234dbff19b76f9f038dc10c919505
data/Gemfile.lock CHANGED
@@ -1,12 +1,18 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mini_sql (0.1.2)
4
+ mini_sql (0.1.3)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ activesupport (5.2.0)
10
+ concurrent-ruby (~> 1.0, >= 1.0.2)
11
+ i18n (>= 0.7, < 2)
12
+ minitest (~> 5.1)
13
+ tzinfo (~> 1.1)
9
14
  coderay (1.1.2)
15
+ concurrent-ruby (1.0.5)
10
16
  ffi (1.9.25)
11
17
  formatador (0.2.5)
12
18
  guard (2.14.2)
@@ -22,6 +28,8 @@ GEM
22
28
  guard-minitest (2.4.6)
23
29
  guard-compat (~> 1.2)
24
30
  minitest (>= 3.0)
31
+ i18n (1.0.1)
32
+ concurrent-ruby (~> 1.0)
25
33
  listen (3.1.5)
26
34
  rb-fsevent (~> 0.9, >= 0.9.4)
27
35
  rb-inotify (~> 0.9, >= 0.9.7)
@@ -44,11 +52,15 @@ GEM
44
52
  ruby_dep (1.5.0)
45
53
  shellany (0.0.1)
46
54
  thor (0.20.0)
55
+ thread_safe (0.3.6)
56
+ tzinfo (1.2.5)
57
+ thread_safe (~> 0.1)
47
58
 
48
59
  PLATFORMS
49
60
  ruby
50
61
 
51
62
  DEPENDENCIES
63
+ activesupport (~> 5.2)
52
64
  bundler (~> 1.16)
53
65
  guard (~> 2.14)
54
66
  guard-minitest (~> 2.4)
data/lib/mini_sql.rb CHANGED
@@ -1,7 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # we need this for a coder
4
+ require "bigdecimal"
5
+
1
6
  require_relative "mini_sql/version"
2
7
  require_relative "mini_sql/connection"
3
8
  require_relative "mini_sql/deserializer_cache"
4
9
  require_relative "mini_sql/builder"
10
+ require_relative "mini_sql/inline_param_encoder"
5
11
 
6
12
  module MiniSql
7
13
  autoload :Coders, "mini_sql/coders"
@@ -1,7 +1,7 @@
1
1
  class MiniSql::Builder
2
2
 
3
3
  def initialize(connection, template)
4
- @args = {}
4
+ @args = nil
5
5
  @sql = template
6
6
  @sections = {}
7
7
  @connection = connection
@@ -9,6 +9,7 @@ class MiniSql::Builder
9
9
 
10
10
  [:set, :where2, :where, :order_by, :limit, :left_join, :join, :offset, :select].each do |k|
11
11
  define_method k do |data, args = {}|
12
+ @args ||= {}
12
13
  @args.merge!(args)
13
14
  @sections[k] ||= []
14
15
  @sections[k] << data
@@ -50,7 +51,7 @@ class MiniSql::Builder
50
51
  @args.merge!(args)
51
52
  end
52
53
  sql = to_sql
53
- @connection.query(sql, args)
54
+ @connection.query(sql, @args)
54
55
  end
55
56
 
56
57
  def exec(args = nil)
@@ -58,7 +59,7 @@ class MiniSql::Builder
58
59
  @args.merge!(args)
59
60
  end
60
61
  sql = to_sql
61
- @connection.query(sql, args)
62
+ @connection.exec(sql, @args)
62
63
  end
63
64
 
64
65
  end
@@ -2,7 +2,7 @@ module MiniSql
2
2
  module Coders
3
3
  class NumericCoder < PG::SimpleDecoder
4
4
  def decode(string, tuple = nil, field = nil)
5
- string.to_f
5
+ BigDecimal.new(string)
6
6
  end
7
7
  end
8
8
  class IPAddrCoder < PG::SimpleDecoder
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module MiniSql
2
4
  class Connection
5
+ attr_reader :raw_connection
3
6
 
4
7
  def self.default_deserializer_cache
5
8
  @deserializer_cache ||= DeserializerCache.new
@@ -14,22 +17,49 @@ module MiniSql
14
17
  end
15
18
  end
16
19
 
17
- def initialize(conn, deserializer_cache = nil, type_map = nil)
20
+ # Initialize a new MiniSql::Connection object
21
+ #
22
+ # @param raw_connection [PG::Connection] an active connection to PG
23
+ # @param deserializer_cache [MiniSql::DeserializerCache] a cache of field names to deserializer, can be nil
24
+ # @param type_map [PG::TypeMap] a type mapper for all results returned, can be nil
25
+ def initialize(raw_connection, deserializer_cache: nil, type_map: nil, param_encoder: nil)
18
26
  # TODO adapter to support other databases
19
- @conn = conn
27
+ @raw_connection = raw_connection
20
28
  @deserializer_cache = deserializer_cache || Connection.default_deserializer_cache
21
- @type_map = type_map || Connection.type_map(conn)
29
+ @type_map = type_map || Connection.type_map(raw_connection)
30
+ @param_encoder = param_encoder || InlineParamEncoder.new(self)
22
31
  end
23
32
 
24
- def query_single(sql, params=nil)
33
+ # Returns a flat array containing all results.
34
+ # Note, if selecting multiple columns array will be flattened
35
+ #
36
+ # @param sql [String] the query to run
37
+ # @param params [Array or Hash], params to apply to query
38
+ # @return [Object] a flat array containing all results
39
+ def query_single(sql, *params)
25
40
  result = run(sql, params)
26
41
  result.type_map = @type_map
27
- result.column_values(0)
42
+ if result.nfields == 1
43
+ result.column_values(0)
44
+ else
45
+ array = []
46
+ f = 0
47
+ row = 0
48
+ while row < result.ntuples
49
+ while f < result.nfields
50
+ array << result.getvalue(row, f)
51
+ f += 1
52
+ end
53
+ f = 0
54
+ row += 1
55
+ end
56
+ array
57
+ end
28
58
  ensure
29
59
  result.clear if result
30
60
  end
31
61
 
32
- def query(sql, params=nil)
62
+ def query(sql, *params)
33
63
  result = run(sql, params)
34
64
  result.type_map = @type_map
35
65
  @deserializer_cache.materialize(result)
@@ -37,7 +67,7 @@ module MiniSql
37
67
  result.clear if result
38
68
  end
39
69
 
40
- def exec(sql, params=nil)
70
+ def exec(sql, *params)
41
71
  result = run(sql, params)
42
72
  result.cmd_tuples
43
73
  ensure
@@ -48,42 +78,17 @@ module MiniSql
48
78
  Builder.new(self, sql)
49
79
  end
50
80
 
51
- private
52
-
53
- def run(sql, params)
54
- if params
55
- @conn.async_exec(*process_params(sql, params))
56
- else
57
- @conn.async_exec(sql)
58
- end
81
+ def escape_string(str)
82
+ raw_connection.escape_string(str)
59
83
  end
60
84
 
61
- def process_params(sql, params)
62
- sql = sql.dup
63
- param_array = nil
85
+ private
64
86
 
65
- if Hash === params
66
- param_array = []
67
- params.each do |k, v|
68
- sql.gsub!(":#{k.to_s}", "$#{param_array.length + 1}")
69
- param_array << v
70
- end
71
- elsif Array === params
72
- i = 0
73
- sql.gsub!("?") do
74
- i += 1
75
- case params[i-1]
76
- when Integer then "$#{i}::bigint"
77
- when Float then "$#{i}::float8"
78
- when String then "$#{i}::text"
79
- else "$#{i}::unknown"
80
- end
81
- end
82
- param_array = params
87
+ def run(sql, params)
88
+ if params && params.length > 0
89
+ sql = @param_encoder.encode(sql, *params)
83
90
  end
84
-
85
- [sql, param_array]
86
-
91
+ raw_connection.async_exec(sql)
87
92
  end
88
93
 
89
94
  end
@@ -40,6 +40,7 @@ module MiniSql
40
40
 
41
41
  Class.new do
42
42
  attr_accessor(*fields)
43
+ alias :read_attribute_for_serialization :send
43
44
 
44
45
  instance_eval <<~RUBY
45
46
  def materialize(pg_result, index)
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MiniSql
4
+ class InlineParamEncoder
5
+ attr_reader :conn
6
+
7
+ def initialize(conn)
8
+ @conn = conn
9
+ end
10
+
11
+ def encode(sql, *params)
12
+ return sql unless params && params.length > 0
13
+
14
+ if Hash === (hash = params[0])
15
+ raise ArgumentError, "Only one hash param is allowed, multiple were sent" if params.length > 1
16
+ encode_hash(sql, hash)
17
+ else
18
+ encode_array(sql, params)
19
+ end
20
+ end
21
+
22
+ def encode_hash(sql, hash)
23
+ sql = sql.dup
24
+
25
+ hash.each do |k, v|
26
+ sql.gsub!(":#{k}") do
27
+ # ignore ::int and stuff like that
28
+ # $` is previous to match
29
+ if $` && $`[-1] != ":"
30
+ quote_val(v)
31
+ else
32
+ ":#{k}"
33
+ end
34
+ end
35
+ end
36
+ sql
37
+ end
38
+
39
+ def encode_array(sql, array)
40
+ i = -1
41
+ sql.gsub("?") do |p|
42
+ i += 1
43
+ quote_val(array[i])
44
+ end
45
+ end
46
+
47
+ def quoted_date(value)
48
+ value.utc.iso8601
49
+ end
50
+
51
+ def quote_val(value)
52
+ case value
53
+ when Array
54
+ value.map do |v|
55
+ quote_val(v)
56
+ end.join(', ')
57
+ when String
58
+ "'#{conn.escape_string(value.to_s)}'"
59
+ when true then "true"
60
+ when false then "false"
61
+ when nil then "NULL"
62
+ when BigDecimal then value.to_s("F")
63
+ when Numeric then value.to_s
64
+ when Date, Time then "'#{quoted_date(value)}'"
65
+ when Symbol then "'#{escape_string(value.to_s)}'"
66
+ else raise TypeError, "can't quote #{value.class.name}"
67
+ end
68
+ end
69
+ end
70
+ end
@@ -1,3 +1,3 @@
1
1
  module MiniSql
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
data/mini_sql.gemspec CHANGED
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.add_development_dependency "pg", "~> 1.0.0"
29
29
  spec.add_development_dependency "guard", "~> 2.14"
30
30
  spec.add_development_dependency "guard-minitest", "~> 2.4"
31
+ spec.add_development_dependency "activesupport", "~> 5.2"
31
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mini_sql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-16 00:00:00.000000000 Z
11
+ date: 2018-06-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '2.4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '5.2'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '5.2'
97
111
  description: A fast, safe, simple direct SQL executor for PG
98
112
  email:
99
113
  - sam.saffron@gmail.com
@@ -118,6 +132,7 @@ files:
118
132
  - lib/mini_sql/coders.rb
119
133
  - lib/mini_sql/connection.rb
120
134
  - lib/mini_sql/deserializer_cache.rb
135
+ - lib/mini_sql/inline_param_encoder.rb
121
136
  - lib/mini_sql/version.rb
122
137
  - mini_sql.gemspec
123
138
  homepage: https://discourse.org