mini_sql 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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