mini_sql 0.2.4 → 0.2.5
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/.rubocop-https---raw-githubusercontent-com-discourse-discourse-master--rubocop-yml +355 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +3 -1
- data/CHANGELOG +4 -0
- data/Gemfile +3 -1
- data/Guardfile +2 -0
- data/README.md +60 -1
- data/Rakefile +3 -1
- data/bench/timestamp_perf.rb +22 -21
- data/bench/topic_mysql_perf.rb +1 -7
- data/bench/topic_perf.rb +174 -10
- data/bin/console +1 -0
- data/lib/mini_sql/builder.rb +0 -1
- data/lib/mini_sql/connection.rb +1 -1
- data/lib/mini_sql/deserializer_cache.rb +2 -0
- data/lib/mini_sql/inline_param_encoder.rb +9 -9
- data/lib/mini_sql/mysql/connection.rb +12 -3
- data/lib/mini_sql/mysql/deserializer_cache.rb +7 -3
- data/lib/mini_sql/postgres/coders.rb +2 -0
- data/lib/mini_sql/postgres/connection.rb +17 -0
- data/lib/mini_sql/postgres/deserializer_cache.rb +7 -4
- data/lib/mini_sql/postgres_jdbc/connection.rb +5 -0
- data/lib/mini_sql/postgres_jdbc/deserializer_cache.rb +45 -41
- data/lib/mini_sql/sqlite/connection.rb +11 -1
- data/lib/mini_sql/sqlite/deserializer_cache.rb +7 -3
- data/lib/mini_sql/version.rb +1 -1
- data/mini_sql.gemspec +5 -1
- metadata +32 -2
@@ -50,19 +50,19 @@ module MiniSql
|
|
50
50
|
|
51
51
|
def quote_val(value)
|
52
52
|
case value
|
53
|
+
when String then "'#{conn.escape_string(value.to_s)}'"
|
54
|
+
when Numeric then value.to_s
|
55
|
+
when BigDecimal then value.to_s("F")
|
56
|
+
when Date, Time then "'#{quoted_date(value)}'"
|
57
|
+
when Symbol then "'#{conn.escape_string(value.to_s)}'"
|
58
|
+
when true then "true"
|
59
|
+
when false then "false"
|
60
|
+
when nil then "NULL"
|
61
|
+
when [] then "NULL"
|
53
62
|
when Array
|
54
63
|
value.map do |v|
|
55
64
|
quote_val(v)
|
56
65
|
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 "'#{conn.escape_string(value.to_s)}'"
|
66
66
|
else raise TypeError, "can't quote #{value.class.name}"
|
67
67
|
end
|
68
68
|
end
|
@@ -20,6 +20,10 @@ module MiniSql
|
|
20
20
|
result.to_a
|
21
21
|
end
|
22
22
|
|
23
|
+
def query_array(sql, *params)
|
24
|
+
run(sql, :array, params).to_a
|
25
|
+
end
|
26
|
+
|
23
27
|
def exec(sql, *params)
|
24
28
|
run(sql, :array, params)
|
25
29
|
raw_connection.affected_rows
|
@@ -30,6 +34,11 @@ module MiniSql
|
|
30
34
|
@deserializer_cache.materialize(result)
|
31
35
|
end
|
32
36
|
|
37
|
+
def query_decorator(decorator, sql, *params)
|
38
|
+
result = run(sql, :array, params)
|
39
|
+
@deserializer_cache.materialize(result, decorator)
|
40
|
+
end
|
41
|
+
|
33
42
|
def escape_string(str)
|
34
43
|
raw_connection.escape(str)
|
35
44
|
end
|
@@ -45,9 +54,9 @@ module MiniSql
|
|
45
54
|
sql = param_encoder.encode(sql, *params)
|
46
55
|
end
|
47
56
|
raw_connection.query(
|
48
|
-
sql,
|
49
|
-
as: as,
|
50
|
-
database_timezone: :utc,
|
57
|
+
sql,
|
58
|
+
as: as,
|
59
|
+
database_timezone: :utc,
|
51
60
|
application_timezone: :utc,
|
52
61
|
cast_booleans: true,
|
53
62
|
cast: true,
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MiniSql
|
2
4
|
module Mysql
|
3
5
|
class DeserializerCache
|
@@ -9,7 +11,7 @@ module MiniSql
|
|
9
11
|
@max_size = max_size || DEFAULT_MAX_SIZE
|
10
12
|
end
|
11
13
|
|
12
|
-
def materialize(result)
|
14
|
+
def materialize(result, decorator_module = nil)
|
13
15
|
key = result.fields
|
14
16
|
|
15
17
|
# trivial fast LRU implementation
|
@@ -21,6 +23,8 @@ module MiniSql
|
|
21
23
|
@cache.shift if @cache.length > @max_size
|
22
24
|
end
|
23
25
|
|
26
|
+
materializer.include(decorator_module) if decorator_module
|
27
|
+
|
24
28
|
result.map do |data|
|
25
29
|
materializer.materialize(data)
|
26
30
|
end
|
@@ -40,7 +44,7 @@ module MiniSql
|
|
40
44
|
def to_h
|
41
45
|
r = {}
|
42
46
|
instance_variables.each do |f|
|
43
|
-
r[f.to_s.sub('@','').to_sym] = instance_variable_get(f)
|
47
|
+
r[f.to_s.sub('@', '').to_sym] = instance_variable_get(f)
|
44
48
|
end
|
45
49
|
r
|
46
50
|
end
|
@@ -48,7 +52,7 @@ module MiniSql
|
|
48
52
|
instance_eval <<~RUBY
|
49
53
|
def materialize(data)
|
50
54
|
r = self.new
|
51
|
-
#{col
|
55
|
+
#{col = -1; fields.map { |f| "r.#{f} = data[#{col += 1}]" }.join("; ")}
|
52
56
|
r
|
53
57
|
end
|
54
58
|
RUBY
|
@@ -39,6 +39,7 @@ module MiniSql
|
|
39
39
|
@raw_connection = raw_connection
|
40
40
|
@deserializer_cache = (args && args[:deserializer_cache]) || self.class.default_deserializer_cache
|
41
41
|
@param_encoder = (args && args[:param_encoder]) || InlineParamEncoder.new(self)
|
42
|
+
@type_map = args && args[:type_map]
|
42
43
|
end
|
43
44
|
|
44
45
|
def type_map
|
@@ -78,6 +79,14 @@ module MiniSql
|
|
78
79
|
result.clear if result
|
79
80
|
end
|
80
81
|
|
82
|
+
def query_array(sql, *params)
|
83
|
+
result = run(sql, params)
|
84
|
+
result.type_map = type_map
|
85
|
+
result.values
|
86
|
+
ensure
|
87
|
+
result.clear if result
|
88
|
+
end
|
89
|
+
|
81
90
|
def query(sql, *params)
|
82
91
|
result = run(sql, params)
|
83
92
|
result.type_map = type_map
|
@@ -86,6 +95,14 @@ module MiniSql
|
|
86
95
|
result.clear if result
|
87
96
|
end
|
88
97
|
|
98
|
+
def query_decorator(decorator, sql, *params)
|
99
|
+
result = run(sql, params)
|
100
|
+
result.type_map = type_map
|
101
|
+
@deserializer_cache.materialize(result, decorator)
|
102
|
+
ensure
|
103
|
+
result.clear if result
|
104
|
+
end
|
105
|
+
|
89
106
|
def exec(sql, *params)
|
90
107
|
result = run(sql, params)
|
91
108
|
result.cmd_tuples
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MiniSql
|
2
4
|
module Postgres
|
3
5
|
class DeserializerCache
|
@@ -9,8 +11,7 @@ module MiniSql
|
|
9
11
|
@max_size = max_size || DEFAULT_MAX_SIZE
|
10
12
|
end
|
11
13
|
|
12
|
-
def materialize(result)
|
13
|
-
|
14
|
+
def materialize(result, decorator_module = nil)
|
14
15
|
return [] if result.ntuples == 0
|
15
16
|
|
16
17
|
key = result.fields
|
@@ -24,6 +25,8 @@ module MiniSql
|
|
24
25
|
@cache.shift if @cache.length > @max_size
|
25
26
|
end
|
26
27
|
|
28
|
+
materializer.include(decorator_module) if decorator_module
|
29
|
+
|
27
30
|
i = 0
|
28
31
|
r = []
|
29
32
|
# quicker loop
|
@@ -48,7 +51,7 @@ module MiniSql
|
|
48
51
|
def to_h
|
49
52
|
r = {}
|
50
53
|
instance_variables.each do |f|
|
51
|
-
r[f.to_s.sub('@','').to_sym] = instance_variable_get(f)
|
54
|
+
r[f.to_s.sub('@', '').to_sym] = instance_variable_get(f)
|
52
55
|
end
|
53
56
|
r
|
54
57
|
end
|
@@ -56,7 +59,7 @@ module MiniSql
|
|
56
59
|
instance_eval <<~RUBY
|
57
60
|
def materialize(pg_result, index)
|
58
61
|
r = self.new
|
59
|
-
#{col
|
62
|
+
#{col = -1; fields.map { |f| "r.#{f} = pg_result.getvalue(index, #{col += 1})" }.join("; ")}
|
60
63
|
r
|
61
64
|
end
|
62
65
|
RUBY
|
@@ -60,6 +60,11 @@ module MiniSql
|
|
60
60
|
@deserializer_cache.materialize(result)
|
61
61
|
end
|
62
62
|
|
63
|
+
def query_decorator(decorator, sql, *params)
|
64
|
+
result = run(sql, params)
|
65
|
+
@deserializer_cache.materialize(result, decorator)
|
66
|
+
end
|
67
|
+
|
63
68
|
def exec(sql, *params)
|
64
69
|
result = run(sql, params)
|
65
70
|
if result.kind_of? Integer
|
@@ -1,67 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MiniSql
|
2
4
|
module Postgres
|
3
5
|
class DeserializerCache
|
4
6
|
|
5
|
-
|
7
|
+
DEFAULT_MAX_SIZE = 500
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
def initialize(max_size = nil)
|
10
|
+
@cache = {}
|
11
|
+
@max_size = max_size || DEFAULT_MAX_SIZE
|
12
|
+
end
|
11
13
|
|
12
|
-
|
14
|
+
def materialize(result, decorator_module = nil)
|
13
15
|
|
14
|
-
|
16
|
+
return [] if result.ntuples == 0
|
15
17
|
|
16
|
-
|
18
|
+
key = result.fields
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
# trivial fast LRU implementation
|
21
|
+
materializer = @cache.delete(key)
|
22
|
+
if materializer
|
23
|
+
@cache[key] = materializer
|
24
|
+
else
|
25
|
+
materializer = @cache[key] = new_row_matrializer(result)
|
26
|
+
@cache.shift if @cache.length > @max_size
|
27
|
+
end
|
28
|
+
|
29
|
+
materializer.include(decorator_module) if decorator_module
|
26
30
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
i = 0
|
32
|
+
r = []
|
33
|
+
# quicker loop
|
34
|
+
while i < result.ntuples
|
35
|
+
r << materializer.materialize(result, i)
|
36
|
+
i += 1
|
37
|
+
end
|
38
|
+
r
|
33
39
|
end
|
34
|
-
r
|
35
|
-
end
|
36
40
|
|
37
|
-
|
41
|
+
private
|
38
42
|
|
39
|
-
|
40
|
-
|
43
|
+
def new_row_matrializer(result)
|
44
|
+
fields = result.fields
|
41
45
|
|
42
|
-
|
43
|
-
|
46
|
+
Class.new do
|
47
|
+
attr_accessor(*fields)
|
44
48
|
|
45
|
-
|
46
|
-
|
49
|
+
# AM serializer support
|
50
|
+
alias :read_attribute_for_serialization :send
|
47
51
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
+
def to_h
|
53
|
+
r = {}
|
54
|
+
instance_variables.each do |f|
|
55
|
+
r[f.to_s.sub('@', '').to_sym] = instance_variable_get(f)
|
56
|
+
end
|
57
|
+
r
|
52
58
|
end
|
53
|
-
r
|
54
|
-
end
|
55
59
|
|
56
|
-
|
60
|
+
instance_eval <<~RUBY
|
57
61
|
def materialize(pg_result, index)
|
58
62
|
r = self.new
|
59
|
-
#{col
|
63
|
+
#{col = -1; fields.map { |f| "r.#{f} = pg_result.getvalue(index, #{col += 1})" }.join("; ")}
|
60
64
|
r
|
61
65
|
end
|
62
|
-
|
66
|
+
RUBY
|
67
|
+
end
|
63
68
|
end
|
64
69
|
end
|
65
70
|
end
|
66
71
|
end
|
67
|
-
end
|
@@ -26,6 +26,10 @@ module MiniSql
|
|
26
26
|
r
|
27
27
|
end
|
28
28
|
|
29
|
+
def query_array(sql, *params)
|
30
|
+
run(sql, *params)
|
31
|
+
end
|
32
|
+
|
29
33
|
def exec(sql, *params)
|
30
34
|
|
31
35
|
start = raw_connection.total_changes
|
@@ -46,8 +50,14 @@ module MiniSql
|
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
53
|
+
def query_decorator(decorator, sql, *params)
|
54
|
+
run(sql, *params) do |set|
|
55
|
+
deserializer_cache.materialize(set, decorator)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
49
59
|
def escape_string(str)
|
50
|
-
str.gsub("'","''")
|
60
|
+
str.gsub("'", "''")
|
51
61
|
end
|
52
62
|
|
53
63
|
private
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module MiniSql
|
2
4
|
module Sqlite
|
3
5
|
class DeserializerCache
|
@@ -9,7 +11,7 @@ module MiniSql
|
|
9
11
|
@max_size = max_size || DEFAULT_MAX_SIZE
|
10
12
|
end
|
11
13
|
|
12
|
-
def materialize(result)
|
14
|
+
def materialize(result, decorator_module = nil)
|
13
15
|
|
14
16
|
key = result.columns
|
15
17
|
|
@@ -22,6 +24,8 @@ module MiniSql
|
|
22
24
|
@cache.shift if @cache.length > @max_size
|
23
25
|
end
|
24
26
|
|
27
|
+
materializer.include(decorator_module) if decorator_module
|
28
|
+
|
25
29
|
r = []
|
26
30
|
# quicker loop
|
27
31
|
while !result.eof?
|
@@ -47,7 +51,7 @@ module MiniSql
|
|
47
51
|
def to_h
|
48
52
|
r = {}
|
49
53
|
instance_variables.each do |f|
|
50
|
-
r[f.to_s.sub('@','').to_sym] = instance_variable_get(f)
|
54
|
+
r[f.to_s.sub('@', '').to_sym] = instance_variable_get(f)
|
51
55
|
end
|
52
56
|
r
|
53
57
|
end
|
@@ -55,7 +59,7 @@ module MiniSql
|
|
55
59
|
instance_eval <<~RUBY
|
56
60
|
def materialize(data)
|
57
61
|
r = self.new
|
58
|
-
#{col
|
62
|
+
#{col = -1; fields.map { |f| "r.#{f} = data[#{col += 1}]" }.join("; ")}
|
59
63
|
r
|
60
64
|
end
|
61
65
|
RUBY
|
data/lib/mini_sql/version.rb
CHANGED
data/mini_sql.gemspec
CHANGED
@@ -25,9 +25,11 @@ Gem::Specification.new do |spec|
|
|
25
25
|
|
26
26
|
# Specify which files should be added to the gem when it is released.
|
27
27
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
28
|
-
|
28
|
+
# rubocop:disable DiscoruseCops/NoChdir
|
29
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
29
30
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
30
31
|
end
|
32
|
+
# rubocop:enable DiscoruseCops/NoChdir
|
31
33
|
spec.require_paths = ["lib"]
|
32
34
|
|
33
35
|
spec.add_development_dependency "bundler", "> 1.16"
|
@@ -36,6 +38,8 @@ Gem::Specification.new do |spec|
|
|
36
38
|
spec.add_development_dependency "guard", "~> 2.14"
|
37
39
|
spec.add_development_dependency "guard-minitest", "~> 2.4"
|
38
40
|
spec.add_development_dependency "activesupport", "~> 5.2"
|
41
|
+
spec.add_development_dependency 'rubocop', '~> 0.79.0'
|
42
|
+
spec.add_development_dependency 'rubocop-discourse', '~> 1.0.2'
|
39
43
|
|
40
44
|
if RUBY_ENGINE == 'jruby'
|
41
45
|
spec.add_development_dependency "activerecord-jdbcpostgresql-adapter", "~> 52.2"
|
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.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,6 +94,34 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '5.2'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.79.0
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.79.0
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop-discourse
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 1.0.2
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 1.0.2
|
97
125
|
- !ruby/object:Gem::Dependency
|
98
126
|
name: pg
|
99
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,6 +172,8 @@ extensions: []
|
|
144
172
|
extra_rdoc_files: []
|
145
173
|
files:
|
146
174
|
- ".gitignore"
|
175
|
+
- ".rubocop-https---raw-githubusercontent-com-discourse-discourse-master--rubocop-yml"
|
176
|
+
- ".rubocop.yml"
|
147
177
|
- ".travis.yml"
|
148
178
|
- CHANGELOG
|
149
179
|
- CODE_OF_CONDUCT.md
|