Skip to content

Commit bec7d22

Browse files
mpalmerjxs
andauthored
Support int8 migration versions via new int8-versions feature (#330)
* Support int8 migration versions via new int8-versions feature This addresses, though does not really *fix* #83, because it doesn't make refinery support timestamped migrations *by default*, but only if you opt-in to the new feature. However, making it an optional feature neatly sidesteps the unanswered questions in the issue, and so makes the implementation easier to complete and land. * cargo clippy * update wording * remove repr * fix enum migrations * enable int8-versions test * fix PR --------- Co-authored-by: João Oliveira <[email protected]>
1 parent 967f98e commit bec7d22

24 files changed

+221
-64
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
- run: rustup self update
6262
- run: cd refinery_core && cargo test --all-features -- --test-threads 1
6363
- run: cd refinery && cargo build --all-features
64-
- run: cd refinery_macros && cargo test --features=enums
64+
- run: cd refinery_macros && cargo test --all-features
6565
- run: cd refinery_cli && cargo test
6666

6767
test-sqlite:
@@ -98,6 +98,7 @@ jobs:
9898
toolchain: ${{ matrix.rust }}
9999
- run: cargo install --path ./refinery_cli --no-default-features --features=postgresql
100100
- run: cd refinery && cargo test --features postgres --test postgres -- --test-threads 1
101+
- run: cd refinery && cargo test --features postgres,int8-versions --test postgres -- --test-threads 1
101102

102103
test-tokio-postgres:
103104
name: Test tokio-postgres

README.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ If you are using a driver that is not yet supported, namely [`SQLx`](https://git
3535
- Migrations, both .sql files and Rust modules must be named in the format `[U|V]{1}__{2}.sql` or `[U|V]{1}__{2}.rs`, where `{1}` represents the migration version and `{2}` the name.
3636
- Migrations can be run either by embedding them in your Rust code with `embed_migrations` macro, or via [refinery_cli].
3737

38+
NOTE:
39+
40+
- By default, migration version numbers are restricted to `i32` (signed, 32-bit integers).
41+
- If you enable the `int8-versions` feature, this restriction is lifted to being able to use `i64`s for your migration version numbers.
42+
Bear in mind that this feature must be enabled *before* you start using refinery on a given database.
43+
Migrating an existing database's `refinery_schema_history` table to use `int8` versions **will break the checksums on all previously-applied migrations**.
44+
3845
### Example: Library
3946
```rust,no_run
4047
use rusqlite::Connection;
@@ -53,15 +60,10 @@ fn main() {
5360
For more library examples, refer to the [`examples`](https://github.com/rust-db/refinery/tree/main/examples).
5461
### Example: CLI
5562

56-
NOTE:
57-
58-
- Contiguous (adjacent) migration version numbers are restricted to `u32` (unsigned, 32-bit integers).
59-
- Non-contiguous (not adjacent) migration version numbers are restricted to `u32` (unsigned, 32-bit integers).
60-
6163
```bash
6264
export DATABASE_URL="postgres://postgres:secret@localhost:5432/your-db"
6365
pushd migrations
64-
# Runs ./src/V1__*.rs or ./src/V1__*.sql
66+
# Runs ./src/V1__*.rs or ./src/V1__*.sql
6567
refinery migrate -e DATABASE_URL -p ./src -t 1
6668
popd
6769
```

examples/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ edition = "2021"
1010

1111
[features]
1212
enums = ["refinery/enums"]
13+
int8-versions = ["refinery/int8-versions"]
1314

1415
[dependencies]
1516
refinery = { path = "../refinery", features = ["rusqlite"] }

refinery/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ tiberius-config = ["refinery-core/tiberius", "refinery-core/tiberius-config"]
2525
serde = ["refinery-core/serde"]
2626
toml = ["refinery-core/toml"]
2727
enums = ["refinery-macros/enums"]
28+
int8-versions = ["refinery-core/int8-versions", "refinery-macros/int8-versions"]
2829

2930
[dependencies]
3031
refinery-core = { version = "0.8.16", path = "../refinery_core" }

refinery/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ for more examples refer to the [examples](https://github.com/rust-db/refinery/tr
3232
*/
3333

3434
pub use refinery_core::config;
35-
pub use refinery_core::{error, load_sql_migrations, Error, Migration, Report, Runner, Target};
35+
pub use refinery_core::{
36+
error, load_sql_migrations, Error, Migration, Report, Runner, SchemaVersion, Target,
37+
};
3638
#[doc(hidden)]
3739
pub use refinery_core::{AsyncMigrate, Migrate};
3840
pub use refinery_macros::embed_migrations;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use barrel::{types, Migration};
2+
3+
use crate::Sql;
4+
5+
pub fn migration() -> String {
6+
let mut m = Migration::new();
7+
8+
m.create_table("persons", |t| {
9+
t.add_column("id", types::primary());
10+
t.add_column("name", types::varchar(255));
11+
t.add_column("city", types::varchar(255));
12+
});
13+
14+
m.make::<Sql>()
15+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CREATE TABLE cars (
2+
id int,
3+
name varchar(255)
4+
);
5+
CREATE TABLE motos (
6+
id int,
7+
name varchar(255)
8+
);
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE cars
2+
ADD brand varchar(255);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use barrel::{types, Migration};
2+
3+
use crate::Sql;
4+
5+
pub fn migration() -> String {
6+
let mut m = Migration::new();
7+
8+
m.change_table("motos", |t| {
9+
t.add_column("brand", types::varchar(255).nullable(true));
10+
});
11+
12+
m.make::<Sql>()
13+
}

refinery/tests/postgres.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ mod postgres {
3030
embed_migrations!("./tests/migrations_missing");
3131
}
3232

33+
#[cfg(feature = "int8-versions")]
34+
mod int8 {
35+
use refinery::embed_migrations;
36+
embed_migrations!("./tests/migrations_int8");
37+
}
38+
3339
fn db_uri() -> String {
3440
std::env::var("DB_URI").unwrap_or("postgres://postgres@localhost:5432/postgres".to_string())
3541
}
@@ -183,6 +189,37 @@ mod postgres {
183189
});
184190
}
185191

192+
#[test]
193+
#[cfg(feature = "int8-versions")]
194+
fn applies_migration_int8() {
195+
run_test(|| {
196+
let mut client = Client::connect(&db_uri(), NoTls).unwrap();
197+
let report = int8::migrations::runner().run(&mut client).unwrap();
198+
199+
let applied_migrations = report.applied_migrations();
200+
201+
assert_eq!(4, applied_migrations.len());
202+
203+
assert_eq!(20240504090241, applied_migrations[0].version());
204+
assert_eq!(20240504090301, applied_migrations[1].version());
205+
assert_eq!(20240504090322, applied_migrations[2].version());
206+
assert_eq!(20240504090343, applied_migrations[3].version());
207+
208+
client
209+
.execute(
210+
"INSERT INTO persons (name, city) VALUES ($1, $2)",
211+
&[&"John Legend", &"New York"],
212+
)
213+
.unwrap();
214+
for row in &client.query("SELECT name, city FROM persons", &[]).unwrap() {
215+
let name: String = row.get(0);
216+
let city: String = row.get(1);
217+
assert_eq!("John Legend", name);
218+
assert_eq!("New York", city);
219+
}
220+
});
221+
}
222+
186223
#[test]
187224
fn applies_migration_grouped_transaction() {
188225
run_test(|| {
@@ -282,8 +319,15 @@ mod postgres {
282319
assert_eq!("initial", migrations[0].name());
283320
assert_eq!("add_cars_table", applied_migrations[1].name());
284321

322+
#[cfg(not(feature = "int8-versions"))]
285323
assert_eq!(2959965718684201605, applied_migrations[0].checksum());
324+
#[cfg(feature = "int8-versions")]
325+
assert_eq!(13938959368620441626, applied_migrations[0].checksum());
326+
327+
#[cfg(not(feature = "int8-versions"))]
286328
assert_eq!(8238603820526370208, applied_migrations[1].checksum());
329+
#[cfg(feature = "int8-versions")]
330+
assert_eq!(5394706226941044339, applied_migrations[1].checksum());
287331
});
288332
}
289333

0 commit comments

Comments
 (0)