extern crate msql_srv;
extern crate mysql;
use gluesql::{
prelude::{Glue, Payload, Value},
sled_storage::SledStorage,
};
use gluesql_core::store::{GStore, GStoreMut};
use msql_srv::*;
use mysql::prelude::*;
use std::{
fmt::Debug,
io::{Error, Result, Write},
};
pub struct MySQLApi<T, U>
where
T: Debug,
U: GStore<T> + GStoreMut<T>,
{
glue: Glue<T, U>,
}
impl<T, U> MySQLApi<T, U>
where
T: Debug,
U: GStore<T> + GStoreMut<T>,
{
pub fn new(storage: U) -> Self {
let glue = Glue::new(storage);
Self { glue }
}
}
impl<W: Write, T, U> MysqlShim<W> for MySQLApi<T, U>
where
T: Debug,
U: GStore<T> + GStoreMut<T>,
{
type Error = Error;
fn on_prepare(&mut self, _: &str, info: StatementMetaWriter<W>) -> Result<()> {
info.reply(42, &[], &[])
}
fn on_execute(&mut self, _: u32, _: ParamParser, results: QueryResultWriter<W>) -> Result<()> {
results.completed(0, 0)
}
fn on_close(&mut self, _: u32) {}
fn on_init(&mut self, _: &str, writer: InitWriter<W>) -> Result<()> {
Ok(())
}
fn on_query(&mut self, sql: &str, results: QueryResultWriter<W>) -> Result<()> {
println!("sql: {}", sql);
let output = self.glue.execute(sql).unwrap();
match output {
Payload::DropTable => results.completed(1, 0),
Payload::Delete(c) => results.completed(c as u64, 0),
Payload::Insert(c) => results.completed(c as u64, 0),
Payload::Create => results.completed(1, 0),
Payload::Select { labels, rows } => {
let mut cols = vec![];
if rows.len() > 0 {
for i in 0..rows[0].len() {
let col = &rows[0][i];
match col {
Value::Str(_) => {
let str_col = Column {
table: "".to_string(),
column: labels[i].to_string(),
coltype: ColumnType::MYSQL_TYPE_STRING,
colflags: ColumnFlags::empty(),
};
cols.push(str_col);
}
Value::I64(_) => {
let int_col = Column {
table: "".to_string(),
column: labels[i].to_string(),
coltype: ColumnType::MYSQL_TYPE_STRING,
colflags: ColumnFlags::empty(),
};
cols.push(int_col);
}
Value::Timestamp(t) => {
let ts_col = Column {
table: "".to_string(),
column: labels[i].to_string(),
coltype: ColumnType::MYSQL_TYPE_TIMESTAMP,
colflags: ColumnFlags::empty(),
};
cols.push(ts_col);
}
_ => {}
}
}
}
let mut rw = results.start(&cols)?;
for i in 0..rows.len() {
for col in &rows[i] {
match col {
Value::I64(int_64) => {
rw.write_col(int_64)?;
}
Value::Str(s) => {
rw.write_col(s)?;
}
Value::Timestamp(s) => {
rw.write_col(s)?;
}
_ => {}
}
}
rw.end_row()?;
}
rw.finish()
}
_ => Ok(()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {}
}