mini_sql 1.5.0 → 1.6.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/.github/workflows/ci.yml +1 -1
- data/CHANGELOG +5 -0
- data/README.md +34 -7
- data/lib/mini_sql/inline_param_encoder.rb +4 -3
- data/lib/mini_sql/postgres/connection.rb +16 -1
- data/lib/mini_sql/version.rb +1 -1
- data/mini_sql.gemspec +3 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1160fe3ddc5b4d248f62efcb205d6bc83982912355a932f23ab9620fbbd0c8fe
|
4
|
+
data.tar.gz: f60fe47f807aa8273ce5d018611f111b0e99b21552ac258ac0b8594035fb0725
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca800672b020af15bb69ca8b3cad63d435835c67f27d052ee01039eb31b7f0f8c4719ca9330f3ada3ff29b4442f2f423861686876e004d72bad7116be9b08235
|
7
|
+
data.tar.gz: 9394f995fe546af9c908597928699f7a1214dc3b5ae18ddb4a224b2c1d335da4a17be63c6e4b25adc0b8984af43259eec1ebaec0ceeceef31678115dbe790cae
|
data/.github/workflows/ci.yml
CHANGED
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -56,6 +56,15 @@ p conn.query_array("select 1 as a, '2' as b union select 3, 'e'").to_h
|
|
56
56
|
# {1 => '2', 3 => 'e'}
|
57
57
|
```
|
58
58
|
|
59
|
+
## Auto Encode Arrays (only PostgreSQL)
|
60
|
+
```ruby
|
61
|
+
pg_conn = PG.connect(db_name: 'my_db')
|
62
|
+
conn = MiniSql::Connection.get(pg_conn, auto_encode_arrays: true)
|
63
|
+
|
64
|
+
# select * from table where id = ANY('{1,2,3}')
|
65
|
+
conn.query("select * from table where id = ANY(?)", [1, 2, 3])
|
66
|
+
```
|
67
|
+
|
59
68
|
## The query builder
|
60
69
|
|
61
70
|
You can use the simple query builder interface to compose queries.
|
@@ -241,15 +250,33 @@ Streaming support is only implemented in the postgres backend at the moment, PRs
|
|
241
250
|
See [benchmark mini_sql](https://github.com/discourse/mini_sql/tree/master/bench/prepared_perf.rb)
|
242
251
|
[benchmark mini_sql vs rails](https://github.com/discourse/mini_sql/tree/master/bench/bilder_perf.rb).
|
243
252
|
|
244
|
-
By default prepared cache size is 500 queries. Use prepared queries only for frequent queries.
|
245
|
-
|
246
253
|
```ruby
|
247
254
|
conn.prepared.query("select * from table where id = ?", id: 10)
|
255
|
+
```
|
256
|
+
|
257
|
+
### Prepared Statement Bloat in PostgreSQL
|
258
|
+
By default prepared cache size is __500__ queries per connection. Use prepared queries only for frequent queries.
|
259
|
+
|
260
|
+
The following code will create 100 prepared statements in PostgreSQL for a single database connection:
|
248
261
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
262
|
+
```ruby
|
263
|
+
100.times do |i|
|
264
|
+
ids = (1..i).to_a
|
265
|
+
conn.prepared.query("SELECT * FROM table WHERE id IN (?)", ids)
|
266
|
+
end
|
267
|
+
```
|
268
|
+
|
269
|
+
This can lead to high memory usage and performance issues due to the overhead of maintaining numerous prepared statements.
|
270
|
+
|
271
|
+
To improve performance, you can enable `auto_encode_arrays: true`. With this option, only one prepared statement is created, regardless of the size of ids:
|
272
|
+
|
273
|
+
```ruby
|
274
|
+
pg_conn = PG.connect(db_name: 'my_db')
|
275
|
+
conn = MiniSql::Connection.get(pg_conn, auto_encode_arrays: true)
|
276
|
+
100.times do |i|
|
277
|
+
ids = (1..i).to_a
|
278
|
+
conn.prepared.query("select * from table where id = ANY (?)", ids)
|
279
|
+
end
|
253
280
|
```
|
254
281
|
|
255
282
|
## Active Record Postgres
|
@@ -276,7 +303,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
276
303
|
export MINI_SQL_MYSQL_HOST=127.0.0.1
|
277
304
|
export MINI_SQL_MYSQL_PORT=33306
|
278
305
|
|
279
|
-
docker run --name mini-sql-postgres --rm -it -p 55432:5432 -e POSTGRES_DB=test_mini_sql -e POSTGRES_HOST_AUTH_METHOD=trust -d postgres
|
306
|
+
docker run --name mini-sql-postgres --rm -it -p 55432:5432 -e POSTGRES_DB=test_mini_sql -e POSTGRES_HOST_AUTH_METHOD=trust -d postgres # or ankane/pgvector for testing vector type decoder
|
280
307
|
export MINI_SQL_PG_USER=postgres
|
281
308
|
export MINI_SQL_PG_HOST=127.0.0.1
|
282
309
|
export MINI_SQL_PG_PORT=55432
|
@@ -2,10 +2,11 @@
|
|
2
2
|
|
3
3
|
module MiniSql
|
4
4
|
class InlineParamEncoder
|
5
|
-
attr_reader :conn
|
5
|
+
attr_reader :conn, :array_encoder
|
6
6
|
|
7
|
-
def initialize(conn)
|
7
|
+
def initialize(conn, array_encoder = nil)
|
8
8
|
@conn = conn
|
9
|
+
@array_encoder = array_encoder
|
9
10
|
end
|
10
11
|
|
11
12
|
def encode(sql, *params)
|
@@ -62,7 +63,7 @@ module MiniSql
|
|
62
63
|
when false then "false"
|
63
64
|
when nil then "NULL"
|
64
65
|
when [] then "NULL"
|
65
|
-
when Array then value.map { |v| quote_val(v) }.join(', ')
|
66
|
+
when Array then array_encoder ? "'#{array_encoder.encode(value)}'" : value.map { |v| quote_val(v) }.join(', ')
|
66
67
|
else raise TypeError, "can't quote #{value.class.name}"
|
67
68
|
end
|
68
69
|
end
|
@@ -26,6 +26,20 @@ module MiniSql
|
|
26
26
|
else
|
27
27
|
map.add_coder(MiniSql::Postgres::Coders::TimestampUtc.new(name: "timestamp", oid: 1114, format: 0))
|
28
28
|
end
|
29
|
+
|
30
|
+
if defined? Pgvector::PG
|
31
|
+
vector_oid =
|
32
|
+
PG::BasicTypeRegistry::CoderMapsBundle
|
33
|
+
.new(conn)
|
34
|
+
.typenames_by_oid
|
35
|
+
.find { |k, v| v == "vector" }
|
36
|
+
&.first
|
37
|
+
|
38
|
+
if !vector_oid.nil?
|
39
|
+
map.add_coder(Pgvector::PG::TextDecoder::Vector.new(name: "vector", oid: vector_oid, format: 0))
|
40
|
+
map.add_coder(Pgvector::PG::BinaryDecoder::Vector.new(name: "vector", oid: vector_oid, format: 1))
|
41
|
+
end
|
42
|
+
end
|
29
43
|
map
|
30
44
|
end
|
31
45
|
end
|
@@ -38,7 +52,8 @@ module MiniSql
|
|
38
52
|
def initialize(raw_connection, args = nil)
|
39
53
|
@raw_connection = raw_connection
|
40
54
|
@deserializer_cache = (args && args[:deserializer_cache]) || self.class.default_deserializer_cache
|
41
|
-
|
55
|
+
array_encoder = PG::TextEncoder::Array.new if args && args[:auto_encode_arrays]
|
56
|
+
@param_encoder = (args && args[:param_encoder]) || InlineParamEncoder.new(self, array_encoder)
|
42
57
|
@type_map = args && args[:type_map]
|
43
58
|
end
|
44
59
|
|
data/lib/mini_sql/version.rb
CHANGED
data/mini_sql.gemspec
CHANGED
@@ -49,5 +49,8 @@ Gem::Specification.new do |spec|
|
|
49
49
|
spec.add_development_dependency "mysql2"
|
50
50
|
spec.add_development_dependency "sqlite3", "~> 1.4.4"
|
51
51
|
spec.add_development_dependency "activerecord", "~> 7.0.0"
|
52
|
+
if RUBY_VERSION >= "3.0"
|
53
|
+
spec.add_development_dependency "pgvector", "~> 0.2.1"
|
54
|
+
end
|
52
55
|
end
|
53
56
|
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: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|