toasty_driver_integration_suite/
helpers.rs1pub fn table_id(db: &toasty::Db, table_name: &str) -> toasty_core::schema::db::TableId {
3 let schema = db.schema();
4
5 if let Some(position) = schema.db.tables.iter().position(|t| t.name == table_name) {
7 return toasty_core::schema::db::TableId(position);
8 }
9
10 if let Some(position) = schema
12 .db
13 .tables
14 .iter()
15 .position(|t| t.name.ends_with(table_name))
16 {
17 return toasty_core::schema::db::TableId(position);
18 }
19
20 let available_tables: Vec<_> = schema.db.tables.iter().map(|t| &t.name).collect();
22 panic!(
23 "Table '{}' not found. Available tables: {:?}",
24 table_name, available_tables
25 );
26}
27
28pub fn column(
30 db: &toasty::Db,
31 table_name: &str,
32 column_name: &str,
33) -> toasty_core::schema::db::ColumnId {
34 columns(db, table_name, &[column_name])[0]
35}
36
37pub fn columns(
39 db: &toasty::Db,
40 table_name: &str,
41 column_names: &[&str],
42) -> Vec<toasty_core::schema::db::ColumnId> {
43 let schema = db.schema();
44
45 let table = schema
47 .db
48 .tables
49 .iter()
50 .find(|t| t.name == table_name || t.name.ends_with(table_name))
51 .unwrap_or_else(|| panic!("Table '{}' not found", table_name));
52
53 let table_id = table_id(db, table_name);
54
55 column_names
56 .iter()
57 .map(|col_name| {
58 let index = table
59 .columns
60 .iter()
61 .position(|c| c.name == *col_name)
62 .unwrap_or_else(|| {
63 panic!("Column '{}' not found in table '{}'", col_name, table_name)
64 });
65
66 toasty_core::schema::db::ColumnId {
67 table: table_id,
68 index,
69 }
70 })
71 .collect()
72}
73
74use std::collections::BTreeMap;
75
76use toasty_core::{
77 driver::{Operation, operation::TypedValue},
78 stmt::{Assignment, Expr, ExprSet, Statement, Value},
79};
80
81use crate::Test;
82
83fn expr_value(expr: &Expr, params: &[Value]) -> Value {
86 match expr {
87 Expr::Value(value) => value.clone(),
88 Expr::Arg(arg) => params[arg.position].clone(),
89 other => panic!("expected a value expression, got {other:#?}"),
90 }
91}
92
93fn params_of(params: Vec<TypedValue>) -> Vec<Value> {
94 params.into_iter().map(|tv| tv.value).collect()
95}
96
97pub fn pop_insert(test: &mut Test) -> BTreeMap<usize, Value> {
101 let (op, _) = test.log().pop();
102 let (stmt, params) = match op {
103 Operation::QuerySql(q) => (q.stmt, params_of(q.params)),
104 Operation::Insert(i) => (i.stmt, params_of(i.params)),
105 other => panic!("expected an insert op, got {other:#?}"),
106 };
107 let Statement::Insert(insert) = stmt else {
108 panic!("expected an Insert statement");
109 };
110 let toasty_core::stmt::InsertTarget::Table(target) = &insert.target else {
111 panic!("expected a table insert target");
112 };
113 let ExprSet::Values(values) = &insert.source.body else {
114 panic!("expected a VALUES source");
115 };
116 let row: Vec<Value> = match &values.rows[0] {
119 Expr::Record(record) => record
120 .fields
121 .iter()
122 .map(|expr| expr_value(expr, ¶ms))
123 .collect(),
124 Expr::Value(Value::Record(record)) => record.fields.clone(),
125 other => panic!("expected a record row, got {other:#?}"),
126 };
127 target
128 .columns
129 .iter()
130 .zip(row)
131 .map(|(col, value)| (col.index, value))
132 .collect()
133}
134
135pub fn pop_update(test: &mut Test) -> BTreeMap<usize, Value> {
139 let (op, _) = test.log().pop();
140 let (assignments, params) = match op {
141 Operation::QuerySql(q) => match q.stmt {
142 Statement::Update(update) => (update.assignments, params_of(q.params)),
143 other => panic!("expected an Update statement, got {other:#?}"),
144 },
145 Operation::UpdateByKey(update) => (update.assignments, vec![]),
146 other => panic!("expected an update op, got {other:#?}"),
147 };
148 assignments
149 .iter()
150 .map(|(projection, assignment)| {
151 let Assignment::Set(expr) = assignment else {
152 panic!("expected a Set assignment, got {assignment:#?}");
153 };
154 (projection.as_slice()[0], expr_value(expr, ¶ms))
155 })
156 .collect()
157}
158
159pub fn pop_filter(test: &mut Test) -> Expr {
162 let (op, _) = test.log().pop();
163 match op {
164 Operation::QuerySql(q) => {
165 let Statement::Query(query) = q.stmt else {
166 panic!("expected a Query statement");
167 };
168 let ExprSet::Select(select) = query.body else {
169 panic!("expected a Select body");
170 };
171 select.filter.expr.expect("filter predicate present")
172 }
173 Operation::Scan(scan) => scan.filter.expect("filter predicate present"),
174 other => panic!("expected a query/scan op, got {other:#?}"),
175 }
176}