mem-query 0.0.1

Relational algebra interface for Rust collections
use super::{RelationImpl,Relation,Queryable,SelfQuery,Insert,QueryOutput,Delete};
use tylisp::{defun, ops::Ret};
use crate::{
    query::{QueryPlanImpl, request::QueryRequest, filter::QueryFilter},
    header::Header,
    record::Record,
    transaction::{UndoLog, RevertableOp},
};

#[derive(Clone,Debug,Default,Hash,Eq,PartialEq,Ord,PartialOrd)]
pub struct OpaqueRel<R>(R);

impl<R> OpaqueRel<R> {
    pub fn new(rel: R) -> Self {
        OpaqueRel(rel)
    }
}

impl<R:RelationImpl> RelationImpl for OpaqueRel<R> {
    type Cols = R::Cols;
    type FastCols = R::FastCols;
    type Planner = OpaquePlanner; 
}

impl<'a, R:QueryOutput<'a>> QueryOutput<'a> for OpaqueRel<R>
    where Self: RelationImpl<Cols=R::Cols>
{
    type QueryRow = R::QueryRow;
}

impl<'a, R:Relation<'a>> IntoIterator for &'a OpaqueRel<R> {
    type IntoIter = <R as SelfQuery<'a>>::Iter;
    type Item = R::QueryRow;

    fn into_iter(self)->Self::IntoIter {
        let r:&'a R = &self.0;
        r.iter_all()
    }
}

pub struct OpaquePlan<'a, R:'a, Req>(&'a OpaqueRel<R>, Req);

impl<'a, Req:'a, R:'a> IntoIterator for OpaquePlan<'a, R, Req>
where R: Queryable<'a, Req>, Req:QueryRequest {
    type Item = R::QueryRow;
    type IntoIter = <R::Plan as IntoIterator>::IntoIter;
    fn into_iter(self)->Self::IntoIter {
        let r:&'a R = &self.0.0;
        r.query(self.1)
    }
}

impl<'a, R, Req> QueryPlanImpl<'a, OpaqueRel<R>, Req> for OpaquePlan<'a, R, Req> {
    // type EstimatedCost;
    fn prepare(rel: &'a OpaqueRel<R>, req: Req)->Self {
        OpaquePlan(rel, req)
    }
}

#[derive(Debug,Default)]
pub struct OpaquePlanner;
defun!{ OpaquePlanner {
    ('a, Rel:'a, Req) { _:&'a OpaqueRel<Rel>, _:Req } => { Ret, @OpaquePlan<'a, Rel, Req> };
}}

impl<R,H:Header> Insert<H> for OpaqueRel<R> where R:Insert<H> {
    /// The fields from `H` that aren't consumed
    type Remainder = R::Remainder;
    type Op = OpaqueOp<R::Op>;

    fn insert_op<FromRec:Record<Cols=H>>(rec:FromRec)
    -> (Self::Op, Self::Remainder) {
        let (op, remainder) = R::insert_op(rec);
        (OpaqueOp(op), remainder)
    }
}

impl<R,Q:QueryFilter> Delete<Q> for OpaqueRel<R> where R:Delete<Q> {
    type Op = OpaqueOp<R::Op>;
    type Deleter = impl Fn(Q)->Self::Op;

    fn deleter()->Self::Deleter {
        |q| OpaqueOp((R::deleter())(q))
    }
}

pub struct OpaqueOp<Op>(Op);

impl<Target, Op:RevertableOp<Target>>
RevertableOp<OpaqueRel<Target>> for OpaqueOp<Op> {
    type Err = Op::Err;
    type Log = OpaqueLog<Op::Log>;

    fn apply(self, target:&mut OpaqueRel<Target>) -> Result<Self::Log, Self::Err> {
        Ok(OpaqueLog(self.0.apply(&mut target.0)?))
    }
}

pub struct OpaqueLog<Log>(Log);

impl<Target, Log:UndoLog<Target>>
UndoLog<OpaqueRel<Target>> for OpaqueLog<Log> {
    fn revert(self, target: &mut OpaqueRel<Target>) {
        self.0.revert(&mut target.0);
    }
}

/*
impl<'a, R:RelationImpl> RelationImpl for &'a R {
    type Cols = R::Cols;
    type Planner = RefPlanner;
}

impl<'a, R:RelationImpl> RelationImpl for &'a mut R {
    type Cols = R::Cols;
    type Planner = RefPlanner;
}

impl<R:RelationImpl> RelationImpl for std::rc::Rc<R> {
    type Cols = R::Cols;
    type Planner = RefPlanner;
}

impl<R:RelationImpl> RelationImpl for std::sync::Arc<R> {
    type Cols = R::Cols;
    type Planner = RefPlanner;
}

impl<R:RelationImpl> RelationImpl for std::boxed::Box<R> {
    type Cols = R::Cols;
    type Planner = RefPlanner;
}
*/