e621_export_downloader 0.0.18 → 0.0.19
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c5d969922b067f0eb6f92d7f73497105d17a2d228b86a34931f24eaed48c2312
|
|
4
|
+
data.tar.gz: f85056aa89a468b019ae03585b53470d0b1c1d8d31c335f1c47e000e7727c743
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: df8d73bb8eaea951cb41e26c0384647f5219ec71518962986d88a014ded3592454e8ea64bf07c2f4acf44a23b42de0e47b1bbda8134dd42631481ccafb6a3615
|
|
7
|
+
data.tar.gz: c7fce51d4283904e52f3defd64fa1de02a4a624a52983cd571123a9124349f4b71edb934d40f7f68d34dd4bbb28c580b28bc423fd221413082771c0d91ec12e5
|
data/lib/e621/csv_importable.rb
CHANGED
|
@@ -49,9 +49,11 @@ module E621
|
|
|
49
49
|
model.connection.execute("TRUNCATE #{model.quoted_table_name}") if truncate
|
|
50
50
|
indexes.each_key { |name| model.connection.execute("DROP INDEX IF EXISTS #{name}") }
|
|
51
51
|
|
|
52
|
-
count =
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
count = begin
|
|
53
|
+
copy_csv(csv_path, chunk_bytes: chunk_bytes)
|
|
54
|
+
ensure
|
|
55
|
+
indexes.each_value { |ddl| model.connection.execute(ddl) }
|
|
56
|
+
end
|
|
55
57
|
self.row_count = count
|
|
56
58
|
count
|
|
57
59
|
end
|
|
@@ -55,7 +55,7 @@ module E621ExportDownloader
|
|
|
55
55
|
client.debug("downloading export", header: ["export:#{type.serialize}"])
|
|
56
56
|
|
|
57
57
|
FileUtils.mkdir_p(Constants::TEMP_DIR)
|
|
58
|
-
digest = T.let(client.options.validate_checksum ? Digest::
|
|
58
|
+
digest = T.let(client.options.validate_checksum ? Digest::SHA256.new : nil, T.nilable(Digest::SHA256))
|
|
59
59
|
File.open(file_path, "wb") do |file|
|
|
60
60
|
inflater = Zlib::Inflate.new(Zlib::MAX_WBITS + 16)
|
|
61
61
|
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require("minitest/autorun")
|
|
4
|
+
require("tempfile")
|
|
5
|
+
require("active_record")
|
|
6
|
+
require("e621_export_downloader")
|
|
7
|
+
require("e621/csv_importable")
|
|
8
|
+
require("e621/row_count")
|
|
9
|
+
|
|
10
|
+
class CsvImportablePostgresTestModel < ActiveRecord::Base
|
|
11
|
+
extend(E621::CsvImportable)
|
|
12
|
+
|
|
13
|
+
self.table_name = "import_index_test_tags"
|
|
14
|
+
self.record_timestamps = false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class CsvImportablePostgresTest < Minitest::Test
|
|
18
|
+
INDEX_NAME = "index_import_index_test_tags_on_name"
|
|
19
|
+
|
|
20
|
+
def setup
|
|
21
|
+
skip("set E621_TEST_DATABASE_URL to run PostgreSQL import tests") unless ENV["E621_TEST_DATABASE_URL"]
|
|
22
|
+
|
|
23
|
+
ActiveRecord::Base.establish_connection(ENV.fetch("E621_TEST_DATABASE_URL"))
|
|
24
|
+
@tempfiles = []
|
|
25
|
+
setup_schema
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def teardown
|
|
29
|
+
return unless ENV["E621_TEST_DATABASE_URL"]
|
|
30
|
+
|
|
31
|
+
connection.execute("DROP TABLE IF EXISTS import_index_test_tags")
|
|
32
|
+
connection.execute("DROP TABLE IF EXISTS e621.row_counts")
|
|
33
|
+
@tempfiles&.each(&:unlink)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_recreate_indexes_restores_postgres_indexes_after_successful_import
|
|
37
|
+
count = CsvImportablePostgresTestModel.import_from_csv(csv_file(successful_csv), truncate: true, recreate_indexes: true, chunk_bytes: 8)
|
|
38
|
+
|
|
39
|
+
assert_equal(2, count)
|
|
40
|
+
assert_equal(2, CsvImportablePostgresTestModel.count)
|
|
41
|
+
assert_index_exists
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_recreate_indexes_restores_postgres_indexes_after_import_error
|
|
45
|
+
error = assert_raises(StandardError) do
|
|
46
|
+
CsvImportablePostgresTestModel.import_from_csv(csv_file(invalid_csv), truncate: true, recreate_indexes: true, chunk_bytes: 8)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
assert_match(/COPY|missing data|extra data|invalid input/i, error.message)
|
|
50
|
+
assert_index_exists
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def setup_schema
|
|
56
|
+
connection.execute("CREATE SCHEMA IF NOT EXISTS e621")
|
|
57
|
+
connection.execute(<<~SQL)
|
|
58
|
+
CREATE TABLE IF NOT EXISTS e621.row_counts (
|
|
59
|
+
table_name varchar PRIMARY KEY,
|
|
60
|
+
count bigint NOT NULL DEFAULT 0
|
|
61
|
+
)
|
|
62
|
+
SQL
|
|
63
|
+
connection.execute("DROP TABLE IF EXISTS import_index_test_tags")
|
|
64
|
+
connection.execute(<<~SQL)
|
|
65
|
+
CREATE TABLE import_index_test_tags (
|
|
66
|
+
id bigint PRIMARY KEY,
|
|
67
|
+
name text NOT NULL,
|
|
68
|
+
post_count integer NOT NULL
|
|
69
|
+
)
|
|
70
|
+
SQL
|
|
71
|
+
connection.execute("CREATE INDEX #{INDEX_NAME} ON import_index_test_tags (name)")
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def successful_csv
|
|
75
|
+
<<~CSV
|
|
76
|
+
id,name,post_count
|
|
77
|
+
1,alpha,10
|
|
78
|
+
2,beta,20
|
|
79
|
+
CSV
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def invalid_csv
|
|
83
|
+
<<~CSV
|
|
84
|
+
id,name,post_count
|
|
85
|
+
1,alpha
|
|
86
|
+
CSV
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def csv_file(content)
|
|
90
|
+
file = Tempfile.new(["e621-import", ".csv"])
|
|
91
|
+
file.write(content)
|
|
92
|
+
file.close
|
|
93
|
+
@tempfiles << file
|
|
94
|
+
file.path
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def assert_index_exists
|
|
98
|
+
assert(index_exists?, "expected PostgreSQL index #{INDEX_NAME} to exist")
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def index_exists?
|
|
102
|
+
connection.select_value(<<~SQL)
|
|
103
|
+
SELECT EXISTS (
|
|
104
|
+
SELECT 1
|
|
105
|
+
FROM pg_class c
|
|
106
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
107
|
+
WHERE c.relkind = 'i'
|
|
108
|
+
AND c.relname = #{connection.quote(INDEX_NAME)}
|
|
109
|
+
)
|
|
110
|
+
SQL
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def connection
|
|
114
|
+
ActiveRecord::Base.connection
|
|
115
|
+
end
|
|
116
|
+
end
|
data/test/export_test.rb
CHANGED
|
@@ -39,7 +39,7 @@ class ExportChecksumTest < Minitest::Test
|
|
|
39
39
|
def setup
|
|
40
40
|
@csv_content = "id,name\n1,foo\n"
|
|
41
41
|
@compressed = Zlib.gzip(@csv_content)
|
|
42
|
-
@checksum = Digest::
|
|
42
|
+
@checksum = Digest::SHA256.hexdigest(@compressed)
|
|
43
43
|
# split across chunks to exercise streaming, matching how a real download arrives
|
|
44
44
|
midpoint = @compressed.bytesize / 2
|
|
45
45
|
@chunks = [@compressed.byteslice(0, midpoint), @compressed.byteslice(midpoint..)]
|
|
@@ -79,14 +79,14 @@ class ExportChecksumTest < Minitest::Test
|
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
def test_download_raises_and_removes_the_file_when_checksum_does_not_match
|
|
82
|
-
export = build_export(checksum: "0" *
|
|
82
|
+
export = build_export(checksum: "0" * 64, validate_checksum: true)
|
|
83
83
|
error = assert_raises(E621ExportDownloader::ResolveError) { export.download }
|
|
84
84
|
assert_match(/Checksum mismatch/, error.message)
|
|
85
85
|
assert_empty(Dir.children(E621ExportDownloader::Constants::TEMP_DIR))
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
def test_download_ignores_checksum_mismatch_when_validation_is_disabled
|
|
89
|
-
export = build_export(checksum: "0" *
|
|
89
|
+
export = build_export(checksum: "0" * 64, validate_checksum: false)
|
|
90
90
|
path = export.download
|
|
91
91
|
assert(File.exist?(path))
|
|
92
92
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: e621_export_downloader
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.19
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Donovan_DMC
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-08-03 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: csv
|
|
@@ -223,6 +223,7 @@ files:
|
|
|
223
223
|
- sorbet/rbi/todo.rbi
|
|
224
224
|
- sorbet/tapioca/config.yml
|
|
225
225
|
- sorbet/tapioca/require.rb
|
|
226
|
+
- test/csv_importable_postgres_test.rb
|
|
226
227
|
- test/export_test.rb
|
|
227
228
|
- test/generators/install_generator_test.rb
|
|
228
229
|
homepage: https://github.com/DonovanDMC/E621ExportDownloader.rb
|