Rename ColumnValue to Variant

This commit is contained in:
Dan Spencer 2015-03-28 17:04:08 -06:00
parent 7e8bdd3838
commit 4f3cc3b17a
7 changed files with 120 additions and 115 deletions

15
src/columnvalueops.rs Normal file
View File

@ -0,0 +1,15 @@
use std::borrow::Cow;
pub trait ColumnValueOps: Sized {
fn from_string_literal(s: Cow<str>) -> Result<Self, Cow<str>>;
fn from_number_literal(s: Cow<str>) -> Result<Self, Cow<str>>;
/// Used for predicate logic (such as the entire WHERE expression).
fn tests_true(&self) -> bool;
fn equals(&self, rhs: &Self) -> Self;
fn not_equals(&self, rhs: &Self) -> Self;
fn and(&self, rhs: &Self) -> Self;
fn or(&self, rhs: &Self) -> Self;
fn concat(&self, rhs: &Self) -> Self;
}

View File

@ -1,6 +1,6 @@
use columnvalueops::ColumnValueOps;
use identifier::Identifier; use identifier::Identifier;
use types::DbType; use types::DbType;
use std::borrow::Cow;
use std::fmt; use std::fmt;
/// A read-only interface to information about the database schema. /// A read-only interface to information about the database schema.
@ -32,17 +32,3 @@ pub trait ColumnInfo {
fn get_name(&self) -> &Identifier; fn get_name(&self) -> &Identifier;
fn get_dbtype(&self) -> &DbType; fn get_dbtype(&self) -> &DbType;
} }
pub trait ColumnValueOps: Sized {
fn from_string_literal(s: Cow<str>) -> Result<Self, Cow<str>>;
fn from_number_literal(s: Cow<str>) -> Result<Self, Cow<str>>;
/// Used for predicate logic (such as the entire WHERE expression).
fn tests_true(&self) -> bool;
fn equals(&self, rhs: &Self) -> Self;
fn not_equals(&self, rhs: &Self) -> Self;
fn and(&self, rhs: &Self) -> Self;
fn or(&self, rhs: &Self) -> Self;
fn concat(&self, rhs: &Self) -> Self;
}

View File

@ -1,4 +1,5 @@
use databaseinfo::{DatabaseInfo, ColumnValueOps}; use columnvalueops::ColumnValueOps;
use databaseinfo::DatabaseInfo;
use databasestorage::DatabaseStorage; use databasestorage::DatabaseStorage;
use super::sexpression::SExpression; use super::sexpression::SExpression;

View File

@ -1,4 +1,5 @@
use databaseinfo::{DatabaseInfo, TableInfo, ColumnValueOps}; use columnvalueops::ColumnValueOps;
use databaseinfo::{DatabaseInfo, TableInfo};
use identifier::Identifier; use identifier::Identifier;
use sqlsyntax::ast; use sqlsyntax::ast;

View File

@ -5,11 +5,10 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::fmt;
use databaseinfo::{DatabaseInfo, TableInfo, ColumnInfo, ColumnValueOps}; use databaseinfo::{DatabaseInfo, TableInfo, ColumnInfo};
use identifier::Identifier; use identifier::Identifier;
use types::DbType; use types::{DbType, Variant};
use sqlsyntax::ast; use sqlsyntax::ast;
mod table; mod table;
@ -31,103 +30,9 @@ pub struct ResultSet<'a> {
pub type ExecuteStatementResult<'a> = Result<ExecuteStatementResponse<'a>, String>; pub type ExecuteStatementResult<'a> = Result<ExecuteStatementResponse<'a>, String>;
#[derive(Clone)]
pub enum ColumnValue {
Null,
StringLiteral(String),
Number(u64)
}
impl fmt::Display for ColumnValue {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self {
&ColumnValue::Null => write!(f, "NULL"),
&ColumnValue::StringLiteral(ref s) => write!(f, "\"{}\"", s),
&ColumnValue::Number(n) => write!(f, "{}", n)
}
}
}
impl ColumnValue {
fn from_bool(value: bool) -> ColumnValue {
ColumnValue::Number(if value { 1 } else { 0 })
}
}
impl ColumnValueOps for ColumnValue {
fn from_string_literal(s: Cow<str>) -> Result<ColumnValue, Cow<str>> {
Ok(ColumnValue::StringLiteral(s.into_owned()))
}
fn from_number_literal(s: Cow<str>) -> Result<ColumnValue, Cow<str>> {
match s.parse() {
Ok(number) => Ok(ColumnValue::Number(number)),
Err(_) => Err(s)
}
}
fn tests_true(&self) -> bool {
match self {
&ColumnValue::Null => false,
&ColumnValue::StringLiteral(ref s) => !s.is_empty(),
&ColumnValue::Number(n) => n != 0
}
}
fn equals(&self, rhs: &Self) -> Self {
match (self, rhs) {
(&ColumnValue::Null, _) | (_, &ColumnValue::Null) => {
// NULL does not compare.
ColumnValue::Null
},
(&ColumnValue::StringLiteral(ref l), &ColumnValue::StringLiteral(ref r)) => {
ColumnValue::from_bool(l == r)
},
(&ColumnValue::Number(l), &ColumnValue::Number(r)) => {
ColumnValue::from_bool(l == r)
},
_ => ColumnValue::from_bool(false)
}
}
fn not_equals(&self, rhs: &Self) -> Self {
match (self, rhs) {
(&ColumnValue::Null, _) | (_, &ColumnValue::Null) => {
// NULL does not compare.
ColumnValue::Null
},
(&ColumnValue::StringLiteral(ref l), &ColumnValue::StringLiteral(ref r)) => {
ColumnValue::from_bool(l != r)
},
(&ColumnValue::Number(l), &ColumnValue::Number(r)) => {
ColumnValue::from_bool(l != r)
},
_ => ColumnValue::from_bool(true)
}
}
fn and(&self, rhs: &Self) -> Self {
ColumnValue::from_bool(self.tests_true() && rhs.tests_true())
}
fn or(&self, rhs: &Self) -> Self {
ColumnValue::from_bool(self.tests_true() || rhs.tests_true())
}
fn concat(&self, rhs: &Self) -> Self {
match (self, rhs) {
(&ColumnValue::StringLiteral(ref l), &ColumnValue::StringLiteral(ref r)) => {
ColumnValue::StringLiteral(format!("{}{}", l, r))
},
(e, _) => e.clone()
}
}
}
impl DatabaseInfo for TempDb { impl DatabaseInfo for TempDb {
type Table = Table; type Table = Table;
type ColumnValue = ColumnValue; type ColumnValue = Variant;
fn find_table_by_name(&self, name: &Identifier) -> Option<&Table> { fn find_table_by_name(&self, name: &Identifier) -> Option<&Table> {
self.tables.iter().find(|t| &t.name == name) self.tables.iter().find(|t| &t.name == name)

View File

@ -1,5 +1,8 @@
use identifier::Identifier; use identifier::Identifier;
mod variant;
pub use self::variant::Variant;
use std::borrow::Cow; use std::borrow::Cow;
#[derive(Debug, Copy)] #[derive(Debug, Copy)]

94
src/types/variant.rs Normal file
View File

@ -0,0 +1,94 @@
use columnvalueops::ColumnValueOps;
use std::borrow::Cow;
use std::fmt;
#[derive(Clone)]
pub enum Variant {
Null,
StringLiteral(String),
Number(u64)
}
impl fmt::Display for Variant {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match self {
&Variant::Null => write!(f, "NULL"),
&Variant::StringLiteral(ref s) => write!(f, "\"{}\"", s),
&Variant::Number(n) => write!(f, "{}", n)
}
}
}
fn from_bool(value: bool) -> Variant {
Variant::Number(if value { 1 } else { 0 })
}
impl ColumnValueOps for Variant {
fn from_string_literal(s: Cow<str>) -> Result<Variant, Cow<str>> {
Ok(Variant::StringLiteral(s.into_owned()))
}
fn from_number_literal(s: Cow<str>) -> Result<Variant, Cow<str>> {
match s.parse() {
Ok(number) => Ok(Variant::Number(number)),
Err(_) => Err(s)
}
}
fn tests_true(&self) -> bool {
match self {
&Variant::Null => false,
&Variant::StringLiteral(ref s) => !s.is_empty(),
&Variant::Number(n) => n != 0
}
}
fn equals(&self, rhs: &Self) -> Self {
match (self, rhs) {
(&Variant::Null, _) | (_, &Variant::Null) => {
// NULL does not compare.
Variant::Null
},
(&Variant::StringLiteral(ref l), &Variant::StringLiteral(ref r)) => {
from_bool(l == r)
},
(&Variant::Number(l), &Variant::Number(r)) => {
from_bool(l == r)
},
_ => from_bool(false)
}
}
fn not_equals(&self, rhs: &Self) -> Self {
match (self, rhs) {
(&Variant::Null, _) | (_, &Variant::Null) => {
// NULL does not compare.
Variant::Null
},
(&Variant::StringLiteral(ref l), &Variant::StringLiteral(ref r)) => {
from_bool(l != r)
},
(&Variant::Number(l), &Variant::Number(r)) => {
from_bool(l != r)
},
_ => from_bool(true)
}
}
fn and(&self, rhs: &Self) -> Self {
from_bool(self.tests_true() && rhs.tests_true())
}
fn or(&self, rhs: &Self) -> Self {
from_bool(self.tests_true() || rhs.tests_true())
}
fn concat(&self, rhs: &Self) -> Self {
match (self, rhs) {
(&Variant::StringLiteral(ref l), &Variant::StringLiteral(ref r)) => {
Variant::StringLiteral(format!("{}{}", l, r))
},
(e, _) => e.clone()
}
}
}