Part 6: extend db to support Uuid.

This commit is contained in:
Richard Newman 2017-04-26 17:28:33 -07:00
parent ab3600e288
commit 041b29cadf
3 changed files with 22 additions and 1 deletions

View file

@ -26,7 +26,14 @@ use rusqlite::limits::Limit;
use ::{repeat_values, to_namespaced_keyword};
use bootstrap;
use edn::types::Value;
use edn::{
DateTime,
UTC,
Uuid,
Value,
};
use entids;
use mentat_core::{
attribute,
@ -350,6 +357,15 @@ impl TypedSQLValue for TypedValue {
(5, rusqlite::types::Value::Integer(x)) => Ok(TypedValue::Long(x)),
(5, rusqlite::types::Value::Real(x)) => Ok(TypedValue::Double(x.into())),
(10, rusqlite::types::Value::Text(x)) => Ok(TypedValue::String(Rc::new(x))),
(11, rusqlite::types::Value::Blob(x)) => {
let u = Uuid::from_bytes(x.as_slice());
if u.is_err() {
// Rather than exposing Uuid's ParseError…
bail!(ErrorKind::BadSQLValuePair(rusqlite::types::Value::Blob(x),
value_type_tag));
}
Ok(TypedValue::Uuid(u.unwrap()))
},
(13, rusqlite::types::Value::Text(x)) => {
to_namespaced_keyword(&x).map(|k| TypedValue::Keyword(Rc::new(k)))
},
@ -368,6 +384,7 @@ impl TypedSQLValue for TypedValue {
match value {
&Value::Boolean(x) => Some(TypedValue::Boolean(x)),
&Value::Integer(x) => Some(TypedValue::Long(x)),
&Value::Uuid(x) => Some(TypedValue::Uuid(x)),
&Value::Float(ref x) => Some(TypedValue::Double(x.clone())),
&Value::Text(ref x) => Some(TypedValue::String(Rc::new(x.clone()))),
&Value::NamespacedKeyword(ref x) => Some(TypedValue::Keyword(Rc::new(x.clone()))),
@ -384,6 +401,7 @@ impl TypedSQLValue for TypedValue {
&TypedValue::Long(x) => (rusqlite::types::Value::Integer(x).into(), 5),
&TypedValue::Double(x) => (rusqlite::types::Value::Real(x.into_inner()).into(), 5),
&TypedValue::String(ref x) => (rusqlite::types::ValueRef::Text(x.as_str()).into(), 10),
&TypedValue::Uuid(ref u) => (rusqlite::types::Value::Blob(u.as_bytes().to_vec()).into(), 11),
&TypedValue::Keyword(ref x) => (rusqlite::types::ValueRef::Text(&x.to_string()).into(), 13),
}
}
@ -396,6 +414,7 @@ impl TypedSQLValue for TypedValue {
&TypedValue::Long(x) => (Value::Integer(x), ValueType::Long),
&TypedValue::Double(x) => (Value::Float(x), ValueType::Double),
&TypedValue::String(ref x) => (Value::Text(x.as_ref().clone()), ValueType::String),
&TypedValue::Uuid(ref u) => (Value::Uuid(u.clone()), ValueType::Uuid),
&TypedValue::Keyword(ref x) => (Value::NamespacedKeyword(x.as_ref().clone()), ValueType::Keyword),
}
}

View file

@ -120,6 +120,7 @@ pub fn update_schema_map_from_entid_triples<U>(schema_map: &mut SchemaMap, asser
TypedValue::Ref(entids::DB_TYPE_DOUBLE) => { builder.value_type(ValueType::Double); },
TypedValue::Ref(entids::DB_TYPE_LONG) => { builder.value_type(ValueType::Long); },
TypedValue::Ref(entids::DB_TYPE_STRING) => { builder.value_type(ValueType::String); },
TypedValue::Ref(entids::DB_TYPE_UUID) => { builder.value_type(ValueType::Uuid); },
TypedValue::Ref(entids::DB_TYPE_KEYWORD) => { builder.value_type(ValueType::Keyword); },
_ => bail!(ErrorKind::BadSchemaAssertion(format!("Expected [... :db/valueType :db.type/*] but got [... :db/valueType {:?}] for entid {} and attribute {}", value, entid, attr)))
}

View file

@ -240,6 +240,7 @@ impl SchemaTypeChecking for Schema {
(&ValueType::Long, tv @ TypedValue::Long(_)) => Ok(tv),
(&ValueType::Double, tv @ TypedValue::Double(_)) => Ok(tv),
(&ValueType::String, tv @ TypedValue::String(_)) => Ok(tv),
(&ValueType::Uuid, tv @ TypedValue::Uuid(_)) => Ok(tv),
(&ValueType::Keyword, tv @ TypedValue::Keyword(_)) => Ok(tv),
// Ref coerces a little: we interpret some things depending on the schema as a Ref.
(&ValueType::Ref, TypedValue::Long(x)) => Ok(TypedValue::Ref(x)),