prick 0.35.0 → 0.37.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b8acf851da65b094d2abab5a6d9469f20a974732b9e8a8f5bbc4542f72bf8dae
4
- data.tar.gz: d7ce7beb146b47aea6f25a93771b206a41434bd2ecbd3a1df33b8580374e29ea
3
+ metadata.gz: aa15e8c866ef97ee0ba04de08ca05ea38b5cf47d6cb156e09be24d3e10a0c8d5
4
+ data.tar.gz: 550a8f65c73c1148fa8f9359dbfb7299d0ae2ca4c8acfc3aea7c82f7254c399f
5
5
  SHA512:
6
- metadata.gz: b861e5129259bcb0dd384ba7e3c2db09c826cd50105ec514bda309268779e56458a99a3ef8ca1b83226accf7ce6569b957790e5c4374473a3cfb3700ba5ef380
7
- data.tar.gz: 6c1b7227ffa63e49825f4acb503d855b9110f18224c1b3f2f7b27b72a92ac0eb3865ea8926470995a71988cb64ab9aa4a5bb26420adafd152364fd31ee28d23a
6
+ metadata.gz: 0b6ccea7c28cb6068597899dc8f740629fc7e3d26d7457a06c7c0e76abca1987cf63e422f2be482300c8b44474e0cda941510c1e97653ec4af064c57bb79eea4
7
+ data.tar.gz: 2e2685d9b25938dc291204eaa7735a167cbd7014219678dddb86ed6e02aa90c960de3aaf8e79fbe64becfff198d435c5ad05aa1657856ce1e1ea5bacee1de9d2
data/exe/prick CHANGED
@@ -150,6 +150,15 @@ SPEC = %(
150
150
  different data sets
151
151
 
152
152
  # TODO: A --clean option that resets data
153
+ #
154
+
155
+ snapshot!
156
+ Records maximum ID for all tables and stores them in prick.snapshot. It is
157
+ used by 'drop data' to reset data to the point in time of the snapshot.
158
+ Only one snapshot can be created at a time
159
+
160
+ reset!
161
+ Restore database to the last snapshot. TODO
153
162
 
154
163
  version!
155
164
  Print project version
@@ -223,6 +232,10 @@ def require_db(database = Prick.state&.database, exist: true)
223
232
  end
224
233
  end
225
234
 
235
+ def clean_pg_meta_cache
236
+ FileUtils.rm_f(PG_META_STATE_PATH)
237
+ end
238
+
226
239
  def parse_database_args(state, args)
227
240
  arg, environment = args.expect(0..2)
228
241
  if arg
@@ -296,13 +309,13 @@ begin
296
309
  database = state.database
297
310
  username = state.username
298
311
  environment = state.environment
299
-
300
312
  # Process subcommands
301
313
  case opts.subcommand
302
314
  when :version!
303
315
  puts "#{Prick.state.name}-#{Prick.state.version}"
304
316
 
305
317
  when :setup!
318
+ clean_pg_meta_cache
306
319
  state.project_loaded? or Prick.error "No #{project_file} found"
307
320
  username, database, environment = parse_database_args(state, args)
308
321
  require_db(database, exist: false)
@@ -310,6 +323,7 @@ begin
310
323
 
311
324
  # FIXME Ensure that we never drop the current user
312
325
  when :teardown!
326
+ clean_pg_meta_cache
313
327
  if args.empty?
314
328
  Prick::SubCommand.teardown(database, remove_state_file: true)
315
329
  else
@@ -326,11 +340,13 @@ begin
326
340
  end
327
341
 
328
342
  when :set!
343
+ clean_pg_meta_cache
329
344
  variable, *args = args.expect(1..3)
330
345
  require_db(database) if variable == "duration"
331
346
  Prick::SubCommand.set(variable, *args) or error "Illegal variable name '#{variable}'"
332
347
 
333
348
  when :clean!
349
+ clean_pg_meta_cache
334
350
  database = args.expect(0..1) || database
335
351
  require_db(database)
336
352
  Prick::SubCommand.clean(database)
@@ -339,10 +355,12 @@ begin
339
355
  create_command = opts.create! # Because we need easy access to subcommand options
340
356
  case create_command.subcommand
341
357
  when :database!
358
+ clean_pg_meta_cache
342
359
  database, username, environment = parse_database_args(state, args)
343
360
  require_db(database, exist: false)
344
361
  Prick::SubCommand.create_database(database, username, environment)
345
362
  when :migration!
363
+ # clean_pg_meta_cache # FIXME ?
346
364
  require_db
347
365
  arg = args.expect(1)
348
366
  version = PrickVersion.try(arg) or Prick.error "Illegal version: #{arg}"
@@ -358,6 +376,7 @@ begin
358
376
 
359
377
  when :build!
360
378
  require_db
379
+ clean_pg_meta_cache
361
380
  dump = cmd.dump? ? cmd.dump("batches")&.to_sym || :batches : nil
362
381
  # exclude = cmd.exclude? ? cmd.exclude.split(",") : []
363
382
  Prick::SubCommand.build(
@@ -366,6 +385,7 @@ begin
366
385
 
367
386
  when :make!
368
387
  require_db
388
+ clean_pg_meta_cache
369
389
  dump = cmd.dump? ? cmd.dump("batches")&.to_sym || :batches : nil
370
390
  Prick::SubCommand.make(
371
391
  database, username, args.expect(0..1),
@@ -373,18 +393,26 @@ begin
373
393
 
374
394
  when :run!
375
395
  require_db
396
+ clean_pg_meta_cache
376
397
  dump = cmd.dump? ? cmd.dump("batches")&.to_sym || :batches : nil
377
398
  Prick::SubCommand.run(
378
399
  database, username, args.expect(1),
379
400
  step: cmd.step?, timer: cmd.time?, dump: dump, schema: cmd.schema)
380
401
 
381
402
  when :bash!
403
+ args.expect(0)
404
+ clean_pg_meta_cache
382
405
  Prick::SubCommand.bash(main: cmd.main?)
383
406
 
384
407
  when :fox!
385
408
  require_db
386
409
  Prick::SubCommand.fox(database, username, args)
387
410
 
411
+ when :snapshot!
412
+ require_db
413
+ args.expect(0)
414
+ Prick::SubCommand.snapshot(database, username)
415
+
388
416
  when :drop!
389
417
  case cmd.subcommand
390
418
  when :users!
@@ -397,12 +425,16 @@ begin
397
425
  owner = args.expect(0..1) || username
398
426
  Prick::SubCommand.drop_owner(owner)
399
427
  when :database!
428
+ clean_pg_meta_cache
400
429
  database = args.expect(0..1) || database
401
430
  Prick::SubCommand.drop_database(database)
402
431
  when :data!
403
- raise NotImplementedError
432
+ args.expect(0)
433
+ require_db
434
+ Prick::SubCommand.drop_data(database)
404
435
  when :schema!
405
436
  require_db
437
+ clean_pg_meta_cache
406
438
  schemas = args.to_a
407
439
  Prick::SubCommand.drop_schema(database, schemas)
408
440
  else
@@ -417,6 +449,7 @@ begin
417
449
 
418
450
  when :migrate!
419
451
  require_db
452
+ # clean_pg_meta_cache # FIXME ?
420
453
  args.expect(0)
421
454
  Prick::SubCommand.migrate(database, username, file: cmd.file)
422
455
 
@@ -15,8 +15,6 @@ module Prick
15
15
  def schema() @schema ||= parent&.schema || "public" end
16
16
  def schema=(s) @schema = s end
17
17
 
18
- attr_reader :source
19
-
20
18
  def source
21
19
  @source ||= read_source
22
20
  end
@@ -98,6 +98,7 @@ module Prick
98
98
  # value is returned
99
99
  def parse_file_entry(unit, dir, entry)
100
100
  entry = entry.sub(/\/$/, "")
101
+ # puts "#parse_file_entry(#{unit.path.inspect}, #{dir.inspect}, #{entry.inspect})"
101
102
  if entry =~ /^(\S+?)(\?)?(?:\s+(.+))?\s*$/
102
103
  command = $1
103
104
  optional = !$2.nil?
@@ -141,7 +142,7 @@ module Prick
141
142
  (path, args = parse_file_entry(unit, dir, entry)) or return nil
142
143
  if File.directory? path
143
144
  parse_directory(unit, path)
144
- elsif File.executable? path
145
+ elsif File.executable?(path)
145
146
  ExecNode.new(unit, phase, path, args)
146
147
  elsif File.file? path
147
148
  case path
@@ -166,10 +167,13 @@ module Prick
166
167
  #
167
168
  # Note that "." is ignored in the search path
168
169
  def find_executable(filename) # ChatGPT
169
- Prick.state.executable_search_path.split(File::PATH_SEPARATOR).each do |directory|
170
- next if directory == "."
171
- path = File.join(directory, filename)
172
- return path if File.file?(path) && File.executable?(path)
170
+ # puts "#find_executable(#{filename.inspect})"
171
+ if !Prick.state.environments.key?(filename) # Environment names are reserved
172
+ Prick.state.executable_search_path.split(File::PATH_SEPARATOR).each do |directory|
173
+ next if directory == "."
174
+ path = File.join(directory, filename)
175
+ return path if File.file?(path) && File.executable?(path)
176
+ end
173
177
  end
174
178
  nil
175
179
  end
@@ -40,6 +40,8 @@ module Prick
40
40
  PRICK_ENVIRONMENT_FILE = "prick.environment.yml"
41
41
  PRICK_ENVIRONMENT_PATH = PRICK_ENVIRONMENT_FILE
42
42
 
43
+ # TODO: Move to var/cache
44
+
43
45
  # State file
44
46
  PRICK_STATE_FILE = ".prick.state.yml"
45
47
  PRICK_STATE_PATH = PRICK_STATE_FILE
@@ -48,6 +50,10 @@ module Prick
48
50
  FOX_STATE_FILE = ".fox-state.yml"
49
51
  FOX_STATE_PATH = FOX_STATE_FILE
50
52
 
53
+ # PgMeta snapshot. Is deleted at the start of each build
54
+ PG_META_STATE_FILE = ".pg_meta-state.yml"
55
+ PG_META_STATE_PATH = PG_META_STATE_FILE
56
+
51
57
  # Reflections file
52
58
  REFLECTIONS_FILE = "reflections.yml"
53
59
  REFLECTIONS_PATH = File.join(SCHEMA_DIR, REFLECTIONS_FILE)
@@ -35,3 +35,12 @@ create table builds (
35
35
  make_duration float -- Duration of enclosing make script
36
36
  );
37
37
 
38
+ create table snapshots (
39
+ id integer generated by default as identity primary key,
40
+ schema_name varchar not null,
41
+ table_name varchar not null,
42
+ max_id integer, -- may be null
43
+
44
+ unique(schema_name, table_name)
45
+ );
46
+
@@ -41,6 +41,35 @@ module Prick::SubCommand
41
41
  State.connection { |conn| conn.rdbms.drop database }
42
42
  end
43
43
 
44
+ # Drop data not in snapshot
45
+ def self.drop_data(database, schemas = nil)
46
+ conn = Prick.state.conn
47
+ conn.session.triggers(false) {
48
+ if schemas.nil?
49
+ builder = Prick::Build::Builder.new(conn, Prick.state.schema_dir)
50
+ pool = builder.pool
51
+ schemas = pool.refresh_schemas
52
+ end
53
+ schema_list = conn.quote_literal_list(schemas)
54
+ schema_expr = schemas ? "true = true" : "schema_name in #{schema_list}"
55
+ tables = conn.tuples %(
56
+ select schema_name, table_name, max_id
57
+ from prick.snapshots
58
+ where #{schema_expr}
59
+ )
60
+ tables.each { |schema, table, max_id|
61
+ uid = "#{schema}.#{table}"
62
+ if max_id
63
+ conn.exec "delete from #{uid} where id > #{max_id}"
64
+ conn.schema.set_serial(schema, table, max_id) if conn.schema.sequence(schema, table)
65
+ else
66
+ conn.exec "delete from #{uid}"
67
+ conn.schema.set_serial(schema, table, nil) if conn.schema.sequence(schema, table)
68
+ end
69
+ }
70
+ }
71
+ end
72
+
44
73
  # Empty the database
45
74
  def self.drop_schema(database, schemas = [])
46
75
  constrain database, String
@@ -65,7 +65,7 @@ module Prick::SubCommand
65
65
  end
66
66
  end
67
67
 
68
- # Write-back schema to builder
68
+ # Write back schema to builder
69
69
  builder.root.schema = schema
70
70
 
71
71
  # Drop schema if needed
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../builder/builder.rb'
4
+
5
+ module Prick::SubCommand
6
+ def self.snapshot(
7
+ database, username,
8
+ builddir: Prick.state.schema_dir)
9
+
10
+ conn = Prick.state.connection
11
+ builder = Prick::Build::Builder.new(conn, builddir)
12
+ pool = builder.pool
13
+ schemas = pool.refresh_schemas
14
+
15
+ # Clear snapshots table
16
+ conn.exec "delete from prick.snapshots"
17
+
18
+ # Fill it again
19
+ records = []
20
+ for schema in schemas
21
+ conn.schema.list_tables(schema).each { |table|
22
+ max_id = conn.value "select max(id) from #{schema}.#{table}"
23
+ records << { schema_name: schema, table_name: table, max_id: max_id}
24
+ }
25
+ end
26
+ conn.insert("prick", "snapshots", records)
27
+ end
28
+ end
29
+
@@ -1,4 +1,4 @@
1
- module Prick::Subcommand
1
+ module Prick::SubCommand
2
2
  # def self.parse_username_database
3
3
  # case username_database
4
4
  # when nil
data/lib/prick/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Prick
4
- VERSION = "0.35.0"
4
+ VERSION = "0.37.0"
5
5
  end
data/lib/prick.rb CHANGED
@@ -53,6 +53,7 @@ require_relative 'prick/subcommand/prick-release.rb'
53
53
  require_relative 'prick/subcommand/prick-run.rb'
54
54
  require_relative 'prick/subcommand/prick-set.rb'
55
55
  require_relative 'prick/subcommand/prick-setup.rb'
56
+ require_relative 'prick/subcommand/prick-snapshot.rb'
56
57
  require_relative 'prick/subcommand/prick-teardown.rb'
57
58
 
58
59
  module Prick
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prick
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.35.0
4
+ version: 0.37.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-04-28 00:00:00.000000000 Z
11
+ date: 2024-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: semantic
@@ -233,6 +233,7 @@ files:
233
233
  - lib/prick/subcommand/prick-run.rb
234
234
  - lib/prick/subcommand/prick-set.rb
235
235
  - lib/prick/subcommand/prick-setup.rb
236
+ - lib/prick/subcommand/prick-snapshot.rb
236
237
  - lib/prick/subcommand/prick-teardown.rb
237
238
  - lib/prick/subcommand/subcommand.rb
238
239
  - lib/prick/version.rb