Part 1: flatten V2 schema into V1. Add UUID and URI.
Bump expected ident and bootstrap datom count in tests.
This commit is contained in:
parent
407dd7a07a
commit
044635e8bc
4 changed files with 34 additions and 58 deletions
|
@ -61,6 +61,8 @@ lazy_static! {
|
|||
(ns_keyword!("db.type", "long"), entids::DB_TYPE_LONG),
|
||||
(ns_keyword!("db.type", "double"), entids::DB_TYPE_DOUBLE),
|
||||
(ns_keyword!("db.type", "string"), entids::DB_TYPE_STRING),
|
||||
(ns_keyword!("db.type", "uuid"), entids::DB_TYPE_UUID),
|
||||
(ns_keyword!("db.type", "uri"), entids::DB_TYPE_URI),
|
||||
(ns_keyword!("db.type", "boolean"), entids::DB_TYPE_BOOLEAN),
|
||||
(ns_keyword!("db.type", "instant"), entids::DB_TYPE_INSTANT),
|
||||
(ns_keyword!("db.type", "bytes"), entids::DB_TYPE_BYTES),
|
||||
|
@ -69,16 +71,11 @@ lazy_static! {
|
|||
(ns_keyword!("db.unique", "value"), entids::DB_UNIQUE_VALUE),
|
||||
(ns_keyword!("db.unique", "identity"), entids::DB_UNIQUE_IDENTITY),
|
||||
(ns_keyword!("db", "doc"), entids::DB_DOC),
|
||||
(ns_keyword!("db.schema", "version"), entids::DB_SCHEMA_VERSION),
|
||||
(ns_keyword!("db.schema", "attribute"), entids::DB_SCHEMA_ATTRIBUTE),
|
||||
]
|
||||
};
|
||||
|
||||
static ref V2_IDENTS: Vec<(symbols::NamespacedKeyword, i64)> = {
|
||||
[(*V1_IDENTS).clone(),
|
||||
vec![(ns_keyword!("db.schema", "version"), entids::DB_SCHEMA_VERSION),
|
||||
(ns_keyword!("db.schema", "attribute"), entids::DB_SCHEMA_ATTRIBUTE),
|
||||
]].concat()
|
||||
};
|
||||
|
||||
static ref V1_PARTS: Vec<(symbols::NamespacedKeyword, i64, i64)> = {
|
||||
vec![(ns_keyword!("db.part", "db"), 0, (1 + V1_IDENTS.len()) as i64),
|
||||
(ns_keyword!("db.part", "user"), 0x10000, 0x10000),
|
||||
|
@ -86,13 +83,6 @@ lazy_static! {
|
|||
]
|
||||
};
|
||||
|
||||
static ref V2_PARTS: Vec<(symbols::NamespacedKeyword, i64, i64)> = {
|
||||
vec![(ns_keyword!("db.part", "db"), 0, (1 + V2_IDENTS.len()) as i64),
|
||||
(ns_keyword!("db.part", "user"), 0x10000, 0x10000),
|
||||
(ns_keyword!("db.part", "tx"), TX0, TX0),
|
||||
]
|
||||
};
|
||||
|
||||
static ref V1_SYMBOLIC_SCHEMA: Value = {
|
||||
let s = r#"
|
||||
{:db/ident {:db/valueType :db.type/keyword
|
||||
|
@ -126,16 +116,8 @@ lazy_static! {
|
|||
:db/fulltext {:db/valueType :db.type/boolean
|
||||
:db/cardinality :db.cardinality/one}
|
||||
:db/noHistory {:db/valueType :db.type/boolean
|
||||
:db/cardinality :db.cardinality/one}}"#;
|
||||
edn::parse::value(s)
|
||||
.map(|v| v.without_spans())
|
||||
.map_err(|_| ErrorKind::BadBootstrapDefinition("Unable to parse V1_SYMBOLIC_SCHEMA".into()))
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
static ref V2_SYMBOLIC_SCHEMA: Value = {
|
||||
let s = r#"
|
||||
{:db.alter/attribute {:db/valueType :db.type/ref
|
||||
:db/cardinality :db.cardinality/one}
|
||||
:db.alter/attribute {:db/valueType :db.type/ref
|
||||
:db/cardinality :db.cardinality/many}
|
||||
:db.schema/version {:db/valueType :db.type/long
|
||||
:db/cardinality :db.cardinality/one}
|
||||
|
@ -146,13 +128,9 @@ lazy_static! {
|
|||
:db/index true
|
||||
:db/unique :db.unique/value
|
||||
:db/cardinality :db.cardinality/many}}"#;
|
||||
let right = edn::parse::value(s)
|
||||
edn::parse::value(s)
|
||||
.map(|v| v.without_spans())
|
||||
.map_err(|_| ErrorKind::BadBootstrapDefinition("Unable to parse V2_SYMBOLIC_SCHEMA".into()))
|
||||
.unwrap();
|
||||
|
||||
edn::utils::merge(&V1_SYMBOLIC_SCHEMA, &right)
|
||||
.ok_or(ErrorKind::BadBootstrapDefinition("Unable to parse V2_SYMBOLIC_SCHEMA".into()))
|
||||
.map_err(|_| ErrorKind::BadBootstrapDefinition("Unable to parse V1_SYMBOLIC_SCHEMA".into()))
|
||||
.unwrap()
|
||||
};
|
||||
}
|
||||
|
@ -248,27 +226,27 @@ fn symbolic_schema_to_assertions(symbolic_schema: &Value) -> Result<Vec<Value>>
|
|||
}
|
||||
|
||||
pub fn bootstrap_partition_map() -> PartitionMap {
|
||||
V2_PARTS[..].iter()
|
||||
V1_PARTS[..].iter()
|
||||
.map(|&(ref part, start, index)| (part.to_string(), Partition::new(start, index)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn bootstrap_ident_map() -> IdentMap {
|
||||
V2_IDENTS[..].iter()
|
||||
V1_IDENTS[..].iter()
|
||||
.map(|&(ref ident, entid)| (ident.clone(), entid))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn bootstrap_schema() -> Schema {
|
||||
let ident_map = bootstrap_ident_map();
|
||||
let bootstrap_triples = symbolic_schema_to_triples(&ident_map, &V2_SYMBOLIC_SCHEMA).unwrap();
|
||||
let bootstrap_triples = symbolic_schema_to_triples(&ident_map, &V1_SYMBOLIC_SCHEMA).unwrap();
|
||||
Schema::from_ident_map_and_triples(ident_map, bootstrap_triples).unwrap()
|
||||
}
|
||||
|
||||
pub fn bootstrap_entities() -> Vec<Entity> {
|
||||
let bootstrap_assertions: Value = Value::Vector([
|
||||
symbolic_schema_to_assertions(&V2_SYMBOLIC_SCHEMA).unwrap(),
|
||||
idents_to_assertions(&V2_IDENTS[..]),
|
||||
symbolic_schema_to_assertions(&V1_SYMBOLIC_SCHEMA).unwrap(),
|
||||
idents_to_assertions(&V1_IDENTS[..]),
|
||||
].concat());
|
||||
|
||||
// Failure here is a coding error (since the inputs are fixed), not a runtime error.
|
||||
|
|
16
db/src/db.rs
16
db/src/db.rs
|
@ -72,10 +72,8 @@ pub fn new_connection<T>(uri: T) -> rusqlite::Result<rusqlite::Connection> where
|
|||
|
||||
/// Version history:
|
||||
///
|
||||
/// 1: initial schema.
|
||||
/// 2: added :db.schema/version and /attribute in bootstrap; assigned idents 36 and 37, so we bump
|
||||
/// the part range here; tie bootstrapping to the SQLite user_version.
|
||||
pub const CURRENT_VERSION: i32 = 2;
|
||||
/// 1: initial Mentat schema.
|
||||
pub const CURRENT_VERSION: i32 = 1;
|
||||
|
||||
/// MIN_SQLITE_VERSION should be changed when there's a new minimum version of sqlite required
|
||||
/// for the project to work.
|
||||
|
@ -93,9 +91,9 @@ fn to_bool_ref(x: bool) -> &'static bool {
|
|||
}
|
||||
|
||||
lazy_static! {
|
||||
/// SQL statements to be executed, in order, to create the Mentat SQL schema (version 2).
|
||||
/// SQL statements to be executed, in order, to create the Mentat SQL schema (version 1).
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
static ref V2_STATEMENTS: Vec<&'static str> = { vec![
|
||||
static ref V1_STATEMENTS: Vec<&'static str> = { vec![
|
||||
r#"CREATE TABLE datoms (e INTEGER NOT NULL, a SMALLINT NOT NULL, v BLOB NOT NULL, tx INTEGER NOT NULL,
|
||||
value_type_tag SMALLINT NOT NULL,
|
||||
index_avet TINYINT NOT NULL DEFAULT 0, index_vaet TINYINT NOT NULL DEFAULT 0,
|
||||
|
@ -203,7 +201,7 @@ fn get_user_version(conn: &rusqlite::Connection) -> Result<i32> {
|
|||
pub fn create_current_version(conn: &mut rusqlite::Connection) -> Result<DB> {
|
||||
let tx = conn.transaction()?;
|
||||
|
||||
for statement in (&V2_STATEMENTS).iter() {
|
||||
for statement in (&V1_STATEMENTS).iter() {
|
||||
tx.execute(statement, &[])?;
|
||||
}
|
||||
|
||||
|
@ -1173,12 +1171,12 @@ mod tests {
|
|||
|
||||
// Does not include :db/txInstant.
|
||||
let datoms = debug::datoms_after(&conn, &db.schema, 0).unwrap();
|
||||
assert_eq!(datoms.0.len(), 74);
|
||||
assert_eq!(datoms.0.len(), 76);
|
||||
|
||||
// Includes :db/txInstant.
|
||||
let transactions = debug::transactions_after(&conn, &db.schema, 0).unwrap();
|
||||
assert_eq!(transactions.0.len(), 1);
|
||||
assert_eq!(transactions.0[0].0.len(), 75);
|
||||
assert_eq!(transactions.0[0].0.len(), 77);
|
||||
|
||||
let test_conn = TestConn {
|
||||
sqlite: conn,
|
||||
|
|
|
@ -44,18 +44,18 @@ pub const DB_TYPE_KEYWORD: Entid = 24;
|
|||
pub const DB_TYPE_LONG: Entid = 25;
|
||||
pub const DB_TYPE_DOUBLE: Entid = 26;
|
||||
pub const DB_TYPE_STRING: Entid = 27;
|
||||
pub const DB_TYPE_BOOLEAN: Entid = 28;
|
||||
pub const DB_TYPE_INSTANT: Entid = 29;
|
||||
pub const DB_TYPE_BYTES: Entid = 30;
|
||||
pub const DB_CARDINALITY_ONE: Entid = 31;
|
||||
pub const DB_CARDINALITY_MANY: Entid = 32;
|
||||
pub const DB_UNIQUE_VALUE: Entid = 33;
|
||||
pub const DB_UNIQUE_IDENTITY: Entid = 34;
|
||||
pub const DB_DOC: Entid = 35;
|
||||
|
||||
// Added in SQL schema v2.
|
||||
pub const DB_SCHEMA_VERSION: Entid = 36;
|
||||
pub const DB_SCHEMA_ATTRIBUTE: Entid = 37;
|
||||
pub const DB_TYPE_UUID: Entid = 28;
|
||||
pub const DB_TYPE_URI: Entid = 29;
|
||||
pub const DB_TYPE_BOOLEAN: Entid = 30;
|
||||
pub const DB_TYPE_INSTANT: Entid = 31;
|
||||
pub const DB_TYPE_BYTES: Entid = 32;
|
||||
pub const DB_CARDINALITY_ONE: Entid = 33;
|
||||
pub const DB_CARDINALITY_MANY: Entid = 34;
|
||||
pub const DB_UNIQUE_VALUE: Entid = 35;
|
||||
pub const DB_UNIQUE_IDENTITY: Entid = 36;
|
||||
pub const DB_DOC: Entid = 37;
|
||||
pub const DB_SCHEMA_VERSION: Entid = 38;
|
||||
pub const DB_SCHEMA_ATTRIBUTE: Entid = 39;
|
||||
|
||||
/// Return `false` if the given attribute will not change the metadata: recognized idents, schema,
|
||||
/// partitions in the partition map.
|
||||
|
|
|
@ -46,7 +46,7 @@ fn test_rel() {
|
|||
let end = time::PreciseTime::now();
|
||||
|
||||
// This will need to change each time we add a default ident.
|
||||
assert_eq!(37, results.len());
|
||||
assert_eq!(39, results.len());
|
||||
|
||||
// Every row is a pair of a Ref and a Keyword.
|
||||
if let QueryResults::Rel(ref rel) = results {
|
||||
|
@ -154,7 +154,7 @@ fn test_coll() {
|
|||
.expect("Query failed");
|
||||
let end = time::PreciseTime::now();
|
||||
|
||||
assert_eq!(37, results.len());
|
||||
assert_eq!(39, results.len());
|
||||
|
||||
if let QueryResults::Coll(ref coll) = results {
|
||||
assert!(coll.iter().all(|item| item.matches_type(ValueType::Ref)));
|
||||
|
|
Loading…
Reference in a new issue