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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a027c577de1ee27127880328c29208456a26635c9ea18b1c5eb3c1cb0dbbd5fc
4
- data.tar.gz: 71764d6ec16bf3425ba3d3bfb4ac47c04dd2a6f7001342c0ae35ebec63af293d
3
+ metadata.gz: e6e1a94456ed2dca944d9f5dc7775acdde3db19912cf65c556fc315902dd6514
4
+ data.tar.gz: 0c6c8ec72019f94c819922dc3c8cc63e63e0d0138a3f95ed442384838d02beb5
5
5
  SHA512:
6
- metadata.gz: 5ce8091d3c644545cecff05c0f85a6252bdd8de015710770a861bfea81793fc50c5b96d19ce304fc2158cd40fc8bfde72f88309e0dc6dea468e2a977a533f980
7
- data.tar.gz: a80404a67e51b77a1dd6ac40fe8ebbd93329b170e25855024f325e965f76ec9ad723ea2698fc4f699edad9cd7eb8555c5f6b28d870eb6c2f0355c44686904b19
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
- ## Additional handy functions
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 << "START WITH #{options[:start]}" if options[:start]
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
- sql = "DROP SEQUENCE IF EXISTS #{name}"
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 << "START WITH #{options[:start]}" if options[:start]
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
- sql = "DROP SEQUENCE IF EXISTS #{name}"
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 create_sequenced_column(stringify(table),
79
- stringify(column),
80
- stringify(sequence))
81
- run update_sequenced_column(stringify(table),
82
- stringify(column),
83
- stringify(sequence))
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 INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
101
- fiction INT);
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 INT);
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 create_sequenced_column(table, _column, sequence)
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 update_sequenced_column(table, column, sequence)
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(create_sequenced_column(stringify(table),
66
- stringify(column),
67
- stringify(sequence)))
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 create_sequenced_column(table, column, sequence)
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sequel
4
4
  module Sequence
5
- VERSION = '0.4.2'
5
+ VERSION = '0.5.0'
6
6
  end
7
7
  end
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'test_helper'
4
+ # require 'logger'
4
5
 
5
6
  MariaDB = Sequel.connect(
7
+ # loggers: [Logger.new($stdout)],
6
8
  adapter: 'mysql2',
7
9
  user: ENV['TEST_MARIA_USERNAME'] || 'root',
8
10
  password: ENV['TEST_MARIA_PASSWORD'] || 'root',
@@ -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
@@ -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
- "sqlite://#{ENV.fetch('TEST_SQLITE_DATABASE', nil) || 'db/test.sqlite3'}",
8
- loggers: [Logger.new($stdout)]
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.2
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-03 00:00:00.000000000 Z
11
+ date: 2023-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel