prick 0.35.0 → 0.37.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: 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