Skip to content

Commit 108a212

Browse files
committed
database version check
1 parent 6e01ee7 commit 108a212

File tree

8 files changed

+108
-92
lines changed

8 files changed

+108
-92
lines changed

Cargo.lock

Lines changed: 68 additions & 59 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mithril-aggregator/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ flate2 = "1.0.23"
1919
hex = "0.4.3"
2020
mithril-common = { path = "../mithril-common" }
2121
reqwest = { version = "0.11", features = ["json"] }
22-
sqlite = "0.27"
22+
semver = "1.0"
2323
serde = { version = "1.0", features = ["derive"] }
2424
serde_json = "1.0"
2525
serde_yaml = "0.9.10"
2626
slog = { version = "2.7.0", features = ["max_level_trace", "release_max_level_debug"] }
2727
slog-async = "2.7.0"
2828
slog-bunyan = "2.4.0"
2929
slog-scope = "4.4.0"
30+
sqlite = "0.28"
3031
tar = "0.4.38"
3132
thiserror = "1.0.31"
3233
tokio = { version = "1.17.0", features = ["full"] }

mithril-aggregator/src/command_args.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use clap::{Parser, Subcommand};
22
use config::{builder::DefaultState, ConfigBuilder, Map, Source, Value, ValueKind};
3+
use semver::{Version, VersionReq};
34
use slog::Level;
45
use slog_scope::debug;
56
use sqlite::Connection;
@@ -42,19 +43,20 @@ fn check_database_version(connection: &Connection) -> Result<bool, Box<dyn Error
4243
provider.create_table_if_not_exists()?;
4344
let maybe_option = provider.get_database_version()?;
4445

45-
let _database_version = match maybe_option {
46+
let version = match maybe_option {
4647
None => {
4748
let provider = VersionUpdatedProvider::new(connection);
4849
let version = DatabaseVersion {
49-
database_version: DATABASE_SCHEMATIC_VERSION.to_string(),
50+
database_version: Version::parse(DATABASE_SCHEMATIC_VERSION)?,
5051
application_type: ApplicationNodeType::new("aggregator")?,
5152
};
5253
provider.save(version)?
5354
}
5455
Some(version) => version,
5556
};
57+
let req = VersionReq::parse("~0.1").unwrap();
5658

57-
Ok(true)
59+
Ok(req.matches(&version.database_version))
5860
}
5961

6062
fn setup_genesis_dependencies(

mithril-common/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,15 @@ nom = "7.1"
2828
rand-chacha-dalek-compat = { package = "rand_chacha", version = "0.2" }
2929
rand_chacha = "0.3.1"
3030
rand_core = "0.6.3"
31+
semver = "1.0"
3132
serde = { version = "1.0", features = ["derive"] }
3233
serde_bytes = "0.11.7"
3334
serde_cbor = "0.11.2"
3435
serde_json = "1.0"
3536
serde_yaml = "0.9.10"
3637
sha2 = "0.10.2"
3738
slog = { version = "2.7.0", features = ["max_level_trace", "release_max_level_debug"] }
38-
sqlite = "0.27.0"
39+
sqlite = "0.28"
3940
thiserror = "1.0.31"
4041
tokio = { version = "1.17.0", features = ["full"] }
4142
walkdir = "2"

mithril-common/src/database/db_version.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::{collections::HashMap, error::Error, fmt::Display};
22

3+
use semver::Version;
34
use sqlite::{Connection, Row, Value};
45

56
use crate::sqlite::{HydrationError, Projection, ProjectionField, Provider, SqLiteEntity};
@@ -38,7 +39,7 @@ impl Display for ApplicationNodeType {
3839
#[derive(Debug, PartialEq, Eq)]
3940
pub struct DatabaseVersion {
4041
/// Semver of the database structure.
41-
pub database_version: String,
42+
pub database_version: Version,
4243

4344
/// Name of the application.
4445
pub application_type: ApplicationNodeType,
@@ -47,7 +48,8 @@ pub struct DatabaseVersion {
4748
impl SqLiteEntity for DatabaseVersion {
4849
fn hydrate(row: Row) -> Result<Self, HydrationError> {
4950
Ok(Self {
50-
database_version: row.get::<String, _>(0),
51+
database_version: Version::parse(&row.get::<String, _>(0))
52+
.map_err(|e| HydrationError::InvalidData(format!("{}", e)))?,
5153
application_type: ApplicationNodeType::new(&row.get::<String, _>(1))
5254
.map_err(|e| HydrationError::InvalidData(format!("{}", e)))?,
5355
})
@@ -172,7 +174,7 @@ impl<'conn> VersionUpdatedProvider<'conn> {
172174
pub fn save(&self, version: DatabaseVersion) -> Result<DatabaseVersion, Box<dyn Error>> {
173175
let params = [
174176
Value::String(format!("{}", version.application_type)),
175-
Value::String(version.database_version),
177+
Value::String(version.database_version.to_string()),
176178
];
177179
let entity = self
178180
.find(None, &params)?
@@ -249,8 +251,8 @@ where true
249251

250252
assert_eq!(
251253
r#"
252-
insert into db_version values (?, ?)
253-
on conflict on (application_type) do update set version = excluded.version
254+
insert into db_version (application_type, version) values (?, ?)
255+
on conflict (application_type) do update set version = excluded.version
254256
returning db_version.version as db_version, db_version.application_type as application_type
255257
"#,
256258
provider.get_definition(None)

mithril-common/src/sqlite/projection.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ mod tests {
102102
}
103103

104104
fn set_field(&mut self, field: ProjectionField) {
105-
let _ = self.fields.push(field);
105+
self.fields.push(field);
106106
}
107107
}
108108

mithril-common/src/sqlite/provider.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub trait Provider<'conn> {
2626
let cursor = self
2727
.get_connection()
2828
.prepare(&sql)
29-
.map_err(|e| format!("error=`{:?}, SQL=`{}`", e, &sql.replace("\n", " ").trim()))?
29+
.map_err(|e| format!("error=`{:?}, SQL=`{}`", e, &sql.replace('\n', " ").trim()))?
3030
.into_cursor()
3131
.bind(params)?;
3232
let iterator = EntityCursor::new(cursor);
@@ -42,7 +42,6 @@ pub trait Provider<'conn> {
4242
#[cfg(test)]
4343
mod tests {
4444
use super::super::{entity::HydrationError, ProjectionField, SqLiteEntity};
45-
4645
use super::*;
4746

4847
#[derive(Debug, PartialEq)]
@@ -74,7 +73,7 @@ mod tests {
7473
}
7574

7675
fn set_field(&mut self, field: ProjectionField) {
77-
let _ = self.fields.push(field);
76+
self.fields.push(field);
7877
}
7978
}
8079

@@ -179,8 +178,8 @@ returning {projection}
179178
"
180179
drop table if exists provider_test;
181180
create table provider_test(text_data text not null primary key, real_data real not null, integer_data integer not null, maybe_null integer);
182-
insert into provider_test(text_data, real_data, integer_data, maybe_null) values ('row 1', 3.14, -52, null);
183-
insert into provider_test(text_data, real_data, integer_data, maybe_null) values ('row 2', 2.72, 1789, 0);
181+
insert into provider_test(text_data, real_data, integer_data, maybe_null) values ('row 1', 1.23, -52, null);
182+
insert into provider_test(text_data, real_data, integer_data, maybe_null) values ('row 2', 2.34, 1789, 0);
184183
",
185184
)
186185
.unwrap();
@@ -198,7 +197,7 @@ returning {projection}
198197
assert_eq!(
199198
TestEntity {
200199
text_data: "row 1".to_string(),
201-
real_data: 3.14,
200+
real_data: 1.23,
202201
integer_data: -52,
203202
maybe_null: None
204203
},
@@ -210,7 +209,7 @@ returning {projection}
210209
assert_eq!(
211210
TestEntity {
212211
text_data: "row 2".to_string(),
213-
real_data: 2.72,
212+
real_data: 2.34,
214213
integer_data: 1789,
215214
maybe_null: Some(0)
216215
},
@@ -232,7 +231,7 @@ returning {projection}
232231
assert_eq!(
233232
TestEntity {
234233
text_data: "row 2".to_string(),
235-
real_data: 2.72,
234+
real_data: 2.34,
236235
integer_data: 1789,
237236
maybe_null: Some(0)
238237
},
@@ -245,18 +244,15 @@ returning {projection}
245244
pub fn test_parameters() {
246245
let provider = TestEntityProvider::new(init_database());
247246
let mut cursor = provider
248-
.find(
249-
Some("text_data like ?"),
250-
&[Value::String("%1".to_string())].to_vec(),
251-
)
247+
.find(Some("text_data like ?"), &[Value::String("%1".to_string())])
252248
.unwrap();
253249
let entity = cursor
254250
.next()
255251
.expect("there shoud be one result, none returned");
256252
assert_eq!(
257253
TestEntity {
258254
text_data: "row 1".to_string(),
259-
real_data: 3.14,
255+
real_data: 1.23,
260256
integer_data: -52,
261257
maybe_null: None
262258
},

mithril-common/src/store/adapter/sqlite_adapter.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,10 @@ where
101101
sql: String,
102102
key: &K,
103103
) -> Result<Statement> {
104-
let statement = connection
104+
let mut statement = connection
105105
.prepare(sql)
106-
.map_err(|e| AdapterError::InitializationError(e.into()))?
106+
.map_err(|e| AdapterError::InitializationError(e.into()))?;
107+
statement
107108
.bind::<&str>(1, self.get_hash_from_key(key)?.as_str())
108109
.map_err(|e| AdapterError::InitializationError(e.into()))?;
109110

@@ -165,11 +166,14 @@ where
165166
})?;
166167
let mut statement = connection
167168
.prepare(sql)
168-
.map_err(|e| AdapterError::InitializationError(e.into()))?
169+
.map_err(|e| AdapterError::InitializationError(e.into()))?;
170+
statement
169171
.bind::<&str>(1, self.get_hash_from_key(key)?.as_str())
170-
.map_err(|e| AdapterError::InitializationError(e.into()))?
172+
.map_err(|e| AdapterError::InitializationError(e.into()))?;
173+
statement
171174
.bind::<&str>(2, self.serialize_key(key)?.as_str())
172-
.map_err(|e| AdapterError::InitializationError(e.into()))?
175+
.map_err(|e| AdapterError::InitializationError(e.into()))?;
176+
statement
173177
.bind::<&str>(3, value.as_str())
174178
.map_err(|e| AdapterError::InitializationError(e.into()))?;
175179
let _ = statement
@@ -215,12 +219,13 @@ where
215219
"select cast(key as text) as key, cast(value as text) as value from {} order by ROWID desc limit ?1",
216220
self.table
217221
);
218-
let cursor = connection
222+
let mut statement = connection
219223
.prepare(sql)
220-
.map_err(|e| AdapterError::InitializationError(e.into()))?
224+
.map_err(|e| AdapterError::InitializationError(e.into()))?;
225+
statement
221226
.bind::<i64>(1, how_many as i64)
222-
.map_err(|e| AdapterError::InitializationError(e.into()))?
223-
.into_cursor();
227+
.map_err(|e| AdapterError::InitializationError(e.into()))?;
228+
let cursor = statement.into_cursor();
224229

225230
let results = cursor
226231
.map(|row| {

0 commit comments

Comments
 (0)