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
74pub fn column_storage_ty(
77 db: &toasty::Db,
78 table_name: &str,
79 column_name: &str,
80) -> toasty_core::schema::db::Type {
81 let schema = db.schema();
82 let table = schema
83 .db
84 .tables
85 .iter()
86 .find(|t| t.name == table_name || t.name.ends_with(table_name))
87 .unwrap_or_else(|| panic!("table '{table_name}' not in schema"));
88 table
89 .columns
90 .iter()
91 .find(|c| c.name == column_name)
92 .unwrap_or_else(|| panic!("column '{column_name}' not in table '{table_name}'"))
93 .storage_ty
94 .clone()
95}
96
97use std::collections::BTreeMap;
98
99use toasty_core::{
100 driver::{Operation, operation::TypedValue},
101 stmt::{Assignment, Expr, ExprSet, Statement, Value},
102};
103
104use crate::Test;
105
106fn expr_value(expr: &Expr, params: &[Value]) -> Value {
109 match expr {
110 Expr::Value(value) => value.clone(),
111 Expr::Arg(arg) => params[arg.position].clone(),
112 other => panic!("expected a value expression, got {other:#?}"),
113 }
114}
115
116fn params_of(params: Vec<TypedValue>) -> Vec<Value> {
117 params.into_iter().map(|tv| tv.value).collect()
118}
119
120pub fn pop_insert(test: &mut Test) -> BTreeMap<usize, Value> {
124 let (op, _) = test.log().pop();
125 let (stmt, params) = match op {
126 Operation::QuerySql(q) => (q.stmt, params_of(q.params)),
127 Operation::Insert(i) => (i.stmt, params_of(i.params)),
128 other => panic!("expected an insert op, got {other:#?}"),
129 };
130 let Statement::Insert(insert) = stmt else {
131 panic!("expected an Insert statement");
132 };
133 let toasty_core::stmt::InsertTarget::Table(target) = &insert.target else {
134 panic!("expected a table insert target");
135 };
136 let ExprSet::Values(values) = &insert.source.body else {
137 panic!("expected a VALUES source");
138 };
139 let row: Vec<Value> = match &values.rows[0] {
142 Expr::Record(record) => record
143 .fields
144 .iter()
145 .map(|expr| expr_value(expr, ¶ms))
146 .collect(),
147 Expr::Value(Value::Record(record)) => record.fields.clone(),
148 other => panic!("expected a record row, got {other:#?}"),
149 };
150 target
151 .columns
152 .iter()
153 .zip(row)
154 .map(|(col, value)| (col.index, value))
155 .collect()
156}
157
158pub fn pop_update(test: &mut Test) -> BTreeMap<usize, Value> {
162 let (op, _) = test.log().pop();
163 let (assignments, params) = match op {
164 Operation::QuerySql(q) => match q.stmt {
165 Statement::Update(update) => (update.assignments, params_of(q.params)),
166 other => panic!("expected an Update statement, got {other:#?}"),
167 },
168 Operation::UpdateByKey(update) => (update.assignments, vec![]),
169 other => panic!("expected an update op, got {other:#?}"),
170 };
171 assignments
172 .iter()
173 .map(|(projection, assignment)| {
174 let Assignment::Set(expr) = assignment else {
175 panic!("expected a Set assignment, got {assignment:#?}");
176 };
177 (projection.as_slice()[0], expr_value(expr, ¶ms))
178 })
179 .collect()
180}
181
182pub fn pop_filter(test: &mut Test) -> Expr {
185 let (op, _) = test.log().pop();
186 match op {
187 Operation::QuerySql(q) => {
188 let Statement::Query(query) = q.stmt else {
189 panic!("expected a Query statement");
190 };
191 let ExprSet::Select(select) = query.body else {
192 panic!("expected a Select body");
193 };
194 select.filter.expr.expect("filter predicate present")
195 }
196 Operation::Scan(scan) => scan.filter.expect("filter predicate present"),
197 other => panic!("expected a query/scan op, got {other:#?}"),
198 }
199}