mini_sql 0.2.1 → 0.2.2

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: 8b9e4f7f96a77f3eaead87f509583b9bf604d49eec6e3caaf8a0234646eb208a
4
- data.tar.gz: 94cac1f8ef8a82860686b1001761ef1b06a8be5228299427dc41d6be92d5a1c5
3
+ metadata.gz: 45fd7b2a7b68f3186fa88a3387188312f926128f3dcb24f9fee3e8d9b695683d
4
+ data.tar.gz: c9ed648c9ef6976ef774863b509c63901b1c94629561b9fce63425155248b046
5
5
  SHA512:
6
- metadata.gz: 04a54bb044404c6ed17bd425b0f7779afa130002850592ad1e91a249504c0b4b46e17453a59dab0e5e816a131669079742ca1baaae013259917bfec6dedab83f
7
- data.tar.gz: fd4ceaf5f7e46efb8e5b067a54304c5a5eaa5d4216ff4c405bb64688b57b7844d7106dc3568e059b912994b193e197b83f9e81bfb1d5e91611b8c3ce5b65033f
6
+ metadata.gz: 37d82773bbae9390c7c68852734b713a863df638510326a1022a8fe675b4aa3eb597b64ccb1adaef5067bbb808f6995e4f90c691f7b4276512708967d154f3cf
7
+ data.tar.gz: 81523394fe465e59ab60f8d895f1cff17c4e4006b88792dd1bc5b536b17d00b8ab2c2180f5a1e7150e53dcd4d3bac5759397f7d76870d7ce92965b3f277493b6
data/.gitignore CHANGED
@@ -7,3 +7,4 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  Gemfile.lock
10
+ /.idea/
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ 2019-11-04 - 0.2.2
2
+
3
+ - Added adapters for JRuby postgres support thanks to @enebo
4
+
1
5
  2019-02-25 - 0.2.1
2
6
 
3
7
  - Handle `BigDecimal.new` deprecation by using `BigDecimal()` instead
data/Rakefile CHANGED
@@ -1,10 +1,16 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
3
 
4
+ if RUBY_ENGINE == 'jruby' # Excluding sqlite3 tests
5
+ test_glob = "test/**/{inline_param_encoder_test.rb,postgres/*_test.rb}"
6
+ else
7
+ test_glob = "test/**/*_test.rb"
8
+ end
9
+
4
10
  Rake::TestTask.new(:test) do |t|
5
11
  t.libs << "test"
6
12
  t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
13
+ t.test_files = FileList[test_glob]
8
14
  end
9
15
 
10
16
  task :default => :test
@@ -10,14 +10,21 @@ require_relative "mini_sql/builder"
10
10
  require_relative "mini_sql/inline_param_encoder"
11
11
 
12
12
  module MiniSql
13
- module Postgres
14
- autoload :Coders, "mini_sql/postgres/coders"
15
- autoload :Connection, "mini_sql/postgres/connection"
16
- autoload :DeserializerCache, "mini_sql/postgres/deserializer_cache"
17
- end
13
+ if RUBY_ENGINE == 'jruby'
14
+ module Postgres
15
+ autoload :Connection, "mini_sql/postgres_jdbc/connection"
16
+ autoload :DeserializerCache, "mini_sql/postgres_jdbc/deserializer_cache"
17
+ end
18
+ else
19
+ module Postgres
20
+ autoload :Coders, "mini_sql/postgres/coders"
21
+ autoload :Connection, "mini_sql/postgres/connection"
22
+ autoload :DeserializerCache, "mini_sql/postgres/deserializer_cache"
23
+ end
18
24
 
19
- module Sqlite
20
- autoload :Connection, "mini_sql/sqlite/connection"
21
- autoload :DeserializerCache, "mini_sql/sqlite/deserializer_cache"
25
+ module Sqlite
26
+ autoload :Connection, "mini_sql/sqlite/connection"
27
+ autoload :DeserializerCache, "mini_sql/sqlite/deserializer_cache"
28
+ end
22
29
  end
23
30
  end
@@ -4,7 +4,9 @@ module MiniSql
4
4
  class Connection
5
5
 
6
6
  def self.get(raw_connection, options = {})
7
- if (defined? ::PG::Connection) && (PG::Connection === raw_connection)
7
+ if (defined? ::PG::Connection) && (PG::Connection === raw_connection)
8
+ Postgres::Connection.new(raw_connection, options)
9
+ elsif (defined? ::ArJdbc)
8
10
  Postgres::Connection.new(raw_connection, options)
9
11
  elsif (defined? ::SQLite3::Database) && (SQLite3::Database === raw_connection)
10
12
  Sqlite::Connection.new(raw_connection, options)
@@ -0,0 +1,97 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MiniSql
4
+ module Postgres
5
+ class Connection < MiniSql::Connection
6
+ class NumericCoder
7
+ def decode(string)
8
+ BigDecimal(string)
9
+ end
10
+ end
11
+
12
+ class IPAddrCoder
13
+ def decode(string)
14
+ IPAddr.new(string)
15
+ end
16
+ end
17
+
18
+ attr_reader :raw_connection, :type_map, :param_encoder
19
+
20
+ def self.default_deserializer_cache
21
+ @deserializer_cache ||= DeserializerCache.new
22
+ end
23
+
24
+ def self.typemap
25
+ @type_map ||= {
26
+ "numeric" => NumericCoder.new,
27
+ "inet" => IPAddrCoder.new,
28
+ "cidr" => IPAddrCoder.new
29
+ }
30
+ end
31
+
32
+ # Initialize a new MiniSql::Postgres::Connection object
33
+ #
34
+ # @param raw_connection [PG::Connection] an active connection to PG
35
+ # @param deserializer_cache [MiniSql::DeserializerCache] a cache of field names to deserializer, can be nil
36
+ # @param type_map [PG::TypeMap] a type mapper for all results returned, can be nil
37
+ def initialize(raw_connection, args = nil)
38
+ @raw_connection = raw_connection
39
+ @deserializer_cache = (args && args[:deserializer_cache]) || self.class.default_deserializer_cache
40
+ @param_encoder = (args && args[:param_encoder]) || InlineParamEncoder.new(self)
41
+ end
42
+
43
+ # Returns a flat array containing all results.
44
+ # Note, if selecting multiple columns array will be flattened
45
+ #
46
+ # @param sql [String] the query to run
47
+ # @param params [Array or Hash], params to apply to query
48
+ # @return [Object] a flat array containing all results
49
+ def query_single(sql, *params)
50
+ result = run(sql, params)
51
+ if result.length == 1
52
+ result.values[0]
53
+ else
54
+ result.values.each_with_object([]) { |value, array| array.concat value }
55
+ end
56
+ end
57
+
58
+ def query(sql, *params)
59
+ result = run(sql, params)
60
+ @deserializer_cache.materialize(result)
61
+ end
62
+
63
+ def exec(sql, *params)
64
+ result = run(sql, params)
65
+ if result.kind_of? Integer
66
+ result
67
+ else
68
+ result.length
69
+ end
70
+ end
71
+
72
+ def query_hash(sql, *params)
73
+ run(sql, params).to_a
74
+ end
75
+
76
+ def build(sql)
77
+ Builder.new(self, sql)
78
+ end
79
+
80
+ def escape_string(str)
81
+ raw_connection.escape_string(str)
82
+ end
83
+
84
+ private
85
+
86
+ def run(sql, params)
87
+ sql = param_encoder.encode(sql, *params) if params && params.length > 0
88
+ conn = raw_connection
89
+ conn.typemap = self.class.typemap
90
+ conn.execute(sql)
91
+ ensure
92
+ # Force unsetting of typemap since we don't want mixed AR usage to continue to use these extra converters.
93
+ conn.typemap = nil
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,67 @@
1
+ module MiniSql
2
+ module Postgres
3
+ class DeserializerCache
4
+
5
+ DEFAULT_MAX_SIZE = 500
6
+
7
+ def initialize(max_size = nil)
8
+ @cache = {}
9
+ @max_size = max_size || DEFAULT_MAX_SIZE
10
+ end
11
+
12
+ def materialize(result)
13
+
14
+ return [] if result.ntuples == 0
15
+
16
+ key = result.fields
17
+
18
+ # trivial fast LRU implementation
19
+ materializer = @cache.delete(key)
20
+ if materializer
21
+ @cache[key] = materializer
22
+ else
23
+ materializer = @cache[key] = new_row_matrializer(result)
24
+ @cache.shift if @cache.length > @max_size
25
+ end
26
+
27
+ i = 0
28
+ r = []
29
+ # quicker loop
30
+ while i < result.ntuples
31
+ r << materializer.materialize(result, i)
32
+ i += 1
33
+ end
34
+ r
35
+ end
36
+
37
+ private
38
+
39
+ def new_row_matrializer(result)
40
+ fields = result.fields
41
+
42
+ Class.new do
43
+ attr_accessor(*fields)
44
+
45
+ # AM serializer support
46
+ alias :read_attribute_for_serialization :send
47
+
48
+ def to_h
49
+ r = {}
50
+ instance_variables.each do |f|
51
+ r[f.to_s.sub('@','').to_sym] = instance_variable_get(f)
52
+ end
53
+ r
54
+ end
55
+
56
+ instance_eval <<~RUBY
57
+ def materialize(pg_result, index)
58
+ r = self.new
59
+ #{col=-1; fields.map{|f| "r.#{f} = pg_result.getvalue(index, #{col+=1})"}.join("; ")}
60
+ r
61
+ end
62
+ RUBY
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -1,3 +1,3 @@
1
1
  module MiniSql
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -15,6 +15,8 @@ Gem::Specification.new do |spec|
15
15
  spec.homepage = "https://discourse.org"
16
16
  spec.license = "MIT"
17
17
 
18
+ spec.platform = 'java' if RUBY_ENGINE == 'jruby'
19
+
18
20
  # Specify which files should be added to the gem when it is released.
19
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
22
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
@@ -25,9 +27,14 @@ Gem::Specification.new do |spec|
25
27
  spec.add_development_dependency "bundler", "> 1.16"
26
28
  spec.add_development_dependency "rake", "~> 10.0"
27
29
  spec.add_development_dependency "minitest", "~> 5.0"
28
- spec.add_development_dependency "pg", "> 1"
29
30
  spec.add_development_dependency "guard", "~> 2.14"
30
31
  spec.add_development_dependency "guard-minitest", "~> 2.4"
31
32
  spec.add_development_dependency "activesupport", "~> 5.2"
32
- spec.add_development_dependency "sqlite3", "~> 1.3"
33
+
34
+ if RUBY_ENGINE == 'jruby'
35
+ spec.add_development_dependency "activerecord-jdbcpostgresql-adapter", "~> 52.2"
36
+ else
37
+ spec.add_development_dependency "pg", "> 1"
38
+ spec.add_development_dependency "sqlite3", "~> 1.3"
39
+ end
33
40
  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.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-25 00:00:00.000000000 Z
11
+ date: 2019-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '5.0'
55
- - !ruby/object:Gem::Dependency
56
- name: pg
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">"
60
- - !ruby/object:Gem::Version
61
- version: '1'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">"
67
- - !ruby/object:Gem::Version
68
- version: '1'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: guard
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +94,20 @@ dependencies:
108
94
  - - "~>"
109
95
  - !ruby/object:Gem::Version
110
96
  version: '5.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pg
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">"
102
+ - !ruby/object:Gem::Version
103
+ version: '1'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">"
109
+ - !ruby/object:Gem::Version
110
+ version: '1'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: sqlite3
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +150,8 @@ files:
150
150
  - lib/mini_sql/postgres/coders.rb
151
151
  - lib/mini_sql/postgres/connection.rb
152
152
  - lib/mini_sql/postgres/deserializer_cache.rb
153
+ - lib/mini_sql/postgres_jdbc/connection.rb
154
+ - lib/mini_sql/postgres_jdbc/deserializer_cache.rb
153
155
  - lib/mini_sql/sqlite/connection.rb
154
156
  - lib/mini_sql/sqlite/deserializer_cache.rb
155
157
  - lib/mini_sql/version.rb
@@ -173,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
175
  - !ruby/object:Gem::Version
174
176
  version: '0'
175
177
  requirements: []
176
- rubygems_version: 3.0.1
178
+ rubygems_version: 3.0.3
177
179
  signing_key:
178
180
  specification_version: 4
179
181
  summary: A fast, safe, simple direct SQL executor