extralite 3.0.1 → 3.1.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/CHANGELOG.md +9 -0
- data/README.md +10 -1
- data/Rakefile +2 -2
- data/TODO.md +2 -2
- data/examples/pubsub_store_polyphony.rb +1 -1
- data/ext/extralite/common.c +180 -79
- data/ext/extralite/database.c +81 -30
- data/ext/extralite/extralite.h +39 -17
- data/ext/extralite/iterator.c +1 -1
- data/ext/extralite/query.c +11 -11
- data/lib/extralite/version.rb +3 -2
- data/lib/extralite.rb +2 -1
- data/lib/sequel/adapters/extralite.rb +22 -22
- data/test/test_database.rb +239 -15
- data/test/test_query.rb +10 -9
- data/test/test_sequel.rb +3 -3
- data/test/test_trace.rb +3 -3
- metadata +1 -1
data/test/test_database.rb
CHANGED
|
@@ -109,21 +109,28 @@ class DatabaseTest < Minitest::Test
|
|
|
109
109
|
assert_equal false, @db.transaction_active?
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
def
|
|
113
|
-
|
|
112
|
+
def test_query_multi_stmt
|
|
113
|
+
assert_raises(Extralite::Error) {
|
|
114
|
+
@db.query("insert into t values ('a', 'b', 'c'); insert into t values ('d', 'e', 'f')")
|
|
115
|
+
}
|
|
116
|
+
assert_equal [1, 4], @db.query_splat('select x from t order by x')
|
|
114
117
|
|
|
115
|
-
assert_equal
|
|
118
|
+
assert_equal 2, @db.execute("insert into t values ('d', 'e', 'f'); insert into t values ('g', 'h', 'i');")
|
|
119
|
+
|
|
120
|
+
assert_equal [1, 4, 'd', 'g'], @db.query_splat('select x from t order by x')
|
|
116
121
|
end
|
|
117
122
|
|
|
118
|
-
def
|
|
123
|
+
def test_query_multi_stmt_bad_sql
|
|
119
124
|
error = nil
|
|
120
125
|
begin
|
|
121
|
-
@db.query("insert into t values
|
|
126
|
+
@db.query("insert into t values ('d', 'e', 'f'); insert into t values foo;")
|
|
122
127
|
rescue => error
|
|
123
128
|
end
|
|
124
129
|
|
|
125
130
|
assert_kind_of Extralite::SQLError, error
|
|
126
131
|
assert_equal 'near "foo": syntax error', error.message
|
|
132
|
+
|
|
133
|
+
assert_equal [1, 4], @db.query_splat('select x from t order by x')
|
|
127
134
|
end
|
|
128
135
|
|
|
129
136
|
def test_empty_sql
|
|
@@ -355,11 +362,16 @@ class DatabaseTest < Minitest::Test
|
|
|
355
362
|
assert_equal 1, @db.pragma(:schema_version)
|
|
356
363
|
assert_equal 0, @db.pragma(:recursive_triggers)
|
|
357
364
|
|
|
358
|
-
assert_equal
|
|
365
|
+
assert_equal @db, @db.pragma(schema_version: 33, recursive_triggers: 1)
|
|
359
366
|
assert_equal 33, @db.pragma(:schema_version)
|
|
360
367
|
assert_equal 1, @db.pragma(:recursive_triggers)
|
|
361
368
|
end
|
|
362
369
|
|
|
370
|
+
def test_pragma_set
|
|
371
|
+
@db.pragma('foreign_keys' => 1)
|
|
372
|
+
# assert_equal 1, @db.pragma('foreign_keys')
|
|
373
|
+
end
|
|
374
|
+
|
|
363
375
|
def test_execute
|
|
364
376
|
changes = @db.execute('update t set x = 42')
|
|
365
377
|
assert_equal 2, changes
|
|
@@ -377,6 +389,17 @@ class DatabaseTest < Minitest::Test
|
|
|
377
389
|
assert_equal [[1, 2, 3], [42, 5, 6]], @db.query_array('select * from t order by x')
|
|
378
390
|
end
|
|
379
391
|
|
|
392
|
+
def test_execute_multi_stmt_with_params
|
|
393
|
+
assert_raises(Extralite::Error) {
|
|
394
|
+
@db.execute <<~SQL, 42, 43, 44
|
|
395
|
+
insert into t values (?, ?, ?);
|
|
396
|
+
update t set x = 45 where x = 42;
|
|
397
|
+
SQL
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
assert_equal [[1, 2, 3], [4, 5, 6]], @db.query_array('select * from t order by x')
|
|
401
|
+
end
|
|
402
|
+
|
|
380
403
|
def test_batch_execute
|
|
381
404
|
@db.query('create table foo (a, b, c)')
|
|
382
405
|
assert_equal [], @db.query('select * from foo')
|
|
@@ -1092,18 +1115,22 @@ class DatabaseTest < Minitest::Test
|
|
|
1092
1115
|
assert_equal [0, 0], r
|
|
1093
1116
|
end
|
|
1094
1117
|
|
|
1118
|
+
def test_execute_simple
|
|
1119
|
+
@db.execute('select 1')
|
|
1120
|
+
end
|
|
1121
|
+
|
|
1095
1122
|
def test_execute_with_comments
|
|
1096
1123
|
result = @db.execute(<<~SQL)
|
|
1097
1124
|
-- this is a comment
|
|
1098
1125
|
SQL
|
|
1099
|
-
|
|
1126
|
+
assert_equal 0, result
|
|
1100
1127
|
|
|
1101
1128
|
result = @db.execute(<<~SQL)
|
|
1102
1129
|
DELETE FROM t;
|
|
1103
1130
|
INSERT INTO t (x, y, z) VALUES (1, 1, 1);
|
|
1104
1131
|
INSERT INTO t (x, y, z) VALUES (2, 2, 2);
|
|
1105
1132
|
SQL
|
|
1106
|
-
assert_equal
|
|
1133
|
+
assert_equal 4, result
|
|
1107
1134
|
assert_equal [1, 2], @db.query_splat('SELECT x FROM t ORDER BY x')
|
|
1108
1135
|
|
|
1109
1136
|
result = @db.execute(<<~SQL)
|
|
@@ -1112,7 +1139,7 @@ class DatabaseTest < Minitest::Test
|
|
|
1112
1139
|
INSERT INTO t (x, y, z) VALUES (3, 3, 3);
|
|
1113
1140
|
INSERT INTO t (x, y, z) VALUES (4, 4, 4);
|
|
1114
1141
|
SQL
|
|
1115
|
-
assert_equal
|
|
1142
|
+
assert_equal 4, result
|
|
1116
1143
|
assert_equal [3, 4], @db.query_splat('SELECT x FROM t ORDER BY x')
|
|
1117
1144
|
|
|
1118
1145
|
result = @db.execute(<<~SQL)
|
|
@@ -1121,17 +1148,16 @@ class DatabaseTest < Minitest::Test
|
|
|
1121
1148
|
-- this is a comment in the middle
|
|
1122
1149
|
INSERT INTO t (x, y, z) VALUES (6, 6, 6);
|
|
1123
1150
|
SQL
|
|
1124
|
-
assert_equal
|
|
1151
|
+
assert_equal 4, result
|
|
1125
1152
|
assert_equal [5, 6], @db.query_splat('SELECT x FROM t ORDER BY x')
|
|
1126
1153
|
|
|
1127
1154
|
result = @db.execute(<<~SQL)
|
|
1128
1155
|
DELETE FROM t;
|
|
1129
1156
|
INSERT INTO t (x, y, z) VALUES (7, 7, 7);
|
|
1130
|
-
INSERT INTO t (x, y, z) VALUES (8, 8, 8);
|
|
1131
1157
|
-- this is a comment at the end
|
|
1132
1158
|
SQL
|
|
1133
|
-
|
|
1134
|
-
assert_equal [7
|
|
1159
|
+
assert_equal 3, result
|
|
1160
|
+
assert_equal [7], @db.query_splat('SELECT x FROM t ORDER BY x')
|
|
1135
1161
|
end
|
|
1136
1162
|
|
|
1137
1163
|
def test_quote
|
|
@@ -1200,8 +1226,9 @@ class ScenarioTest < Minitest::Test
|
|
|
1200
1226
|
# "upgrade" to a write transaction
|
|
1201
1227
|
|
|
1202
1228
|
@db.query('commit')
|
|
1229
|
+
sleep 0.1
|
|
1203
1230
|
|
|
1204
|
-
|
|
1231
|
+
loop do
|
|
1205
1232
|
begin
|
|
1206
1233
|
@db.query('begin immediate')
|
|
1207
1234
|
break
|
|
@@ -1354,7 +1381,7 @@ class ConcurrencyTest < Minitest::Test
|
|
|
1354
1381
|
t2.join
|
|
1355
1382
|
t1.join
|
|
1356
1383
|
|
|
1357
|
-
assert_in_range
|
|
1384
|
+
assert_in_range 3.., delays.size
|
|
1358
1385
|
assert_equal 0, delays.select { |d| d > 0.15 }.size
|
|
1359
1386
|
ensure
|
|
1360
1387
|
t1&.kill
|
|
@@ -2002,3 +2029,200 @@ class DatabaseTransformTest < Minitest::Test
|
|
|
2002
2029
|
assert_equal({ a: 4, b: 5, c: { foo: 45, bar: 46 }}, @db.query_single_splat(transform, sql, 4))
|
|
2003
2030
|
end
|
|
2004
2031
|
end
|
|
2032
|
+
|
|
2033
|
+
class MultiStmtTest < Minitest::Test
|
|
2034
|
+
def setup
|
|
2035
|
+
@db = Extralite::Database.new(':memory:')
|
|
2036
|
+
@db.query('create table t (x)')
|
|
2037
|
+
end
|
|
2038
|
+
|
|
2039
|
+
def test_multi_stmt_execute_simple
|
|
2040
|
+
assert_equal 3, @db.execute(<<~SQL
|
|
2041
|
+
insert into t values (42);
|
|
2042
|
+
insert into t values (43);
|
|
2043
|
+
insert into t values (44);
|
|
2044
|
+
SQL
|
|
2045
|
+
)
|
|
2046
|
+
|
|
2047
|
+
assert_equal [
|
|
2048
|
+
{ x: 42 },
|
|
2049
|
+
{ x: 43 },
|
|
2050
|
+
{ x: 44 }
|
|
2051
|
+
], @db.query('select x from t order by x')
|
|
2052
|
+
end
|
|
2053
|
+
|
|
2054
|
+
def test_multi_stmt_execute_raise_on_params
|
|
2055
|
+
assert_raises(Extralite::Error) {
|
|
2056
|
+
@db.execute <<~SQL, 45
|
|
2057
|
+
insert into t values (42);
|
|
2058
|
+
insert into t values (?);
|
|
2059
|
+
insert into t values (43);
|
|
2060
|
+
|
|
2061
|
+
|
|
2062
|
+
SQL
|
|
2063
|
+
}
|
|
2064
|
+
assert_equal [], @db.query('select x from t order by x')
|
|
2065
|
+
|
|
2066
|
+
# Do not raise if single stmt
|
|
2067
|
+
@db.execute <<~SQL, 42
|
|
2068
|
+
insert into t values (?);
|
|
2069
|
+
|
|
2070
|
+
-- cool comment --
|
|
2071
|
+
SQL
|
|
2072
|
+
assert_equal [
|
|
2073
|
+
{ x: 42 }
|
|
2074
|
+
], @db.query('select x from t order by x')
|
|
2075
|
+
end
|
|
2076
|
+
|
|
2077
|
+
def test_multi_stmt_execute_bad_sql
|
|
2078
|
+
assert_raises(Extralite::SQLError) {
|
|
2079
|
+
@db.execute(<<~SQL
|
|
2080
|
+
insert into t values (42);
|
|
2081
|
+
foo bar;
|
|
2082
|
+
insert into t values (44);
|
|
2083
|
+
SQL
|
|
2084
|
+
)
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
assert_equal [
|
|
2088
|
+
{ x: 42 }
|
|
2089
|
+
], @db.query('select x from t order by x')
|
|
2090
|
+
|
|
2091
|
+
assert_raises(Extralite::SQLError) {
|
|
2092
|
+
@db.execute(<<~SQL, 34
|
|
2093
|
+
insert into t values (?);
|
|
2094
|
+
foo bar;
|
|
2095
|
+
SQL
|
|
2096
|
+
)
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
assert_equal [
|
|
2100
|
+
{ x: 42 }
|
|
2101
|
+
], @db.query('select x from t order by x')
|
|
2102
|
+
end
|
|
2103
|
+
|
|
2104
|
+
def test_multi_stmt_query
|
|
2105
|
+
assert_raises(Extralite::Error) {
|
|
2106
|
+
@db.query("select * from t; insert into t values (1)")
|
|
2107
|
+
}
|
|
2108
|
+
assert_equal [], @db.query('select x from t order by x')
|
|
2109
|
+
end
|
|
2110
|
+
|
|
2111
|
+
def test_multi_stmt_query_bad_sql
|
|
2112
|
+
assert_raises(Extralite::SQLError) {
|
|
2113
|
+
@db.query("insert into t values (?); foo bar")
|
|
2114
|
+
}
|
|
2115
|
+
assert_equal [], @db.query('select x from t order by x')
|
|
2116
|
+
|
|
2117
|
+
assert_raises(Extralite::Error) {
|
|
2118
|
+
@db.query("insert into t values (?); select * from t order by x")
|
|
2119
|
+
}
|
|
2120
|
+
assert_equal [], @db.query('select x from t order by x')
|
|
2121
|
+
end
|
|
2122
|
+
end
|
|
2123
|
+
|
|
2124
|
+
class StmtCacheText < Minitest::Test
|
|
2125
|
+
def setup
|
|
2126
|
+
@db = Extralite::Database.new(':memory:')
|
|
2127
|
+
@db.query('create table t (x)')
|
|
2128
|
+
end
|
|
2129
|
+
|
|
2130
|
+
def test_stmt_cache
|
|
2131
|
+
assert_kind_of Hash, @db.stmt_cache
|
|
2132
|
+
|
|
2133
|
+
db2 = Extralite::Database.new(':memory:', stmt_cache: false)
|
|
2134
|
+
assert_nil db2.stmt_cache
|
|
2135
|
+
end
|
|
2136
|
+
|
|
2137
|
+
def test_stmt_cache_disabled
|
|
2138
|
+
db2 = Extralite::Database.new(':memory:', stmt_cache: false)
|
|
2139
|
+
assert_nil db2.stmt_cache
|
|
2140
|
+
db2.query('create table t (x)')
|
|
2141
|
+
sql = 'insert into t values (?)'
|
|
2142
|
+
|
|
2143
|
+
assert_nil db2.stmt_cache
|
|
2144
|
+
changes = db2.execute(sql, 42)
|
|
2145
|
+
assert_equal 1, changes
|
|
2146
|
+
assert_nil db2.stmt_cache
|
|
2147
|
+
|
|
2148
|
+
changes = db2.execute(sql, 43)
|
|
2149
|
+
assert_equal 1, changes
|
|
2150
|
+
assert_nil db2.stmt_cache
|
|
2151
|
+
|
|
2152
|
+
assert_equal [[42], [43]], db2.query_array('select x from t order by x')
|
|
2153
|
+
end
|
|
2154
|
+
|
|
2155
|
+
def test_stmt_cache_execute_with_params
|
|
2156
|
+
sql = 'insert into t values (?)'
|
|
2157
|
+
|
|
2158
|
+
assert_equal({}, @db.stmt_cache)
|
|
2159
|
+
changes = @db.execute(sql, 42)
|
|
2160
|
+
assert_equal 1, changes
|
|
2161
|
+
assert_equal [sql], @db.stmt_cache.keys
|
|
2162
|
+
|
|
2163
|
+
changes = @db.execute(sql, 43)
|
|
2164
|
+
assert_equal 1, changes
|
|
2165
|
+
assert_equal [sql], @db.stmt_cache.keys
|
|
2166
|
+
assert_kind_of Integer, @db.stmt_cache[sql]
|
|
2167
|
+
assert_equal [[42], [43]], @db.query_array('select x from t order by x')
|
|
2168
|
+
|
|
2169
|
+
stmt = @db.stmt_cache[sql]
|
|
2170
|
+
changes = @db.batch_execute(sql, [47, 48, 49])
|
|
2171
|
+
assert_equal 3, changes
|
|
2172
|
+
assert_equal [sql], @db.stmt_cache.keys
|
|
2173
|
+
assert_equal stmt, @db.stmt_cache[sql]
|
|
2174
|
+
assert_equal [[42], [43], [47], [48], [49]], @db.query_array('select x from t order by x')
|
|
2175
|
+
end
|
|
2176
|
+
|
|
2177
|
+
def test_stmt_cache_execute_without_params
|
|
2178
|
+
sql = 'insert into t values (42)'
|
|
2179
|
+
|
|
2180
|
+
assert_equal({}, @db.stmt_cache)
|
|
2181
|
+
changes = @db.execute(sql)
|
|
2182
|
+
assert_equal 1, changes
|
|
2183
|
+
assert_equal({}, @db.stmt_cache)
|
|
2184
|
+
|
|
2185
|
+
changes = @db.execute(sql)
|
|
2186
|
+
assert_equal 1, changes
|
|
2187
|
+
assert_equal({}, @db.stmt_cache)
|
|
2188
|
+
|
|
2189
|
+
assert_equal [42, 42], @db.query_splat('select x from t order by x')
|
|
2190
|
+
end
|
|
2191
|
+
|
|
2192
|
+
|
|
2193
|
+
def test_stmt_cache_query_with_params
|
|
2194
|
+
@db.execute <<~SQL
|
|
2195
|
+
insert into t values (42), (13), (6)
|
|
2196
|
+
SQL
|
|
2197
|
+
|
|
2198
|
+
sql = 'select x from t where x = ?'
|
|
2199
|
+
|
|
2200
|
+
assert_equal({}, @db.stmt_cache)
|
|
2201
|
+
|
|
2202
|
+
rows = @db.query(sql, 42)
|
|
2203
|
+
assert_equal [{ x: 42 }], rows
|
|
2204
|
+
assert_equal [sql], @db.stmt_cache.keys
|
|
2205
|
+
id = @db.stmt_cache[sql]
|
|
2206
|
+
|
|
2207
|
+
rows = @db.query(sql, 13)
|
|
2208
|
+
assert_equal [{ x: 13 }], rows
|
|
2209
|
+
assert_equal [sql], @db.stmt_cache.keys
|
|
2210
|
+
assert_equal id, @db.stmt_cache[sql]
|
|
2211
|
+
end
|
|
2212
|
+
|
|
2213
|
+
def test_stmt_cache_query_without_params
|
|
2214
|
+
sql = 'select x from t where x = 42'
|
|
2215
|
+
|
|
2216
|
+
rows = @db.query(sql)
|
|
2217
|
+
assert_equal [], rows
|
|
2218
|
+
assert_equal({}, @db.stmt_cache)
|
|
2219
|
+
|
|
2220
|
+
@db.execute <<~SQL
|
|
2221
|
+
insert into t values (42)
|
|
2222
|
+
SQL
|
|
2223
|
+
|
|
2224
|
+
rows = @db.query(sql)
|
|
2225
|
+
assert_equal [{ x: 42 }], rows
|
|
2226
|
+
assert_equal({}, @db.stmt_cache)
|
|
2227
|
+
end
|
|
2228
|
+
end
|
data/test/test_query.rb
CHANGED
|
@@ -406,24 +406,25 @@ class QueryTest < Minitest::Test
|
|
|
406
406
|
assert_equal [1, 4, 7], buf
|
|
407
407
|
end
|
|
408
408
|
|
|
409
|
-
def
|
|
409
|
+
def test_query_prepare_invalid_sql
|
|
410
410
|
assert_raises(Extralite::SQLError) { @db.prepare('blah').to_a }
|
|
411
411
|
end
|
|
412
412
|
|
|
413
|
-
def
|
|
414
|
-
|
|
413
|
+
def test_query_prepare_multi_stmt
|
|
414
|
+
q = @db.prepare('select 1; select 2')
|
|
415
|
+
assert_raises(Extralite::Error) { q.to_a }
|
|
415
416
|
end
|
|
416
417
|
|
|
417
|
-
def
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
418
|
+
def test_query_prepare_multi_stmt_execute
|
|
419
|
+
q = @db.prepare("insert into t values ('a', 'b', 'c'); insert into t values ('d', 'e', 'f');")
|
|
420
|
+
assert_raises(Extralite::Error) { q.execute }
|
|
421
|
+
assert_equal [], @db.query("select x from t where x = 'a'")
|
|
421
422
|
end
|
|
422
423
|
|
|
423
|
-
def
|
|
424
|
+
def test_query_prepare_multi_stmt_bad_sql
|
|
424
425
|
error = nil
|
|
425
426
|
begin
|
|
426
|
-
query
|
|
427
|
+
query = @db.prepare("insert into t values foo; insert into t values ('d', 'e', 'f');")
|
|
427
428
|
query.next
|
|
428
429
|
rescue => error
|
|
429
430
|
end
|
data/test/test_sequel.rb
CHANGED
|
@@ -48,13 +48,13 @@ class SequelExtraliteTest < Minitest::Test
|
|
|
48
48
|
# Adapted from https://github.com/digital-fabric/extralite/issues/8
|
|
49
49
|
Dir.mktmpdir('extralite-migration') do |dir|
|
|
50
50
|
File.write(dir + '/001_migrate.rb', <<~RUBY)
|
|
51
|
-
Sequel.migration do
|
|
51
|
+
Sequel.migration do
|
|
52
52
|
change do
|
|
53
|
-
create_table(:foobars) { primary_key :id }
|
|
53
|
+
create_table(:foobars) { primary_key :id }
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
RUBY
|
|
57
|
-
|
|
57
|
+
|
|
58
58
|
Sequel.extension :migration
|
|
59
59
|
db = Sequel.connect('extralite://')
|
|
60
60
|
Sequel::Migrator.run(db, dir)
|
data/test/test_trace.rb
CHANGED
|
@@ -88,7 +88,7 @@ class DatabaseTraceTest < Minitest::Test
|
|
|
88
88
|
|
|
89
89
|
def test_trace_database_batch_query_with_enumerable
|
|
90
90
|
@db.batch_query('select ?', 1..3)
|
|
91
|
-
|
|
91
|
+
|
|
92
92
|
assert_equal [
|
|
93
93
|
{ sql: 'select ?', args: [1] },
|
|
94
94
|
{ sql: 'select ?', args: [2] },
|
|
@@ -100,7 +100,7 @@ class DatabaseTraceTest < Minitest::Test
|
|
|
100
100
|
values = [4, 5, 6]
|
|
101
101
|
|
|
102
102
|
@db.batch_query('select ?', -> { values.shift })
|
|
103
|
-
|
|
103
|
+
|
|
104
104
|
assert_equal [
|
|
105
105
|
{ sql: 'select ?', args: [4] },
|
|
106
106
|
{ sql: 'select ?', args: [5] },
|
|
@@ -184,6 +184,6 @@ class QueryTraceTest < Minitest::Test
|
|
|
184
184
|
{ sql: 'select ?', args: [43] },
|
|
185
185
|
{ sql: 'select ?', args: [44] },
|
|
186
186
|
], @trace_buf
|
|
187
|
-
|
|
187
|
+
|
|
188
188
|
end
|
|
189
189
|
end
|