kip-sql 0.0.1-alpha.8

build the SQL layer of KipDB database
Documentation
use crate::execution::codegen::CodeGenerator;
use crate::execution::ExecutorError;
use crate::impl_from_lua;
use crate::planner::operator::sort::{SortField, SortOperator};
use mlua::prelude::{LuaResult, LuaValue};
use mlua::{FromLua, Lua, UserData, Value};
use std::mem;

pub struct Sort {
    id: i64,
    sort_fields: Option<Vec<SortField>>,
    is_produced: bool,
}

impl UserData for SortField {}

impl_from_lua!(SortField);

impl From<(SortOperator, i64)> for Sort {
    fn from((SortOperator { sort_fields, .. }, id): (SortOperator, i64)) -> Self {
        Sort {
            id,
            sort_fields: Some(sort_fields),
            is_produced: false,
        }
    }
}

impl CodeGenerator for Sort {
    fn produce(&mut self, lua: &Lua, script: &mut String) -> Result<(), ExecutorError> {
        if let Some(sort_fields) = self.sort_fields.take() {
            let env = format!("sort_fields_{}", self.id);
            lua.globals().set(env.as_str(), sort_fields)?;

            script.push_str(
                format!(
                    r#"
            local sort_temp_{} = sort({}, results)
            results = {{}}

            for index, tuple in ipairs(sort_temp_{}) do
                index = index - 1
            "#,
                    self.id, env, self.id
                )
                .as_str(),
            );

            self.is_produced = true;
        }

        Ok(())
    }

    fn consume(&mut self, _: &Lua, script: &mut String) -> Result<(), ExecutorError> {
        if mem::replace(&mut self.is_produced, false) {
            script.push_str(
                r#"
                table.insert(results, tuple)
                ::continue::
            end
            "#,
            );
        }

        Ok(())
    }
}