use smallvec::SmallVec;
use selene_core::{DbString, NodeId, Value};
use crate::plan::{BindingTableSchema, InsertSiteId};
#[derive(Clone, Debug)]
pub struct Binding {
values: SmallVec<[Value; 8]>,
insert_sites: SmallVec<[(InsertSiteId, NodeId); 4]>,
}
impl Binding {
#[must_use]
pub fn new(values: impl IntoIterator<Item = Value>) -> Self {
Self {
values: values.into_iter().collect(),
insert_sites: SmallVec::new(),
}
}
#[must_use]
pub fn empty() -> Self {
Self {
values: SmallVec::new(),
insert_sites: SmallVec::new(),
}
}
pub(crate) fn with_insert_sites(
values: impl IntoIterator<Item = Value>,
insert_sites: SmallVec<[(InsertSiteId, NodeId); 4]>,
) -> Self {
Self {
values: values.into_iter().collect(),
insert_sites,
}
}
pub(crate) fn from_parts(
values: SmallVec<[Value; 8]>,
insert_sites: SmallVec<[(InsertSiteId, NodeId); 4]>,
) -> Self {
Self {
values,
insert_sites,
}
}
#[must_use]
pub fn values(&self) -> &[Value] {
&self.values
}
#[must_use]
pub fn get(&self, index: usize) -> Option<&Value> {
self.values.get(index)
}
pub(crate) fn insert_sites(&self) -> &[(InsertSiteId, NodeId)] {
&self.insert_sites
}
pub(crate) fn cloned_values(&self) -> SmallVec<[Value; 8]> {
self.values.clone()
}
pub(crate) fn cloned_insert_sites(&self) -> SmallVec<[(InsertSiteId, NodeId); 4]> {
self.insert_sites.clone()
}
pub(crate) fn inserted_node(&self, site_id: InsertSiteId) -> Option<NodeId> {
self.insert_sites
.iter()
.find_map(|(site, id)| (*site == site_id).then_some(*id))
}
pub(crate) fn with_appended_values(&self, values: impl IntoIterator<Item = Value>) -> Self {
let mut output = self.values.clone();
output.extend(values);
Self {
values: output,
insert_sites: self.insert_sites.clone(),
}
}
}
impl PartialEq for Binding {
fn eq(&self, rhs: &Self) -> bool {
self.values == rhs.values
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct BindingTable {
schema: BindingTableSchema,
rows: Vec<Binding>,
}
impl BindingTable {
#[must_use]
pub fn empty(schema: BindingTableSchema) -> Self {
Self {
schema,
rows: Vec::new(),
}
}
#[must_use]
pub fn new(schema: BindingTableSchema, rows: Vec<Binding>) -> Self {
Self { schema, rows }
}
#[must_use]
pub const fn schema(&self) -> &BindingTableSchema {
&self.schema
}
#[must_use]
pub fn rows(&self) -> &[Binding] {
&self.rows
}
pub(crate) fn into_parts(self) -> (BindingTableSchema, Vec<Binding>) {
(self.schema, self.rows)
}
pub fn iter(&self) -> impl Iterator<Item = &Binding> {
self.rows.iter()
}
#[must_use]
pub fn row_count(&self) -> usize {
self.rows.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.rows.is_empty()
}
pub fn push_row(&mut self, row: Binding) {
self.rows.push(row);
}
#[must_use]
pub fn column_index(&self, name: DbString) -> Option<usize> {
self.schema
.columns
.iter()
.position(|column| column.name == Some(name.clone()))
}
}