Describe the default core schema, v1 (:db.schema/core). r=nalexander

This commit is contained in:
Richard Newman 2017-12-20 15:26:45 -08:00
parent 4acc6d0658
commit 3d28949add
5 changed files with 60 additions and 5 deletions

View file

@ -35,6 +35,9 @@ pub const TX0: i64 = 0x10000000;
/// This is the start of the :db.part/user partition.
pub const USER0: i64 = 0x10000;
// Corresponds to the version of the :db.schema/core vocabulary.
pub const CORE_SCHEMA_VERSION: u32 = 1;
lazy_static! {
static ref V1_IDENTS: Vec<(symbols::NamespacedKeyword, i64)> = {
vec![(ns_keyword!("db", "ident"), entids::DB_IDENT),
@ -76,6 +79,7 @@ lazy_static! {
(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),
(ns_keyword!("db.schema", "core"), entids::DB_SCHEMA_CORE),
]
};
@ -86,6 +90,26 @@ lazy_static! {
]
};
static ref V1_CORE_SCHEMA: Vec<(symbols::NamespacedKeyword)> = {
vec![(ns_keyword!("db", "ident")),
(ns_keyword!("db.install", "partition")),
(ns_keyword!("db.install", "valueType")),
(ns_keyword!("db.install", "attribute")),
(ns_keyword!("db", "txInstant")),
(ns_keyword!("db", "valueType")),
(ns_keyword!("db", "cardinality")),
(ns_keyword!("db", "doc")),
(ns_keyword!("db", "unique")),
(ns_keyword!("db", "isComponent")),
(ns_keyword!("db", "index")),
(ns_keyword!("db", "fulltext")),
(ns_keyword!("db", "noHistory")),
(ns_keyword!("db.alter", "attribute")),
(ns_keyword!("db.schema", "version")),
(ns_keyword!("db.schema", "attribute")),
]
};
static ref V1_SYMBOLIC_SCHEMA: Value = {
let s = r#"
{:db/ident {:db/valueType :db.type/keyword
@ -149,6 +173,27 @@ fn idents_to_assertions(idents: &[(symbols::NamespacedKeyword, i64)]) -> Vec<Val
.collect()
}
/// Convert an ident list into [:db/add :db.schema/core :db.schema/attribute IDENT] `Value` instances.
fn schema_attrs_to_assertions(version: u32, idents: &[symbols::NamespacedKeyword]) -> Vec<Value> {
let schema_core = Value::NamespacedKeyword(ns_keyword!("db.schema", "core"));
let schema_attr = Value::NamespacedKeyword(ns_keyword!("db.schema", "attribute"));
let schema_version = Value::NamespacedKeyword(ns_keyword!("db.schema", "version"));
idents
.into_iter()
.map(|ident| {
let value = Value::NamespacedKeyword(ident.clone());
Value::Vector(vec![values::DB_ADD.clone(),
schema_core.clone(),
schema_attr.clone(),
value])
})
.chain(::std::iter::once(Value::Vector(vec![values::DB_ADD.clone(),
schema_core.clone(),
schema_version,
Value::Integer(version as i64)])))
.collect()
}
/// Convert {:ident {:key :value ...} ...} to
/// vec![(symbols::NamespacedKeyword(:ident), symbols::NamespacedKeyword(:key), TypedValue(:value)), ...].
///
@ -250,6 +295,7 @@ pub fn bootstrap_entities() -> Vec<Entity> {
let bootstrap_assertions: Value = Value::Vector([
symbolic_schema_to_assertions(&V1_SYMBOLIC_SCHEMA).unwrap(),
idents_to_assertions(&V1_IDENTS[..]),
schema_attrs_to_assertions(CORE_SCHEMA_VERSION, &V1_CORE_SCHEMA),
].concat());
// Failure here is a coding error (since the inputs are fixed), not a runtime error.

View file

@ -1217,12 +1217,12 @@ mod tests {
// Does not include :db/txInstant.
let datoms = debug::datoms_after(&conn, &db.schema, 0).unwrap();
assert_eq!(datoms.0.len(), 76);
assert_eq!(datoms.0.len(), 94);
// 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(), 77);
assert_eq!(transactions.0[0].0.len(), 95);
let mut parts = db.partition_map;

View file

@ -56,6 +56,7 @@ 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;
pub const DB_SCHEMA_CORE: Entid = 40;
/// Return `false` if the given attribute will not change the metadata: recognized idents, schema,
/// partitions in the partition map.

View file

@ -57,6 +57,14 @@ pub use bootstrap::{
pub use schema::AttributeBuilder;
pub use bootstrap::{
CORE_SCHEMA_VERSION,
};
pub use entids::{
DB_SCHEMA_CORE,
};
pub use db::{
TypedSQLValue,
new_connection,

View file

@ -60,7 +60,7 @@ fn test_rel() {
let end = time::PreciseTime::now();
// This will need to change each time we add a default ident.
assert_eq!(39, results.len());
assert_eq!(40, results.len());
// Every row is a pair of a Ref and a Keyword.
if let QueryResults::Rel(ref rel) = results {
@ -168,7 +168,7 @@ fn test_coll() {
.expect("Query failed");
let end = time::PreciseTime::now();
assert_eq!(39, results.len());
assert_eq!(40, results.len());
if let QueryResults::Coll(ref coll) = results {
assert!(coll.iter().all(|item| item.matches_type(ValueType::Ref)));
@ -247,7 +247,7 @@ fn test_instants_and_uuids() {
Some(TypedValue::Uuid(u)),
Some(TypedValue::Instant(t)),
None) => {
assert!(e > 39); // There are at least this many entities in the store.
assert!(e > 40); // There are at least this many entities in the store.
assert_eq!(Ok(u), Uuid::from_str("cf62d552-6569-4d1b-b667-04703041dfc4"));
assert!(t > start);
},