foundries 0.1.4 → 0.1.6
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 +11 -9
- data/lib/foundries/similarity/comparator.rb +1 -1
- data/lib/foundries/similarity/structure_tree.rb +1 -1
- data/lib/foundries/snapshot/adapters/postgres_adapter.rb +11 -3
- data/lib/foundries/snapshot/adapters/sqlite_adapter.rb +5 -1
- data/lib/foundries/snapshot/store.rb +37 -3
- data/lib/foundries/version.rb +2 -2
- 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: 12575eccffc55ee4735cc1fe6cb981ed1109d252d45b6435ab4b8333862f2663
|
|
4
|
+
data.tar.gz: 5ecb9d8707258542b76ec9e72caf4daa3619d72c0dff8f4778163a880302aa3b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bb1eba53555fdf59b449b06cef7e973516341d2806ceed56d42d2e26a43e58be877bf6459cb551b71610acb6790a7f001a3761b5098b25245bb8d3c58be6805e
|
|
7
|
+
data.tar.gz: ef7bd963c7c76e978a96ffed6562358a47cbfdb0da52e873f9613b4aecb3bcc357a4143282b7ff743ddada31e142fcdb8bd395035fa99291dbef4b890d06f419
|
data/CHANGELOG.md
CHANGED
|
@@ -5,19 +5,21 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
7
7
|
|
|
8
|
-
## [0.1.
|
|
8
|
+
## [0.1.6] - 2026-08-25
|
|
9
9
|
|
|
10
|
-
###
|
|
10
|
+
### Fixed
|
|
11
11
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
12
|
+
- Snapshot files are read and written in binary, so captured data with non-ASCII bytes round-trips (6a7d3a3)
|
|
13
|
+
- Restoring a snapshot no longer rewinds a sequence below its current value (df66836)
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
## [0.1.5] - 2026-08-12
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
### Changed
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
- Development dependencies are locked (1129826)
|
|
20
20
|
|
|
21
|
-
###
|
|
21
|
+
### Fixed
|
|
22
22
|
|
|
23
|
-
-
|
|
23
|
+
- Snapshot no longer caches a partial tree when a preset writes to a table that already held rows (2e9f863)
|
|
24
|
+
- Lint under standard 1.56.0 (52be9eb)
|
|
25
|
+
- Releases write a SHA512 checksum again (813a2ae)
|
|
@@ -16,6 +16,10 @@ module Foundries
|
|
|
16
16
|
@connection.select_value("SELECT NOT EXISTS (SELECT 1 FROM #{quoted(table_name)})")
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
+
def count(table_name)
|
|
20
|
+
@connection.select_value("SELECT COUNT(*) FROM #{quoted(table_name)}")
|
|
21
|
+
end
|
|
22
|
+
|
|
19
23
|
def capture(table_name, io)
|
|
20
24
|
raw = @connection.raw_connection
|
|
21
25
|
raw.copy_data("COPY #{quoted(table_name)} TO STDOUT") do
|
|
@@ -51,10 +55,14 @@ module Foundries
|
|
|
51
55
|
)
|
|
52
56
|
return unless seq
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
# setval is not transactional, and rows can already be committed
|
|
59
|
+
# past the restored data (e.g. seeded outside this transaction), so
|
|
60
|
+
# the sequence must only ever move forward.
|
|
61
|
+
@connection.execute(
|
|
62
|
+
"SELECT setval(#{@connection.quote(seq)}, GREATEST(" \
|
|
63
|
+
"(SELECT COALESCE(MAX(#{@connection.quote_column_name(pk)}), 0) FROM #{quoted(table_name)}), " \
|
|
64
|
+
"(SELECT last_value FROM #{seq})))"
|
|
56
65
|
)
|
|
57
|
-
@connection.execute("SELECT setval(#{@connection.quote(seq)}, #{max_id})")
|
|
58
66
|
end
|
|
59
67
|
|
|
60
68
|
private
|
|
@@ -13,7 +13,11 @@ module Foundries
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def empty?(table_name)
|
|
16
|
-
|
|
16
|
+
count(table_name) == 0
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def count(table_name)
|
|
20
|
+
@connection.select_value("SELECT COUNT(*) FROM #{quoted(table_name)}")
|
|
17
21
|
end
|
|
18
22
|
|
|
19
23
|
def capture(table_name, io)
|
|
@@ -25,18 +25,41 @@ module Foundries
|
|
|
25
25
|
|
|
26
26
|
# Record which tables are empty before the preset block runs.
|
|
27
27
|
# Only these tables will be captured after the block completes.
|
|
28
|
+
#
|
|
29
|
+
# The already-populated tables are counted too, so #capture can tell
|
|
30
|
+
# whether the preset wrote into one of them. A preset that only updates
|
|
31
|
+
# existing rows leaves the count unchanged and slips past this check;
|
|
32
|
+
# presets insert, so the count is a good enough signal.
|
|
28
33
|
def record_empty_tables
|
|
29
|
-
@capturable_tables =
|
|
34
|
+
@capturable_tables = []
|
|
35
|
+
@preexisting_counts = {}
|
|
36
|
+
|
|
37
|
+
@adapter.table_names.each do |table|
|
|
38
|
+
if @adapter.empty?(table)
|
|
39
|
+
@capturable_tables << table
|
|
40
|
+
else
|
|
41
|
+
@preexisting_counts[table] = @adapter.count(table)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
30
44
|
end
|
|
31
45
|
|
|
32
46
|
def capture
|
|
47
|
+
spoiled = spoiled_tables
|
|
48
|
+
unless spoiled.empty?
|
|
49
|
+
warn "[Foundries] Not caching preset :#{@preset_name} — it wrote to " \
|
|
50
|
+
"#{spoiled.join(", ")}, which already held rows when it ran. " \
|
|
51
|
+
"Only tables the preset fills from empty can be snapshotted, so " \
|
|
52
|
+
"caching this would restore an incomplete tree."
|
|
53
|
+
return
|
|
54
|
+
end
|
|
55
|
+
|
|
33
56
|
tables = @capturable_tables || @adapter.table_names
|
|
34
57
|
|
|
35
58
|
tmp_dir = Pathname.new("#{cache_dir}.#{$$}.tmp")
|
|
36
59
|
tmp_dir.mkpath
|
|
37
60
|
|
|
38
61
|
tables.each do |table|
|
|
39
|
-
tmp_dir.join("#{table}.dat").open("
|
|
62
|
+
tmp_dir.join("#{table}.dat").open("wb") do |f|
|
|
40
63
|
@adapter.capture(table, f)
|
|
41
64
|
end
|
|
42
65
|
end
|
|
@@ -54,7 +77,7 @@ module Foundries
|
|
|
54
77
|
next unless file.size > 0
|
|
55
78
|
|
|
56
79
|
table = file.basename(".dat").to_s
|
|
57
|
-
file.open("
|
|
80
|
+
file.open("rb") do |f|
|
|
58
81
|
@adapter.restore(table, f)
|
|
59
82
|
end
|
|
60
83
|
@adapter.reset_sequence(table)
|
|
@@ -64,6 +87,17 @@ module Foundries
|
|
|
64
87
|
|
|
65
88
|
private
|
|
66
89
|
|
|
90
|
+
# Pre-populated tables whose row count moved while the preset ran. Their
|
|
91
|
+
# new rows can't be told apart from the ones that were already there, so
|
|
92
|
+
# the snapshot would silently omit them.
|
|
93
|
+
def spoiled_tables
|
|
94
|
+
return [] unless @preexisting_counts
|
|
95
|
+
|
|
96
|
+
@preexisting_counts.filter_map do |table, count|
|
|
97
|
+
table unless @adapter.count(table) == count
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
67
101
|
def cache_dir
|
|
68
102
|
@cache_dir ||= Pathname.new(@storage_path).join(@preset_name)
|
|
69
103
|
end
|
data/lib/foundries/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foundries
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- John Dowd
|
|
@@ -93,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
93
93
|
- !ruby/object:Gem::Version
|
|
94
94
|
version: '0'
|
|
95
95
|
requirements: []
|
|
96
|
-
rubygems_version: 4.0.
|
|
96
|
+
rubygems_version: 4.0.16
|
|
97
97
|
specification_version: 4
|
|
98
98
|
summary: Declarative trees of related data using factory_bot
|
|
99
99
|
test_files: []
|