#[macro_use]
use macros;
use std::collections::HashMap;
use std::collections::HashSet;
use std::rc::Rc;
use std::cell::RefCell;
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;
use mysql::Value;
use mysql::Error;
use mysql::value;
use mysql::prelude::FromValue;
use mysql::Row;
use mysql::prelude::GenericConnection;
use meta::OrmMeta;
use meta::EntityMeta;
use meta::FieldMeta;
use meta::Cascade;
use value::FieldValue;
pub type EntityInnerPointer = Rc<RefCell<EntityInner>>;
pub struct EntityInner {
pub orm_meta: &'static OrmMeta,
pub meta: &'static EntityMeta,
pub field_map: HashMap<String, FieldValue>,
pub cascade: Option<Cascade>,
}
impl EntityInner {
pub fn new(meta: &'static EntityMeta, orm_meta: &'static OrmMeta) -> EntityInner {
EntityInner {
orm_meta: orm_meta,
meta: meta,
field_map: HashMap::new(),
cascade: None, }
}
pub fn default(meta: &'static EntityMeta, orm_meta: &'static OrmMeta) -> EntityInner {
let field_map: HashMap<String, FieldValue> = meta.field_vec
.iter()
.map(|field| {
let field_meta = meta.field_map.get(field).expect(expect!().as_ref());
let default_value = FieldValue::default(field_meta);
(field.to_string(), default_value)
})
.collect::<HashMap<_, _>>();
EntityInner {
orm_meta: orm_meta,
meta: meta,
field_map: field_map,
cascade: None, }
}
pub fn new_pointer(meta: &'static EntityMeta,
orm_meta: &'static OrmMeta)
-> EntityInnerPointer {
Rc::new(RefCell::new(EntityInner::new(meta, orm_meta)))
}
pub fn default_pointer(meta: &'static EntityMeta,
orm_meta: &'static OrmMeta)
-> EntityInnerPointer {
Rc::new(RefCell::new(EntityInner::default(meta, orm_meta)))
}
pub fn get_addr(&self) -> u64 {
self as *const EntityInner as u64
}
pub fn get_id_value(&self) -> Value {
self.field_map.get("id").map_or(Value::NULL, |value| value.as_value())
}
pub fn get_id_u64(&self) -> Option<u64> {
self.field_map.get("id").map(|value| value::from_value::<u64>(value.as_value()))
}
}
impl EntityInner {
pub fn get_value<V>(&self, field: &str) -> V
where V: FromValue
{
let v = self.field_map.get(field).expect(expect!().as_ref()).as_value();
value::from_value(v)
}
pub fn set_value<V>(&mut self, field: &str, value: V)
where Value: From<V>
{
let v = Value::from(value);
let field_value = FieldValue::from(v);
self.field_map.insert(field.to_string(), field_value);
}
pub fn set_value_null(&mut self, field: &str) {
self.field_map.insert(field.to_string(), FieldValue::null());
}
pub fn is_value_null(&self, field: &str) -> bool {
self.field_map.get(field).map_or(false, |v| v.as_value() == Value::NULL)
}
}
impl EntityInner {
pub fn get_entity(&self, field: &str) -> Option<EntityInnerPointer> {
let opt = self.field_map.get(field);
if opt.is_some() {
return opt.unwrap().as_entity();
}
unreachable!();
}
pub fn set_entity(&mut self, field: &str, opt: Option<EntityInnerPointer>) {
match self.meta.field_map.get(field).expect(expect!().as_ref()) {
&FieldMeta::Refer { .. } => {}
&FieldMeta::Pointer { .. } => self.set_entity_pointer(field, opt.clone()),
&FieldMeta::OneToOne { .. } => self.set_entity_one_one(field, opt.clone()),
_ => unreachable!(),
}
let a = self;
let field_value = FieldValue::from(opt);
a.field_map.insert(field.to_string(), field_value);
}
fn set_entity_pointer(&mut self, field: &str, opt: Option<EntityInnerPointer>) {
let a = self;
let field_meta = a.meta.field_map.get(field).expect(expect!().as_ref());
let (left, right) = field_meta.get_refer_lr();
if opt.is_none() {
a.field_map.insert(left, FieldValue::null());
} else {
let b_rc = opt.unwrap();
let b_id = b_rc.borrow()
.field_map
.get(&right)
.map_or(FieldValue::null(), |v| v.clone());
a.field_map.insert(left, b_id);
}
}
fn set_entity_one_one(&mut self, field: &str, opt: Option<EntityInnerPointer>) {
let a = self;
let field_meta = a.meta.field_map.get(field).expect(expect!().as_ref());
let (left, right) = field_meta.get_refer_lr();
let old_b = a.get_entity(field);
if opt.is_some() {
let b_rc = opt.unwrap();
let b_id = b_rc.borrow().field_map.get(&right).map_or(Value::NULL, |v| v.as_value());
a.field_map.insert(left, FieldValue::from(b_id));
}
if old_b.is_some() {
let old_b = old_b.unwrap();
old_b.borrow_mut().field_map.insert(right.clone(), FieldValue::null());
}
}
}
impl EntityInner {
pub fn get_vec(&self, field: &str) -> Vec<EntityInnerPointer> {
let opt = self.field_map.get(field);
if opt.is_some() {
return opt.unwrap().as_vec();
}
unreachable!();
}
pub fn set_vec(&mut self, field: &str, vec: Vec<EntityInnerPointer>) {
let a = self;
let field_meta = a.meta.field_map.get(field).expect(expect!().as_ref());
let (left, right) = field_meta.get_refer_lr();
let old_vec = a.get_vec(field);
for old_b_rc in old_vec.iter() {
old_b_rc.borrow_mut().field_map.insert(right.to_string(), FieldValue::null());
}
let a_id = a.field_map.get(&left).map_or(FieldValue::null(), |v| v.clone());
for b_rc in vec.iter() {
b_rc.borrow_mut().field_map.insert(right.to_string(), a_id.clone());
}
a.field_map.insert(field.to_string(), FieldValue::from(vec));
}
pub fn is_vec_null(&self, field: &str) -> bool {
!self.field_map.contains_key(field)
}
}
impl EntityInner {
pub fn to_json(&self) -> String {
let content = self.meta
.field_vec
.iter()
.filter_map(|field| {
let field_meta = self.meta.field_map.get(field).unwrap();
self.field_map
.get(field)
.map(|value| format!("{}: {}", field, value.to_json(field_meta)))
})
.collect::<Vec<_>>()
.join(", ");
format!("{{{}}}", content)
}
}
impl fmt::Debug for EntityInner {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let entity = &self.meta.entity_name;
write!(f, "{}", self.to_json())
}
}
impl PartialEq for EntityInner {
fn eq(&self, other: &EntityInner) -> bool {
self.get_addr() == other.get_addr()
}
}
impl Hash for EntityInner {
fn hash<H: Hasher>(&self, state: &mut H) {
self.get_addr().hash(state);
}
}
pub trait Entity {
fn orm_meta() -> &'static OrmMeta;
fn meta() -> &'static EntityMeta;
fn default() -> Self;
fn new() -> Self;
fn from_inner(inner: EntityInnerPointer) -> Self;
fn inner(&self) -> EntityInnerPointer;
fn debug(&self) {
let inner = self.inner();
let inner = inner.borrow();
log!("[{}] {}", Self::meta().entity_name, inner.to_json())
}
fn do_inner<F, R>(&self, cb: F) -> R
where F: FnOnce(&EntityInner) -> R
{
let rc = self.inner();
let inner = rc.borrow();
cb(&inner)
}
fn do_inner_mut<F, R>(&self, cb: F) -> R
where F: FnOnce(&mut EntityInner) -> R
{
let rc = self.inner();
let mut inner = rc.borrow_mut();
cb(&mut inner)
}
fn inner_set_value<V>(&self, field: &str, value: V)
where Value: From<V>
{
self.do_inner_mut(|mut inner| inner.set_value(field, value))
}
fn inner_get_value<V>(&self, field: &str) -> V
where V: FromValue
{
self.do_inner(|inner| inner.get_value::<V>(field))
}
fn inner_set_value_null(&self, field: &str) {
self.do_inner_mut(|mut inner| inner.set_value_null(field))
}
fn inner_is_value_null(&self, field: &str) -> bool {
self.do_inner(|inner| inner.is_value_null(field))
}
fn inner_set_entity<E>(&self, field: &str, entity: &E)
where E: Entity
{
self.do_inner_mut(|mut inner| inner.set_entity(field, Some(entity.inner())))
}
fn inner_get_entity<E>(&self, field: &str) -> E
where E: Entity
{
self.do_inner(|inner| E::from_inner(inner.get_entity(field).unwrap()))
}
fn inner_set_entity_null(&self, field: &str) {
self.do_inner_mut(|mut inner| inner.set_entity(field, None))
}
fn inner_is_entity_null(&self, field: &str) -> bool {
self.do_inner(|inner| inner.get_entity(field).is_none())
}
fn inner_set_vec<E>(&self, field: &str, vec: Vec<E>)
where E: Entity
{
let vec = vec.iter().map(E::inner).collect::<Vec<_>>();
self.do_inner_mut(|mut inner| inner.set_vec(field, vec))
}
fn inner_get_vec<E>(&self, field: &str) -> Vec<E>
where E: Entity
{
self.do_inner(|inner| inner.get_vec(field).into_iter().map(E::from_inner).collect())
}
fn inner_is_vec_null(&self, field: &str) -> bool {
self.do_inner(|inner| inner.is_vec_null(field))
}
}