sequel-sequence 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +32 -6
- data/lib/sequel/sequence/database/postgresql.rb +26 -8
- data/lib/sequel/sequence/database/server/mariadb.rb +19 -4
- data/lib/sequel/sequence/database/server/mysql.rb +19 -11
- data/lib/sequel/sequence/database/sqlite.rb +12 -4
- data/lib/sequel/sequence/database.rb +17 -0
- data/lib/sequel/sequence/version.rb +1 -1
- data/test/mariadb_test_helper.rb +2 -0
- data/test/mysql_test_helper.rb +2 -0
- data/test/postgresql_test_helper.rb +2 -0
- data/test/sequel/mariadb_sequence_test.rb +96 -0
- data/test/sequel/mock_sequence_test.rb +19 -1
- data/test/sequel/mysql_sequence_test.rb +91 -0
- data/test/sequel/postgresql_sequence_test.rb +98 -0
- data/test/sequel/sqlite_sequence_test.rb +89 -0
- data/test/sqlite_test_helper.rb +3 -3
- 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: e6e1a94456ed2dca944d9f5dc7775acdde3db19912cf65c556fc315902dd6514
|
4
|
+
data.tar.gz: 0c6c8ec72019f94c819922dc3c8cc63e63e0d0138a3f95ed442384838d02beb5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97954c433db834abdd23e91fd97abfee863f7f55bcf08d83048a6f3afd7d8fa9e780bfab010758af8b0ec01936ff1f40461ff5ec942e39bf59da894b23670798
|
7
|
+
data.tar.gz: 208dc0051f42068cae2009bb2ee04b0cfc1f0381aa872504621541d3ea36d8aef7aa8800559425a5c107eac8620d82f52722444d8bda0de58caf20e9ced1145f
|
data/CHANGELOG.md
CHANGED
@@ -11,6 +11,16 @@ Prefix your message with one of the following:
|
|
11
11
|
- [Security] in case of vulnerabilities.
|
12
12
|
-->
|
13
13
|
|
14
|
+
## v0.5.0 - 2023-10-08
|
15
|
+
|
16
|
+
- [Fixed] The conditions of migrations were clarified and fixed in README.md.
|
17
|
+
- [Added] The `delete_to_currval(name)` method for MySQL and SQLite `SEQUENCE`-table and Exceptions for any other cases.
|
18
|
+
- [Added] The `drop_sequence?` can accept multiple arguments with condition 'IF EXISTS'.
|
19
|
+
- [Added] The `create_sequence!` drops the `SEQUENCE` if it exists before attempting to create it.
|
20
|
+
- [Changed] INT type to BIGINT type for the primery key of a MySQL `SEQUENCE`-table.
|
21
|
+
- [Added] The ext. params for the PostgreSql `SEQUENCE` ( https://www.postgresql.org/docs/current/sql-createsequence.html )
|
22
|
+
- [Added] The ext. params for the Mariadb `SEQUENCE` ( https://mariadb.com/kb/en/create-sequence )
|
23
|
+
|
14
24
|
## v0.4.2 - 2023-10-03
|
15
25
|
|
16
26
|
- [Added] Additions into README.md.
|
data/README.md
CHANGED
@@ -24,8 +24,6 @@ gem 'sequel-sequence'
|
|
24
24
|
To create and delete a `SEQUENCE`, simply use the `create_sequence` and `drop_sequence` methods.
|
25
25
|
|
26
26
|
```ruby
|
27
|
-
require: 'sequel-sequence'
|
28
|
-
|
29
27
|
Sequel.migration do
|
30
28
|
up do
|
31
29
|
create_sequence :position, if_exists: false
|
@@ -39,8 +37,6 @@ end
|
|
39
37
|
|
40
38
|
It would also be correct to write:
|
41
39
|
```ruby
|
42
|
-
require: 'sequel-sequence'
|
43
|
-
|
44
40
|
Sequel.migration do
|
45
41
|
up do
|
46
42
|
create_sequence :position
|
@@ -86,6 +82,17 @@ Sequel.migration do
|
|
86
82
|
end
|
87
83
|
```
|
88
84
|
|
85
|
+
Before running the migration for your application, don't forget to invoke `require`s, for example like this:
|
86
|
+
```ruby
|
87
|
+
require 'sequel'
|
88
|
+
require 'sequel-sequence'
|
89
|
+
|
90
|
+
migrate = -> (env, version) do
|
91
|
+
...
|
92
|
+
Sequel::Migrator.apply(DB, 'db/migrations', version)
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
89
96
|
This gem also adds a few helpers to interact with `SEQUENCE`s.
|
90
97
|
|
91
98
|
```ruby
|
@@ -120,7 +127,10 @@ and
|
|
120
127
|
DB.nextval_with_label(:position, 1)
|
121
128
|
```
|
122
129
|
|
123
|
-
By default, `fiction` has a zero value.
|
130
|
+
By default, `fiction` has a zero value. Moreover, it is assumed that you can use the history of sequence changes, for example, to collect statistics on the fiction field. However, in most cases, such statistics will not be necessary and you can program periodic cleaning of the SEQUENCE table using the method:
|
131
|
+
```ruby
|
132
|
+
DB.delete_to_currval(:position)
|
133
|
+
```
|
124
134
|
|
125
135
|
Otherwise, the operation of this gem for SQLite and MySQL is similar to the ways of using Sequence in more advanced RDBMS. There is only one difference here, you won't be able to change the increment value from 1 to another using the `increment` or `step` parameter.
|
126
136
|
|
@@ -129,12 +139,28 @@ Otherwise, the operation of this gem for SQLite and MySQL is similar to the ways
|
|
129
139
|
- This solution does not allow you to simultaneously work with MySQL and MariaDB databases from one application. If such a need arises, move the data processing functionality to different microservices.
|
130
140
|
- When you start with a new database in SQLite, you'll receive an error message - "`SQLite3::SQLException: no such table: sqlite_sequence`". `sqlite_sequence` table is not created, until you define at least one autoincrement and primary key column in your schema.
|
131
141
|
|
132
|
-
|
142
|
+
All methods defined in this gem can use either a String or a Symbol parameter to denote a `SEQUENCE`.
|
143
|
+
```ruby
|
144
|
+
DB.nextval('position')
|
145
|
+
```
|
146
|
+
is equivalent to
|
147
|
+
```ruby
|
148
|
+
DB.nextval(:position)
|
149
|
+
```
|
150
|
+
- This solution allows you to specify advanced options for a `SEQUENCE` when creating it in PostgreSQL and MariaDB. For more information, check out the description at https://www.postgresql.org/docs/current/sql-createsequence.html and https://mariadb.com/kb/en/create-sequence.
|
151
|
+
|
152
|
+
## Additional handy methods:
|
133
153
|
|
134
154
|
To discover a database information about `SEQUENCE`s you could take advantage of `check_sequences` and `custom_sequence?` methods.
|
135
155
|
- `custom_sequence?(:sequence_name)` allows you to instantly find out the availability of the called `SEQUENCE`.
|
136
156
|
- `check_sequences` provides complete information about known `SEQUENCE`s in the datebase. The output data depends on RDBMS.
|
137
157
|
|
158
|
+
To remove several sequences at once, you can use the method:
|
159
|
+
- `drop_sequence?` can accept multiple arguments of `SEQUENCE`s and checks the `IF EXISTS` condition for each one.
|
160
|
+
|
161
|
+
To drop previous `SEQUENCE` and recreate the new one utilize the method:
|
162
|
+
- `create_sequence!`.
|
163
|
+
|
138
164
|
## Maintainer
|
139
165
|
|
140
166
|
- [Nikolai Bocharov](https://github.com/oreol-group)
|
@@ -7,8 +7,6 @@ module Sequel
|
|
7
7
|
module Sequence
|
8
8
|
module Database
|
9
9
|
module PostgreSQL
|
10
|
-
SEQUENCE_COMMENT = 'created by sequel-sequence'
|
11
|
-
|
12
10
|
def quote_column_name(name)
|
13
11
|
PG::Connection.quote_ident(name).freeze
|
14
12
|
end
|
@@ -27,7 +25,7 @@ module Sequel
|
|
27
25
|
return false
|
28
26
|
end
|
29
27
|
|
30
|
-
out == SEQUENCE_COMMENT
|
28
|
+
out == Sequel::Database::SEQUENCE_COMMENT
|
31
29
|
end
|
32
30
|
|
33
31
|
def check_sequences
|
@@ -35,23 +33,37 @@ module Sequel
|
|
35
33
|
end
|
36
34
|
|
37
35
|
def create_sequence(name, options = {})
|
36
|
+
data_type = options[:data_type]
|
37
|
+
minvalue = options[:minvalue]
|
38
|
+
maxvalue = options[:maxvalue]
|
39
|
+
start = options[:start]
|
40
|
+
cache = options[:cache]
|
41
|
+
cycle = options[:cycle]
|
42
|
+
owned_by = options[:owned_by]
|
43
|
+
|
38
44
|
increment = options[:increment] || options[:step]
|
39
45
|
if_exists = build_exists_condition(options[:if_exists])
|
40
46
|
name = quote_name(name.to_s)
|
41
47
|
|
42
48
|
sql = ["CREATE SEQUENCE #{if_exists} #{name}"]
|
49
|
+
sql << "AS #{data_type}" if data_type
|
43
50
|
sql << "INCREMENT BY #{increment}" if increment
|
44
|
-
sql << "
|
51
|
+
sql << "MINVALUE #{minvalue}" if minvalue
|
52
|
+
sql << "MAXVALUE #{maxvalue}" if maxvalue
|
53
|
+
sql << "START WITH #{start}" if start
|
54
|
+
sql << "CACHE #{cache}" if cache
|
55
|
+
sql << cycle.to_s if cycle
|
56
|
+
sql << "OWNED BY #{owned_by}" if owned_by
|
45
57
|
sql << ';'
|
46
|
-
sql << "COMMENT ON SEQUENCE #{name} IS '#{SEQUENCE_COMMENT}';"
|
58
|
+
sql << "COMMENT ON SEQUENCE #{name} IS '#{Sequel::Database::SEQUENCE_COMMENT}';"
|
47
59
|
|
48
60
|
run(sql.join("\n"))
|
49
61
|
end
|
50
62
|
|
51
|
-
def drop_sequence(name)
|
63
|
+
def drop_sequence(name, options = {})
|
64
|
+
if_exists = build_exists_condition(options[:if_exists])
|
52
65
|
name = quote_name(name.to_s)
|
53
|
-
|
54
|
-
run(sql)
|
66
|
+
run drop_sequence_table(name, if_exists)
|
55
67
|
end
|
56
68
|
|
57
69
|
def nextval(name)
|
@@ -102,6 +114,12 @@ module Sequel
|
|
102
114
|
).strip
|
103
115
|
run sql
|
104
116
|
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def drop_sequence_table(name, if_exists = nil)
|
121
|
+
"DROP SEQUENCE #{if_exists || Sequel::Database::IF_EXISTS} #{name};"
|
122
|
+
end
|
105
123
|
end
|
106
124
|
end
|
107
125
|
end
|
@@ -26,22 +26,33 @@ module Sequel
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def create_sequence(name, options = {})
|
29
|
+
minvalue = options[:minvalue]
|
30
|
+
maxvalue = options[:maxvalue]
|
31
|
+
start = options[:start]
|
32
|
+
cache = options[:cache]
|
33
|
+
cycle = options[:cycle]
|
34
|
+
|
29
35
|
increment = options[:increment] || options[:step]
|
30
36
|
if_exists = build_exists_condition(options[:if_exists])
|
31
37
|
name = quote_name(name.to_s)
|
32
38
|
|
33
39
|
sql = ["CREATE SEQUENCE #{if_exists || Sequel::Database::IF_NOT_EXISTS} #{name}"]
|
34
40
|
sql << "INCREMENT BY #{increment}" if increment
|
35
|
-
sql << "
|
41
|
+
sql << "MINVALUE #{minvalue}" if minvalue
|
42
|
+
sql << "MAXVALUE #{maxvalue}" if maxvalue
|
43
|
+
sql << "START WITH #{start}" if start
|
44
|
+
sql << "CACHE #{cache}" if cache
|
45
|
+
sql << cycle.to_s if cycle
|
46
|
+
sql << "COMMENT '#{Sequel::Database::SEQUENCE_COMMENT}'"
|
36
47
|
sql << ';'
|
37
48
|
|
38
49
|
run(sql.join("\n"))
|
39
50
|
end
|
40
51
|
|
41
|
-
def drop_sequence(name)
|
52
|
+
def drop_sequence(name, options = {})
|
53
|
+
if_exists = build_exists_condition(options[:if_exists])
|
42
54
|
name = quote_name(name.to_s)
|
43
|
-
|
44
|
-
run(sql)
|
55
|
+
run drop_sequence_table(name, if_exists)
|
45
56
|
end
|
46
57
|
|
47
58
|
def nextval(name)
|
@@ -97,6 +108,10 @@ module Sequel
|
|
97
108
|
def name_of_current_database
|
98
109
|
fetch('SELECT DATABASE() AS db;').first[:db]
|
99
110
|
end
|
111
|
+
|
112
|
+
def drop_sequence_table(name, if_exists = nil)
|
113
|
+
"DROP SEQUENCE #{if_exists || Sequel::Database::IF_EXISTS} #{name};"
|
114
|
+
end
|
100
115
|
end
|
101
116
|
end
|
102
117
|
end
|
@@ -75,12 +75,16 @@ module Sequel
|
|
75
75
|
end
|
76
76
|
|
77
77
|
def set_column_default_nextval(table, column, sequence)
|
78
|
-
run
|
79
|
-
|
80
|
-
|
81
|
-
run
|
82
|
-
|
83
|
-
|
78
|
+
run trigger_create_sequenced_column(stringify(table),
|
79
|
+
stringify(column),
|
80
|
+
stringify(sequence))
|
81
|
+
run trigger_update_sequenced_column(stringify(table),
|
82
|
+
stringify(column),
|
83
|
+
stringify(sequence))
|
84
|
+
end
|
85
|
+
|
86
|
+
def delete_to_currval(name)
|
87
|
+
run delete_to_current_seq(stringify(name))
|
84
88
|
end
|
85
89
|
|
86
90
|
private
|
@@ -97,8 +101,8 @@ module Sequel
|
|
97
101
|
def create_sequence_table(name, if_exists = nil)
|
98
102
|
%(
|
99
103
|
CREATE TABLE #{if_exists || Sequel::Database::IF_NOT_EXISTS} #{name}
|
100
|
-
(id
|
101
|
-
fiction
|
104
|
+
(id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
105
|
+
fiction BIGINT);
|
102
106
|
).strip
|
103
107
|
end
|
104
108
|
|
@@ -109,7 +113,7 @@ module Sequel
|
|
109
113
|
def create_mysql_sequence
|
110
114
|
%(
|
111
115
|
CREATE TABLE #{Sequel::Database::IF_NOT_EXISTS} mysql_sequence
|
112
|
-
(name VARCHAR(40), seq
|
116
|
+
(name VARCHAR(40), seq BIGINT);
|
113
117
|
).strip
|
114
118
|
end
|
115
119
|
|
@@ -147,7 +151,7 @@ module Sequel
|
|
147
151
|
"INSERT INTO mysql_sequence (name, seq) VALUES ('#{name}', LAST_INSERT_ID());"
|
148
152
|
end
|
149
153
|
|
150
|
-
def
|
154
|
+
def trigger_create_sequenced_column(table, _column, sequence)
|
151
155
|
%(
|
152
156
|
CREATE TRIGGER IF NOT EXISTS #{table}_#{sequence} BEFORE INSERT
|
153
157
|
ON #{table}
|
@@ -160,7 +164,7 @@ module Sequel
|
|
160
164
|
).strip
|
161
165
|
end
|
162
166
|
|
163
|
-
def
|
167
|
+
def trigger_update_sequenced_column(table, column, sequence)
|
164
168
|
%(
|
165
169
|
CREATE TRIGGER IF NOT EXISTS #{table}_#{column} BEFORE INSERT
|
166
170
|
ON #{table}
|
@@ -178,6 +182,10 @@ module Sequel
|
|
178
182
|
raise e
|
179
183
|
# :nocov:
|
180
184
|
end
|
185
|
+
|
186
|
+
def delete_to_current_seq(name)
|
187
|
+
"DELETE QUICK IGNORE FROM #{name} WHERE id < (SELECT * FROM (SELECT MAX(id) FROM #{name} ) AS a);"
|
188
|
+
end
|
181
189
|
end
|
182
190
|
end
|
183
191
|
end
|
@@ -62,9 +62,13 @@ module Sequel
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def set_column_default_nextval(table, column, sequence)
|
65
|
-
run(
|
66
|
-
|
67
|
-
|
65
|
+
run(trigger_create_sequenced_column(stringify(table),
|
66
|
+
stringify(column),
|
67
|
+
stringify(sequence)))
|
68
|
+
end
|
69
|
+
|
70
|
+
def delete_to_currval(name)
|
71
|
+
run delete_to_current_seq(stringify(name))
|
68
72
|
end
|
69
73
|
|
70
74
|
private
|
@@ -113,7 +117,7 @@ module Sequel
|
|
113
117
|
"SELECT MAX(seq) AS id FROM sqlite_sequence WHERE name = '#{name}';"
|
114
118
|
end
|
115
119
|
|
116
|
-
def
|
120
|
+
def trigger_create_sequenced_column(table, column, sequence)
|
117
121
|
%(
|
118
122
|
CREATE TRIGGER IF NOT EXISTS #{table}_#{sequence} AFTER INSERT
|
119
123
|
ON #{table}
|
@@ -125,6 +129,10 @@ module Sequel
|
|
125
129
|
END;
|
126
130
|
)
|
127
131
|
end
|
132
|
+
|
133
|
+
def delete_to_current_seq(name)
|
134
|
+
"DELETE FROM #{name} WHERE id < (SELECT MAX(id) FROM #{name});"
|
135
|
+
end
|
128
136
|
end
|
129
137
|
end
|
130
138
|
end
|
@@ -7,6 +7,7 @@ module Sequel
|
|
7
7
|
DANGER_OPT_INCREMENT = 'Warning! Increments greater than 1 are not supported.'
|
8
8
|
IF_EXISTS = 'IF EXISTS'
|
9
9
|
IF_NOT_EXISTS = 'IF NOT EXISTS'
|
10
|
+
SEQUENCE_COMMENT = 'created by sequel-sequence'
|
10
11
|
|
11
12
|
def check_options(params)
|
12
13
|
log_info DANGER_OPT_INCREMENT if params[:increment] && params[:increment] != 1
|
@@ -73,6 +74,22 @@ module Sequel
|
|
73
74
|
IF_NOT_EXISTS
|
74
75
|
end
|
75
76
|
end
|
77
|
+
|
78
|
+
def delete_to_currval(_name)
|
79
|
+
raise Sequel::MethodNotAllowed, Sequel::Database::METHOD_NOT_ALLOWED
|
80
|
+
end
|
81
|
+
|
82
|
+
def drop_sequence?(*names)
|
83
|
+
names.each do |n|
|
84
|
+
drop_sequence(n, if_exists: true)
|
85
|
+
end
|
86
|
+
false
|
87
|
+
end
|
88
|
+
|
89
|
+
def create_sequence!(name, options = nil)
|
90
|
+
drop_sequence(name, if_exists: true)
|
91
|
+
create_sequence(name, options)
|
92
|
+
end
|
76
93
|
end
|
77
94
|
end
|
78
95
|
end
|
data/test/mariadb_test_helper.rb
CHANGED
data/test/mysql_test_helper.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
|
+
# require 'logger'
|
4
5
|
|
5
6
|
MysqlDB = Sequel.connect(
|
7
|
+
# loggers: [Logger.new($stdout)],
|
6
8
|
adapter: 'mysql2',
|
7
9
|
user: ENV['TEST_MYSQL_USERNAME'] || 'root',
|
8
10
|
password: ENV['TEST_MYSQL_PASSWORD'] || 'rootroot',
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
|
+
# require 'logger'
|
4
5
|
|
5
6
|
PostgresqlDB = Sequel.connect(
|
7
|
+
# loggers: [Logger.new($stdout)],
|
6
8
|
adapter: 'postgres',
|
7
9
|
user: ENV['TEST_POSTGRES_USERNAME'] || 'postgres',
|
8
10
|
password: ENV['TEST_POSTGRES_PASSWORD'] || 'postgres',
|
@@ -230,4 +230,100 @@ class MariadbSequenceTest < Minitest::Test
|
|
230
230
|
|
231
231
|
assert_equal pos2 - pos1, 1
|
232
232
|
end
|
233
|
+
|
234
|
+
test 'checks exception for delete_to_currval method' do
|
235
|
+
with_migration do
|
236
|
+
def up
|
237
|
+
create_sequence :position_id, if_exists: false, start: 1
|
238
|
+
end
|
239
|
+
end.up
|
240
|
+
|
241
|
+
assert_equal 1, MariaDB.currval(:position_id)
|
242
|
+
|
243
|
+
assert_raises Sequel::MethodNotAllowed do
|
244
|
+
MariaDB.delete_to_currval(:position_id)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
test 'deletes sequences by "drop_sequence?"' do
|
249
|
+
with_migration do
|
250
|
+
def up
|
251
|
+
create_sequence :a
|
252
|
+
create_sequence :b
|
253
|
+
create_sequence :c
|
254
|
+
end
|
255
|
+
end.up
|
256
|
+
|
257
|
+
assert MariaDB.custom_sequence?(:a)
|
258
|
+
assert MariaDB.custom_sequence?(:b)
|
259
|
+
assert MariaDB.custom_sequence?(:c)
|
260
|
+
|
261
|
+
MariaDB.drop_sequence?(:a, :b, :c, :d)
|
262
|
+
|
263
|
+
assert !MariaDB.custom_sequence?(:a)
|
264
|
+
assert !MariaDB.custom_sequence?(:b)
|
265
|
+
assert !MariaDB.custom_sequence?(:c)
|
266
|
+
end
|
267
|
+
|
268
|
+
test 'deletes if exists before creating! the sequence' do
|
269
|
+
with_migration do
|
270
|
+
def up
|
271
|
+
create_sequence! :position, { start: 1000, increment: 10 }
|
272
|
+
end
|
273
|
+
end.up
|
274
|
+
|
275
|
+
assert_equal 1000, MariaDB.currval(:position)
|
276
|
+
|
277
|
+
10.times { MariaDB.nextval(:position) }
|
278
|
+
assert_equal 1100, MariaDB.currval(:position)
|
279
|
+
|
280
|
+
MariaDB.create_sequence!(:position, { start: 1, increment: 1 })
|
281
|
+
|
282
|
+
assert_equal 1, MariaDB.currval(:position)
|
283
|
+
|
284
|
+
10.times { MariaDB.nextval(:position) }
|
285
|
+
assert_equal 11, MariaDB.currval(:position)
|
286
|
+
end
|
287
|
+
|
288
|
+
test 'checks the BIGINT primery key for a sequence table' do
|
289
|
+
with_migration do
|
290
|
+
def up
|
291
|
+
create_sequence :position, { start: 9_223_372_036_854_775_800 }
|
292
|
+
end
|
293
|
+
end.up
|
294
|
+
|
295
|
+
assert_equal 9_223_372_036_854_775_800, MariaDB.currval(:position)
|
296
|
+
assert_equal 9_223_372_036_854_775_801, MariaDB.nextval(:position)
|
297
|
+
end
|
298
|
+
|
299
|
+
test 'checks the BIGINT primery key with negative value for a sequence table' do
|
300
|
+
with_migration do
|
301
|
+
def up
|
302
|
+
create_sequence :position, { minvalue: -9_223_372_036_854_775_807 }
|
303
|
+
end
|
304
|
+
end.up
|
305
|
+
|
306
|
+
assert_equal(-9_223_372_036_854_775_807, MariaDB.currval(:position))
|
307
|
+
assert_equal(-9_223_372_036_854_775_806, MariaDB.nextval(:position))
|
308
|
+
end
|
309
|
+
|
310
|
+
# https://mariadb.com/kb/en/create-sequence/#arguments-to-create
|
311
|
+
test 'adds sequence with ext. params' do
|
312
|
+
with_migration do
|
313
|
+
def up
|
314
|
+
create_sequence :position, {
|
315
|
+
minvalue: -250,
|
316
|
+
maxvalue: 250,
|
317
|
+
start: -1,
|
318
|
+
cache: 3,
|
319
|
+
cycle: 'CYCLE',
|
320
|
+
increment: 2,
|
321
|
+
if_exists: false
|
322
|
+
}
|
323
|
+
end
|
324
|
+
end.up
|
325
|
+
|
326
|
+
assert_equal(-1, MariaDB.nextval('position'))
|
327
|
+
assert_equal 1, MariaDB.nextval('position')
|
328
|
+
end
|
233
329
|
end
|
@@ -20,7 +20,7 @@ class MockSequenceTest < Minitest::Test
|
|
20
20
|
mocked_method.verify
|
21
21
|
end
|
22
22
|
|
23
|
-
test 'checks custom_sequence?' do
|
23
|
+
test 'checks "custom_sequence?"' do
|
24
24
|
assert_raises Sequel::MethodNotAllowed do
|
25
25
|
MockDB.custom_sequence?(:position)
|
26
26
|
end
|
@@ -97,4 +97,22 @@ class MockSequenceTest < Minitest::Test
|
|
97
97
|
test 'checks build_exists_condition for a non boolean condition' do
|
98
98
|
assert_nil MockDB.build_exists_condition('')
|
99
99
|
end
|
100
|
+
|
101
|
+
test 'checks delete_to_currval' do
|
102
|
+
assert_raises Sequel::MethodNotAllowed do
|
103
|
+
MockDB.delete_to_currval(:position)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
test 'checks "drop_sequence?"' do
|
108
|
+
assert_raises Sequel::MethodNotAllowed do
|
109
|
+
MockDB.drop_sequence?(:position)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
test 'checks "create_sequence!"' do
|
114
|
+
assert_raises Sequel::MethodNotAllowed do
|
115
|
+
MockDB.create_sequence!(:position)
|
116
|
+
end
|
117
|
+
end
|
100
118
|
end
|
@@ -394,4 +394,95 @@ class MysqlSequenceTest < Minitest::Test
|
|
394
394
|
MysqlDB.setval(:position, 100)
|
395
395
|
assert_equal 100, MysqlDB.currval(:position)
|
396
396
|
end
|
397
|
+
|
398
|
+
test 'deletes history from the sequence_table' do
|
399
|
+
with_migration do
|
400
|
+
def up
|
401
|
+
create_sequence :position_id, if_exists: false, start: 1
|
402
|
+
end
|
403
|
+
end.up
|
404
|
+
|
405
|
+
assert_equal 1, MysqlDB.currval(:position_id)
|
406
|
+
|
407
|
+
sequence_table_size = MysqlDB.fetch('SELECT count(*) as len FROM position_id;').first[:len]
|
408
|
+
assert_equal 1, sequence_table_size
|
409
|
+
|
410
|
+
10.times { MysqlDB.nextval(:position_id) }
|
411
|
+
|
412
|
+
assert_equal 11, MysqlDB.currval(:position_id)
|
413
|
+
|
414
|
+
sequence_table_size = MysqlDB.fetch('SELECT count(*) as len FROM position_id;').first[:len]
|
415
|
+
assert_equal 11, sequence_table_size
|
416
|
+
|
417
|
+
MysqlDB.delete_to_currval(:position_id)
|
418
|
+
|
419
|
+
assert_equal 11, MysqlDB.currval(:position_id)
|
420
|
+
|
421
|
+
sequence_table_size = MysqlDB.fetch('SELECT count(*) as len FROM position_id;').first[:len]
|
422
|
+
assert_equal 1, sequence_table_size
|
423
|
+
end
|
424
|
+
|
425
|
+
test 'deletes sequences by "drop_sequence?"' do
|
426
|
+
with_migration do
|
427
|
+
def up
|
428
|
+
create_sequence :a
|
429
|
+
create_sequence :b
|
430
|
+
create_sequence :c
|
431
|
+
end
|
432
|
+
end.up
|
433
|
+
|
434
|
+
assert MysqlDB.custom_sequence?(:a)
|
435
|
+
assert MysqlDB.custom_sequence?(:b)
|
436
|
+
assert MysqlDB.custom_sequence?(:c)
|
437
|
+
|
438
|
+
MysqlDB.drop_sequence?(:a, :b, :c, :d)
|
439
|
+
|
440
|
+
assert !MysqlDB.custom_sequence?(:a)
|
441
|
+
assert !MysqlDB.custom_sequence?(:b)
|
442
|
+
assert !MysqlDB.custom_sequence?(:c)
|
443
|
+
end
|
444
|
+
|
445
|
+
test 'deletes if exists before creating! the sequence' do
|
446
|
+
with_migration do
|
447
|
+
def up
|
448
|
+
create_sequence! :position, { start: 1000, increment: 10 }
|
449
|
+
end
|
450
|
+
end.up
|
451
|
+
|
452
|
+
assert_equal 1000, MysqlDB.currval(:position)
|
453
|
+
|
454
|
+
10.times { MysqlDB.nextval(:position) }
|
455
|
+
assert_equal 1010, MysqlDB.currval(:position)
|
456
|
+
|
457
|
+
MysqlDB.create_sequence!(:position, { start: 1, increment: 1 })
|
458
|
+
|
459
|
+
assert_equal 1, MysqlDB.currval(:position)
|
460
|
+
|
461
|
+
10.times { MysqlDB.nextval(:position) }
|
462
|
+
assert_equal 11, MysqlDB.currval(:position)
|
463
|
+
end
|
464
|
+
|
465
|
+
test 'checks the BIGINT primery key for a sequence table' do
|
466
|
+
with_migration do
|
467
|
+
def up
|
468
|
+
create_sequence :position, { start: 9_223_372_036_854_775_800 }
|
469
|
+
end
|
470
|
+
end.up
|
471
|
+
|
472
|
+
assert_equal 9_223_372_036_854_775_800, MysqlDB.currval(:position)
|
473
|
+
assert_equal 9_223_372_036_854_775_801, MysqlDB.nextval(:position)
|
474
|
+
end
|
475
|
+
|
476
|
+
test 'checks the BIGINT primery key with negative value for a sequence table (does not support)' do
|
477
|
+
with_migration do
|
478
|
+
def up
|
479
|
+
create_sequence :position, { start: -9_223_372_036_854_775_807 }
|
480
|
+
end
|
481
|
+
end.up
|
482
|
+
|
483
|
+
assert_equal(-9_223_372_036_854_775_807, MysqlDB.currval(:position))
|
484
|
+
# https://www.cockroachlabs.com/docs/stable/serial#generated-values-for-modes-rowid-and-virtual_sequence
|
485
|
+
# "...negative values are not returned."
|
486
|
+
assert_equal 1, MysqlDB.nextval(:position)
|
487
|
+
end
|
397
488
|
end
|
@@ -238,4 +238,102 @@ class PostgresqlSequenceTest < Minitest::Test
|
|
238
238
|
|
239
239
|
assert_equal pos2 - pos1, 1
|
240
240
|
end
|
241
|
+
|
242
|
+
test 'checks exception for delete_to_currval method' do
|
243
|
+
with_migration do
|
244
|
+
def up
|
245
|
+
create_sequence :position_id, if_exists: false, start: 1
|
246
|
+
end
|
247
|
+
end.up
|
248
|
+
|
249
|
+
assert_equal 1, PostgresqlDB.currval(:position_id)
|
250
|
+
|
251
|
+
assert_raises Sequel::MethodNotAllowed do
|
252
|
+
PostgresqlDB.delete_to_currval(:position_id)
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
test 'deletes sequences by "drop_sequence?"' do
|
257
|
+
with_migration do
|
258
|
+
def up
|
259
|
+
create_sequence :a
|
260
|
+
create_sequence :b
|
261
|
+
create_sequence :c
|
262
|
+
end
|
263
|
+
end.up
|
264
|
+
|
265
|
+
assert PostgresqlDB.custom_sequence?(:a)
|
266
|
+
assert PostgresqlDB.custom_sequence?(:b)
|
267
|
+
assert PostgresqlDB.custom_sequence?(:c)
|
268
|
+
|
269
|
+
PostgresqlDB.drop_sequence?(:a, :b, :c, :d)
|
270
|
+
|
271
|
+
assert !PostgresqlDB.custom_sequence?(:a)
|
272
|
+
assert !PostgresqlDB.custom_sequence?(:b)
|
273
|
+
assert !PostgresqlDB.custom_sequence?(:c)
|
274
|
+
end
|
275
|
+
|
276
|
+
test 'deletes if exists before creating! the sequence' do
|
277
|
+
with_migration do
|
278
|
+
def up
|
279
|
+
create_sequence! :position, { start: 1000, increment: 10 }
|
280
|
+
end
|
281
|
+
end.up
|
282
|
+
|
283
|
+
assert_equal 1000, PostgresqlDB.currval(:position)
|
284
|
+
|
285
|
+
10.times { PostgresqlDB.nextval(:position) }
|
286
|
+
assert_equal 1100, PostgresqlDB.currval(:position)
|
287
|
+
|
288
|
+
PostgresqlDB.create_sequence!(:position, { start: 1, increment: 1 })
|
289
|
+
|
290
|
+
assert_equal 1, PostgresqlDB.currval(:position)
|
291
|
+
|
292
|
+
10.times { PostgresqlDB.nextval(:position) }
|
293
|
+
assert_equal 11, PostgresqlDB.currval(:position)
|
294
|
+
end
|
295
|
+
|
296
|
+
test 'checks the BIGINT primery key for a sequence table' do
|
297
|
+
with_migration do
|
298
|
+
def up
|
299
|
+
create_sequence :position, { start: 9_223_372_036_854_775_800 }
|
300
|
+
end
|
301
|
+
end.up
|
302
|
+
|
303
|
+
assert_equal 9_223_372_036_854_775_800, PostgresqlDB.currval(:position)
|
304
|
+
assert_equal 9_223_372_036_854_775_801, PostgresqlDB.nextval(:position)
|
305
|
+
end
|
306
|
+
|
307
|
+
test 'checks the BIGINT primery key with negative value for a sequence table' do
|
308
|
+
with_migration do
|
309
|
+
def up
|
310
|
+
create_sequence :position, { minvalue: -9_223_372_036_854_775_808 }
|
311
|
+
end
|
312
|
+
end.up
|
313
|
+
|
314
|
+
assert_equal(-9_223_372_036_854_775_808, PostgresqlDB.currval(:position))
|
315
|
+
assert_equal(-9_223_372_036_854_775_807, PostgresqlDB.nextval(:position))
|
316
|
+
end
|
317
|
+
|
318
|
+
# https://www.postgresql.org/docs/current/sql-createsequence.html
|
319
|
+
test 'adds sequence with ext. params' do
|
320
|
+
with_migration do
|
321
|
+
def up
|
322
|
+
create_sequence :position, {
|
323
|
+
data_type: 'smallint',
|
324
|
+
minvalue: -250,
|
325
|
+
maxvalue: 250,
|
326
|
+
start: -1,
|
327
|
+
cache: 3,
|
328
|
+
cycle: 'CYCLE',
|
329
|
+
owned_by: 'NONE',
|
330
|
+
increment: 2,
|
331
|
+
if_exists: false
|
332
|
+
}
|
333
|
+
end
|
334
|
+
end.up
|
335
|
+
|
336
|
+
assert_equal(-1, PostgresqlDB.nextval('position'))
|
337
|
+
assert_equal 1, PostgresqlDB.nextval('position')
|
338
|
+
end
|
241
339
|
end
|
@@ -366,4 +366,93 @@ class SqliteSequenceTest < Minitest::Test
|
|
366
366
|
SQLiteDB.setval(:position, 100)
|
367
367
|
assert_equal 100, SQLiteDB.currval(:position)
|
368
368
|
end
|
369
|
+
|
370
|
+
test 'deletes history from the sequence_table' do
|
371
|
+
with_migration do
|
372
|
+
def up
|
373
|
+
create_sequence :position_id, if_exists: false, start: 1
|
374
|
+
end
|
375
|
+
end.up
|
376
|
+
|
377
|
+
assert_equal 1, SQLiteDB.currval(:position_id)
|
378
|
+
|
379
|
+
sequence_table_size = SQLiteDB.fetch('SELECT count(*) as len FROM position_id;').first[:len]
|
380
|
+
assert_equal 1, sequence_table_size
|
381
|
+
|
382
|
+
10.times { SQLiteDB.nextval(:position_id) }
|
383
|
+
|
384
|
+
assert_equal 11, SQLiteDB.currval(:position_id)
|
385
|
+
|
386
|
+
sequence_table_size = SQLiteDB.fetch('SELECT count(*) as len FROM position_id;').first[:len]
|
387
|
+
assert_equal 11, sequence_table_size
|
388
|
+
|
389
|
+
SQLiteDB.delete_to_currval(:position_id)
|
390
|
+
|
391
|
+
assert_equal 11, SQLiteDB.currval(:position_id)
|
392
|
+
|
393
|
+
sequence_table_size = SQLiteDB.fetch('SELECT count(*) as len FROM position_id;').first[:len]
|
394
|
+
assert_equal 1, sequence_table_size
|
395
|
+
end
|
396
|
+
|
397
|
+
test 'deletes sequences by "drop_sequence?"' do
|
398
|
+
with_migration do
|
399
|
+
def up
|
400
|
+
create_sequence :a
|
401
|
+
create_sequence :b
|
402
|
+
create_sequence :c
|
403
|
+
end
|
404
|
+
end.up
|
405
|
+
|
406
|
+
assert SQLiteDB.custom_sequence?(:a)
|
407
|
+
assert SQLiteDB.custom_sequence?(:b)
|
408
|
+
assert SQLiteDB.custom_sequence?(:c)
|
409
|
+
|
410
|
+
SQLiteDB.drop_sequence?(:a, :b, :c, :d)
|
411
|
+
|
412
|
+
assert !SQLiteDB.custom_sequence?(:a)
|
413
|
+
assert !SQLiteDB.custom_sequence?(:b)
|
414
|
+
assert !SQLiteDB.custom_sequence?(:c)
|
415
|
+
end
|
416
|
+
|
417
|
+
test 'deletes if exists before creating! the sequence' do
|
418
|
+
with_migration do
|
419
|
+
def up
|
420
|
+
create_sequence! :position, { start: 1000, increment: 10 }
|
421
|
+
end
|
422
|
+
end.up
|
423
|
+
|
424
|
+
assert_equal 1000, SQLiteDB.currval(:position)
|
425
|
+
|
426
|
+
10.times { SQLiteDB.nextval(:position) }
|
427
|
+
assert_equal 1010, SQLiteDB.currval(:position)
|
428
|
+
|
429
|
+
SQLiteDB.create_sequence!(:position, { start: 1, increment: 1 })
|
430
|
+
|
431
|
+
assert_equal 1, SQLiteDB.currval(:position)
|
432
|
+
|
433
|
+
10.times { SQLiteDB.nextval(:position) }
|
434
|
+
assert_equal 11, SQLiteDB.currval(:position)
|
435
|
+
end
|
436
|
+
|
437
|
+
test 'checks the BIGINT primery key for a sequence table' do
|
438
|
+
with_migration do
|
439
|
+
def up
|
440
|
+
create_sequence :position, { start: 9_223_372_036_854_775_800 }
|
441
|
+
end
|
442
|
+
end.up
|
443
|
+
|
444
|
+
assert_equal 9_223_372_036_854_775_800, SQLiteDB.currval(:position)
|
445
|
+
assert_equal 9_223_372_036_854_775_801, SQLiteDB.nextval(:position)
|
446
|
+
end
|
447
|
+
|
448
|
+
test 'checks the BIGINT primery key with negative value for a sequence table (does not support)' do
|
449
|
+
with_migration do
|
450
|
+
def up
|
451
|
+
create_sequence :position, { start: -9_223_372_036_854_775_807 }
|
452
|
+
end
|
453
|
+
end.up
|
454
|
+
|
455
|
+
assert_equal 0, SQLiteDB.currval(:position)
|
456
|
+
assert_equal 1, SQLiteDB.nextval(:position)
|
457
|
+
end
|
369
458
|
end
|
data/test/sqlite_test_helper.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
|
-
require 'logger'
|
4
|
+
# require 'logger'
|
5
5
|
|
6
6
|
SQLiteDB = Sequel.connect(
|
7
|
-
|
8
|
-
|
7
|
+
# loggers: [Logger.new($stdout)],
|
8
|
+
"sqlite://#{ENV.fetch('TEST_SQLITE_DATABASE', nil) || 'db/test.sqlite3'}"
|
9
9
|
)
|
10
10
|
|
11
11
|
module SqliteTestHelper
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel-sequence
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikolai Bocharov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|