diff --git a/PgCodeGen.scala b/PgCodeGen.scala index 7b3acc9..8dc2df1 100644 --- a/PgCodeGen.scala +++ b/PgCodeGen.scala @@ -248,22 +248,13 @@ class PgCodeGen private ( _ <- Future { if debug then println("Running migrations...") - val sortedFiles = sourceFiles - .map(p => - MigrationVersion.fromFileName(p.getFileName().toString()) match - case Right(v) => p -> v - case Left(err) => throw Throwable(s"Invalid migration file name: $err") - ) - .sortBy((_, version) => version) - .map((path, _) => path) - Zone: Using( Database(connectionString).either match case Left(err) => throw err case Right(db) => db )(db => - sortedFiles.foreach: path => + sourceFiles.foreach: path => if debug then println(s"Running migration for $path") db.execute(Files.readString(path)).either match case Left(err) => throw err @@ -759,12 +750,19 @@ object PgCodeGen { def listMigrationFiles: Future[(List[Path], String)] = Future: val digest = MessageDigest.getInstance("SHA-1") val files = listFilesRec(sourceDir.toPath) - .map(path => - digest.update(path.toString.getBytes("UTF-8")) - if !Files.isDirectory(path) then digest.update(Files.readAllBytes(path)) + .filter(!Files.isDirectory(_)) + .map(p => + MigrationVersion.fromFileName(p.getFileName().toString()) match + case Right(v) => Some(p -> v) + case Left(_) if !p.endsWith(".sql") => None // ignore non .sql files + case Left(err) => throw Throwable(s"Invalid migration file name: $err") + ) + .collect { case Some(v) => v } + .sortBy((_, version) => version) + .map((path, _) => + digest.update(Files.readAllBytes(path)) path ) - .filter(!Files.isDirectory(_)) (files, digest.digest().map("%02x".format(_)).mkString) @@ -775,7 +773,13 @@ object PgCodeGen { else listMigrationFiles.flatMap: case (sourceFiles, sha1) => + if debug then println(s"Found ${sourceFiles.length} migration files (SHA1: $sha1)") + val isDivergent = !Files.exists(outDir(sha1)) + + if debug && isDivergent then + println(s"No generated files found in: ${outDir(sha1).toAbsolutePath().toString()}") + if forceRegeneration || isDivergent then for _ <- diff --git a/test.sh b/test.sh index 0b1353d..3a5787d 100755 --- a/test.sh +++ b/test.sh @@ -59,6 +59,24 @@ else exit 1 fi +echo "⏳ running generator again with additional non-sql file and -force=false should not run code generation" +./$CODEGEN_BIN \ + -use-docker-image="postgres:17-alpine" \ + -output-dir=test-generated \ + -pkg-name=generated \ + -exclude-tables=unsupported_yet \ + -source-dir=test/migrations_copy \ + -force=false + +TIMESTAMP_D=$(stat test-generated | grep Modify) + +if [ "$TIMESTAMP_B" == "$TIMESTAMP_D" ]; then + echo "✅ Code generation with additional non-sql file and -force=false as expected (timestamps are the same)" +else + echo "❌ Error: Code generation with additional non-sql file and -force=false not as expected (timestamps differ)" + exit 1 +fi + echo "⏳ running code generator with provided connection" docker run --rm --name codegentest -e POSTGRES_PASSWORD=postgres -p 5555:5432 -d postgres:17-alpine diff --git a/test/migrations_copy/R__a_repeatable.sql b/test/migrations_copy/R__a_repeatable.sql new file mode 100644 index 0000000..f865419 --- /dev/null +++ b/test/migrations_copy/R__a_repeatable.sql @@ -0,0 +1 @@ +CREATE VIEW r_test_view_a AS SELECT 1; diff --git a/test/migrations_copy/R__b_repeatable.sql b/test/migrations_copy/R__b_repeatable.sql new file mode 100644 index 0000000..6ac1c64 --- /dev/null +++ b/test/migrations_copy/R__b_repeatable.sql @@ -0,0 +1 @@ +CREATE VIEW r_test_view_b AS SELECT * FROM r_test_view_a; diff --git a/test/migrations_copy/V1__test.sql b/test/migrations_copy/V1__test.sql new file mode 100644 index 0000000..600c5a7 --- /dev/null +++ b/test/migrations_copy/V1__test.sql @@ -0,0 +1,57 @@ +CREATE TYPE test_enum_type AS ENUM ('T1_ONE', 't2_two', 't3_Three', 'T4_FOUR', 'T5_FIVE', 'T6Six', 'MULTIPLE_WORD_ENUM'); + +-- some comment +CREATE TABLE test ( + -- ignore this... + id SERIAL PRIMARY KEY, + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + name text, + name_2 varchar NOT NULL, + number int, + template test_enum_type, + type varchar, + tla char(3) NOT NULL, + tla_var varchar(3) NOT NULL, + numeric_default numeric NOT NULL, + numeric_24p numeric(24) NOT NULL, + numeric_16p_2s numeric(16, 2) NOT NULL, + gen INT NOT NULL GENERATED ALWAYS AS (1 + 1) STORED, + gen_opt INT GENERATED ALWAYS AS (1 + 1) STORED +); + +CREATE TABLE test_ref_only ( + test_id INT NOT NULL REFERENCES test(id) ON DELETE CASCADE +); + +CREATE TABLE test_ref ( + test_id INT NOT NULL REFERENCES test(id) ON DELETE CASCADE, + ref_name VARCHAR NOT NULL +); + +CREATE TABLE test_ref_auto_pk ( + id SERIAL PRIMARY KEY, + test_id INT NOT NULL REFERENCES test(id) ON DELETE CASCADE, + ref_name VARCHAR NOT NULL +); + +CREATE TABLE test_ref_pk ( + id VARCHAR PRIMARY KEY, + test_id INT NOT NULL REFERENCES test(id) ON DELETE CASCADE, + ref_name VARCHAR NOT NULL +); + +CREATE MATERIALIZED VIEW test_materialized_view AS SELECT id, + created_at, + name, + name_2, + number + FROM test WITH DATA; + + +CREATE VIEW test_view AS SELECT id, + created_at, + name, + name_2, + number, + numeric_default + FROM test; diff --git a/test/migrations_copy/V2__test_b.sql b/test/migrations_copy/V2__test_b.sql new file mode 100644 index 0000000..8bc5ed5 --- /dev/null +++ b/test/migrations_copy/V2__test_b.sql @@ -0,0 +1,33 @@ +CREATE TABLE test_b ( + key_a VARCHAR NOT NULL, + key_b VARCHAR NOT NULL, + val_1 VARCHAR NOT NULL, + val_2 VARCHAR NOT NULL, + val_3 VARCHAR NOT NULL, + val_4 VARCHAR NOT NULL, + val_5 VARCHAR NOT NULL, + val_6 VARCHAR NOT NULL, + val_7 VARCHAR NOT NULL, + val_8 VARCHAR NOT NULL, + val_9 VARCHAR NOT NULL, + val_10 VARCHAR NOT NULL, + val_11 VARCHAR NOT NULL, + val_12 VARCHAR NOT NULL, + val_13 VARCHAR NOT NULL, + val_14 VARCHAR NOT NULL, + val_15 VARCHAR NOT NULL, + val_16 VARCHAR NOT NULL, + val_17 VARCHAR NOT NULL, + val_18 VARCHAR NOT NULL, + val_19 VARCHAR NOT NULL, + val_20 VARCHAR NOT NULL, + val_21 VARCHAR NOT NULL, + val_22 VARCHAR NOT NULL, + val_23 VARCHAR NOT NULL, + val_24 VARCHAR NOT NULL, + val_25 VARCHAR NOT NULL, + val_26 VARCHAR[] NOT NULL, + val_27 INT[], + date DATE, + PRIMARY KEY (key_a, key_b) +); diff --git a/test/migrations_copy/V3__exclude.sql b/test/migrations_copy/V3__exclude.sql new file mode 100644 index 0000000..dcc69f9 --- /dev/null +++ b/test/migrations_copy/V3__exclude.sql @@ -0,0 +1,5 @@ +CREATE TABLE unsupported_yet ( + field_a JSON, + field_b JSONB, + field_c INT[] +); diff --git a/test/migrations_copy/ignore_me b/test/migrations_copy/ignore_me new file mode 100644 index 0000000..e69de29