mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-15 13:04:20 +01:00
fix the merge conflicts
This commit is contained in:
@@ -3,7 +3,7 @@ use std::{iter::Sum, ops::SubAssign};
|
||||
use anarchist_readable_name_generator_lib::readable_name_custom;
|
||||
use rand::{distributions::uniform::SampleUniform, Rng};
|
||||
|
||||
use crate::model::table::Table;
|
||||
use crate::runner::env::SimulatorTables;
|
||||
|
||||
mod expr;
|
||||
pub mod plan;
|
||||
@@ -50,7 +50,7 @@ pub trait ArbitraryFromMaybe<T> {
|
||||
/// might return a vector of rows that were inserted into the table.
|
||||
pub(crate) trait Shadow {
|
||||
type Result;
|
||||
fn shadow(&self, tables: &mut Vec<Table>) -> Self::Result;
|
||||
fn shadow(&self, tables: &mut SimulatorTables) -> Self::Result;
|
||||
}
|
||||
|
||||
/// Frequency is a helper function for composing different generators with different frequency
|
||||
|
||||
@@ -8,16 +8,16 @@ use std::{
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use turso_core::{Connection, Result, StepResult, IO};
|
||||
use turso_core::{Connection, Result, StepResult};
|
||||
|
||||
use crate::{
|
||||
generation::Shadow,
|
||||
model::{
|
||||
query::{update::Update, Create, CreateIndex, Delete, Drop, Insert, Query, Select},
|
||||
table::{SimValue, Table},
|
||||
table::SimValue,
|
||||
},
|
||||
runner::{
|
||||
env::{SimConnection, SimulationType},
|
||||
env::{SimConnection, SimulationType, SimulatorTables},
|
||||
io::SimulatorIO,
|
||||
},
|
||||
SimulatorEnv,
|
||||
@@ -114,7 +114,7 @@ pub(crate) enum Interactions {
|
||||
impl Shadow for Interactions {
|
||||
type Result = ();
|
||||
|
||||
fn shadow(&self, tables: &mut Vec<Table>) {
|
||||
fn shadow(&self, tables: &mut SimulatorTables) {
|
||||
match self {
|
||||
Interactions::Property(property) => {
|
||||
let initial_tables = tables.clone();
|
||||
@@ -423,7 +423,7 @@ impl ArbitraryFrom<&mut SimulatorEnv> for InteractionPlan {
|
||||
|
||||
impl Shadow for Interaction {
|
||||
type Result = anyhow::Result<Vec<Vec<SimValue>>>;
|
||||
fn shadow(&self, env: &mut Vec<Table>) -> Self::Result {
|
||||
fn shadow(&self, env: &mut SimulatorTables) -> Self::Result {
|
||||
match self {
|
||||
Self::Query(query) => query.shadow(env),
|
||||
Self::FsyncQuery(query) => {
|
||||
@@ -438,7 +438,7 @@ impl Shadow for Interaction {
|
||||
}
|
||||
}
|
||||
impl Interaction {
|
||||
pub(crate) fn execute_query(&self, conn: &mut Arc<Connection>, io: &SimulatorIO) -> ResultSet {
|
||||
pub(crate) fn execute_query(&self, conn: &mut Arc<Connection>, _io: &SimulatorIO) -> ResultSet {
|
||||
if let Self::Query(query) = self {
|
||||
let query_str = query.to_string();
|
||||
let rows = conn.query(&query_str);
|
||||
@@ -737,7 +737,7 @@ fn random_create<R: rand::Rng>(rng: &mut R, _env: &SimulatorEnv) -> Interactions
|
||||
}
|
||||
|
||||
fn random_read<R: rand::Rng>(rng: &mut R, env: &SimulatorEnv) -> Interactions {
|
||||
Interactions::Query(Query::Select(Select::arbitrary_from(rng, &env.tables)))
|
||||
Interactions::Query(Query::Select(Select::arbitrary_from(rng, &env.tables.tables)))
|
||||
}
|
||||
|
||||
fn random_write<R: rand::Rng>(rng: &mut R, env: &SimulatorEnv) -> Interactions {
|
||||
|
||||
@@ -3,22 +3,16 @@ use turso_core::LimboError;
|
||||
use turso_sqlite3_parser::ast::{self};
|
||||
|
||||
use crate::{
|
||||
model::{
|
||||
generation::Shadow as _, model::{
|
||||
query::{
|
||||
predicate::Predicate,
|
||||
select::{
|
||||
predicate::Predicate, select::{
|
||||
CompoundOperator, CompoundSelect, Distinctness, ResultColumn, SelectBody,
|
||||
SelectInner,
|
||||
},
|
||||
select::{Distinctness, ResultColumn},
|
||||
transaction::{Begin, Commit, Rollback},
|
||||
update::Update,
|
||||
Create, Delete, Drop, Insert, Query, Select,
|
||||
}, transaction::{Begin, Commit, Rollback}, update::Update, Create, Delete, Drop, Insert, Query, Select
|
||||
},
|
||||
table::SimValue,
|
||||
FAULT_ERROR_MSG,
|
||||
},
|
||||
runner::env::SimulatorEnv,
|
||||
}, runner::env::SimulatorEnv
|
||||
};
|
||||
|
||||
use super::{
|
||||
@@ -285,17 +279,17 @@ impl Property {
|
||||
let table_name = create.table.name.clone();
|
||||
|
||||
let assertion = Interaction::Assertion(Assertion {
|
||||
message:
|
||||
"creating two tables with the name should result in a failure for the second query"
|
||||
.to_string(),
|
||||
func: Box::new(move |stack: &Vec<ResultSet>, _: &SimulatorEnv| {
|
||||
let last = stack.last().unwrap();
|
||||
match last {
|
||||
Ok(_) => Ok(false),
|
||||
Err(e) => Ok(e.to_string().to_lowercase().contains(&format!("table {table_name} already exists"))),
|
||||
}
|
||||
}),
|
||||
});
|
||||
message:
|
||||
"creating two tables with the name should result in a failure for the second query"
|
||||
.to_string(),
|
||||
func: Box::new(move |stack: &Vec<ResultSet>, _| {
|
||||
let last = stack.last().unwrap();
|
||||
match last {
|
||||
Ok(_) => Ok(false),
|
||||
Err(e) => Ok(e.to_string().to_lowercase().contains(&format!("table {table_name} already exists"))),
|
||||
}
|
||||
}),
|
||||
});
|
||||
|
||||
let mut interactions = Vec::new();
|
||||
interactions.push(assumption);
|
||||
@@ -318,7 +312,7 @@ impl Property {
|
||||
),
|
||||
func: Box::new({
|
||||
let table_name = select.dependencies();
|
||||
move |_: &Vec<ResultSet>, env: &SimulatorEnv| {
|
||||
move |_: &Vec<ResultSet>, env: &mut SimulatorEnv| {
|
||||
Ok(table_name
|
||||
.iter()
|
||||
.all(|table| env.tables.iter().any(|t| t.name == *table)))
|
||||
@@ -373,8 +367,8 @@ impl Property {
|
||||
)));
|
||||
|
||||
let assertion = Interaction::Assertion(Assertion {
|
||||
message: format!("`{select}` should return no values for table `{table}`",),
|
||||
func: Box::new(move |stack: &Vec<ResultSet>, _: &SimulatorEnv| {
|
||||
message: format!("`{}` should return no values for table `{}`", select, table,),
|
||||
func: Box::new(move |stack: &Vec<ResultSet>, _| {
|
||||
let rows = stack.last().unwrap();
|
||||
match rows {
|
||||
Ok(rows) => Ok(rows.is_empty()),
|
||||
@@ -410,8 +404,11 @@ impl Property {
|
||||
let table_name = table.clone();
|
||||
|
||||
let assertion = Interaction::Assertion(Assertion {
|
||||
message: format!("select query should result in an error for table '{table}'"),
|
||||
func: Box::new(move |stack: &Vec<ResultSet>, _: &SimulatorEnv| {
|
||||
message: format!(
|
||||
"select query should result in an error for table '{}'",
|
||||
table
|
||||
),
|
||||
func: Box::new(move |stack: &Vec<ResultSet>, _| {
|
||||
let last = stack.last().unwrap();
|
||||
match last {
|
||||
Ok(_) => Ok(false),
|
||||
@@ -471,8 +468,8 @@ impl Property {
|
||||
// If rows1 results have more than 1 column, there is a problem
|
||||
if rows1.iter().any(|vs| vs.len() > 1) {
|
||||
return Err(LimboError::InternalError(
|
||||
"Select query without the star should return only one column".to_string(),
|
||||
));
|
||||
"Select query without the star should return only one column".to_string(),
|
||||
));
|
||||
}
|
||||
// Count the 1s in the select query without the star
|
||||
let rows1_count = rows1
|
||||
@@ -517,11 +514,11 @@ impl Property {
|
||||
// then when IO is called the fault triggers. It may happen that a fault is injected
|
||||
// but no IO happens right after it
|
||||
message: "fault occured".to_string(),
|
||||
func: Box::new(move |stack, env| {
|
||||
func: Box::new(move |stack, env: &mut SimulatorEnv| {
|
||||
let last = stack.last().unwrap();
|
||||
match last {
|
||||
Ok(_) => {
|
||||
query_clone.shadow(env);
|
||||
let _ = query_clone.shadow(&mut env.tables);
|
||||
Ok(true)
|
||||
}
|
||||
Err(err) => {
|
||||
@@ -554,7 +551,7 @@ impl Property {
|
||||
),
|
||||
func: Box::new({
|
||||
let tables = select.dependencies();
|
||||
move |_: &Vec<ResultSet>, env: &SimulatorEnv| {
|
||||
move |_: &Vec<ResultSet>, env: &mut SimulatorEnv| {
|
||||
Ok(tables
|
||||
.iter()
|
||||
.all(|table| env.tables.iter().any(|t| t.name == *table)))
|
||||
@@ -612,7 +609,7 @@ impl Property {
|
||||
// select and select_tlp should return the same rows
|
||||
let assertion = Interaction::Assertion(Assertion {
|
||||
message: "select and select_tlp should return the same rows".to_string(),
|
||||
func: Box::new(move |stack: &Vec<ResultSet>, _: &SimulatorEnv| {
|
||||
func: Box::new(move |stack: &Vec<ResultSet>, _: &mut SimulatorEnv| {
|
||||
if stack.len() < 2 {
|
||||
return Err(LimboError::InternalError(
|
||||
"Not enough result sets on the stack".to_string(),
|
||||
@@ -681,7 +678,7 @@ impl Property {
|
||||
Interaction::Query(Query::Select(s3.clone())),
|
||||
Interaction::Assertion(Assertion {
|
||||
message: "UNION ALL should preserve cardinality".to_string(),
|
||||
func: Box::new(move |stack: &Vec<ResultSet>, _: &SimulatorEnv| {
|
||||
func: Box::new(move |stack: &Vec<ResultSet>, _: &mut SimulatorEnv| {
|
||||
if stack.len() < 3 {
|
||||
return Err(LimboError::InternalError(
|
||||
"Not enough result sets on the stack".to_string(),
|
||||
@@ -720,15 +717,14 @@ fn assert_all_table_values(tables: &[String]) -> impl Iterator<Item = Interactio
|
||||
)));
|
||||
|
||||
let assertion = Interaction::Assertion(Assertion {
|
||||
message: format!(
|
||||
"table {table} should contain all of its values after the wal reopened"
|
||||
),
|
||||
message: format!("table {} should contain all of its values", table),
|
||||
func: Box::new({
|
||||
let table = table.clone();
|
||||
move |stack: &Vec<ResultSet>, env: &mut SimulatorEnv| {
|
||||
let table = env.tables.iter().find(|t| t.name == table).ok_or_else(|| {
|
||||
LimboError::InternalError(format!(
|
||||
"table {table} should exist in simulator env",
|
||||
"table {} should exist in simulator env",
|
||||
table
|
||||
))
|
||||
})?;
|
||||
let last = stack.last().unwrap();
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::model::query::select::{
|
||||
use crate::model::query::update::Update;
|
||||
use crate::model::query::{Create, Delete, Drop, Insert, Query, Select};
|
||||
use crate::model::table::{SimValue, Table};
|
||||
use crate::runner::env::SimulatorTables;
|
||||
use crate::SimulatorEnv;
|
||||
use itertools::Itertools;
|
||||
use rand::Rng;
|
||||
@@ -77,7 +78,10 @@ impl ArbitraryFrom<&Vec<Table>> for FromClause {
|
||||
impl ArbitraryFrom<&Vec<Table>> for SelectInner {
|
||||
fn arbitrary_from<R: Rng>(rng: &mut R, tables: &Vec<Table>) -> Self {
|
||||
let from = FromClause::arbitrary_from(rng, tables);
|
||||
let mut tables = tables.clone();
|
||||
let mut tables = SimulatorTables {
|
||||
tables: tables.clone(),
|
||||
snapshot: None,
|
||||
};
|
||||
// todo: this is a temporary hack because env is not separated from the tables
|
||||
let join_table = from
|
||||
.shadow(&mut tables)
|
||||
@@ -180,7 +184,10 @@ impl ArbitraryFrom<&SimulatorEnv> for Insert {
|
||||
|
||||
// Backtrack here cannot return None
|
||||
backtrack(
|
||||
vec![(1, Box::new(gen_values)), (1, Box::new(gen_select))],
|
||||
vec![
|
||||
(1, Box::new(gen_values)),
|
||||
(1, Box::new(|rng| gen_select(rng))),
|
||||
],
|
||||
rng,
|
||||
)
|
||||
.unwrap()
|
||||
@@ -259,14 +266,15 @@ impl ArbitraryFrom<&SimulatorEnv> for Update {
|
||||
|
||||
#[cfg(test)]
|
||||
mod query_generation_tests {
|
||||
|
||||
use rand::RngCore;
|
||||
use turso_core::Value;
|
||||
use turso_sqlite3_parser::to_sql_string::ToSqlString;
|
||||
|
||||
use super::*;
|
||||
|
||||
use crate::model::query::predicate::Predicate;
|
||||
use crate::model::query::EmptyContext;
|
||||
use crate::model::table::{Column, ColumnType};
|
||||
use crate::SimulatorEnv;
|
||||
|
||||
#[test]
|
||||
fn test_select_query_generation() {
|
||||
|
||||
@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
generation::Shadow,
|
||||
model::table::{SimValue, Table},
|
||||
model::table::{SimValue, Table}, runner::env::SimulatorTables,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@@ -15,7 +15,7 @@ pub(crate) struct Create {
|
||||
impl Shadow for Create {
|
||||
type Result = anyhow::Result<Vec<Vec<SimValue>>>;
|
||||
|
||||
fn shadow(&self, tables: &mut Vec<Table>) -> Self::Result {
|
||||
fn shadow(&self, tables: &mut SimulatorTables) -> Self::Result {
|
||||
if !tables.iter().any(|t| t.name == self.table.name) {
|
||||
tables.push(self.table.clone());
|
||||
Ok(vec![])
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
generation::{gen_random_text, pick, pick_n_unique, ArbitraryFrom, Shadow},
|
||||
model::table::{SimValue, Table},
|
||||
runner::env::SimulatorEnv,
|
||||
model::table::SimValue,
|
||||
runner::env::{SimulatorEnv, SimulatorTables},
|
||||
};
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -30,7 +30,7 @@ pub(crate) struct CreateIndex {
|
||||
|
||||
impl Shadow for CreateIndex {
|
||||
type Result = Vec<Vec<SimValue>>;
|
||||
fn shadow(&self, _env: &mut Vec<Table>) -> Vec<Vec<SimValue>> {
|
||||
fn shadow(&self, _env: &mut SimulatorTables) -> Vec<Vec<SimValue>> {
|
||||
// CREATE INDEX doesn't require any shadowing; we don't need to keep track
|
||||
// in the simulator what indexes exist.
|
||||
vec![]
|
||||
|
||||
@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
generation::Shadow,
|
||||
model::table::{SimValue, Table},
|
||||
model::table::SimValue, runner::env::SimulatorTables,
|
||||
};
|
||||
|
||||
use super::predicate::Predicate;
|
||||
@@ -18,8 +18,8 @@ pub(crate) struct Delete {
|
||||
impl Shadow for Delete {
|
||||
type Result = anyhow::Result<Vec<Vec<SimValue>>>;
|
||||
|
||||
fn shadow(&self, tables: &mut Vec<Table>) -> Self::Result {
|
||||
let table = tables.iter_mut().find(|t| t.name == self.table);
|
||||
fn shadow(&self, tables: &mut SimulatorTables) -> Self::Result {
|
||||
let table = tables.tables.iter_mut().find(|t| t.name == self.table);
|
||||
|
||||
if let Some(table) = table {
|
||||
// If the table exists, we can delete from it
|
||||
|
||||
@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
generation::Shadow,
|
||||
model::table::{SimValue, Table},
|
||||
model::table::SimValue, runner::env::SimulatorTables,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
@@ -15,7 +15,7 @@ pub(crate) struct Drop {
|
||||
impl Shadow for Drop {
|
||||
type Result = anyhow::Result<Vec<Vec<SimValue>>>;
|
||||
|
||||
fn shadow(&self, tables: &mut Vec<Table>) -> Self::Result {
|
||||
fn shadow(&self, tables: &mut SimulatorTables) -> Self::Result {
|
||||
if !tables.iter().any(|t| t.name == self.table) {
|
||||
// If the table does not exist, we return an error
|
||||
return Err(anyhow::anyhow!(
|
||||
@@ -24,7 +24,7 @@ impl Shadow for Drop {
|
||||
));
|
||||
}
|
||||
|
||||
tables.retain(|t| t.name != self.table);
|
||||
tables.tables.retain(|t| t.name != self.table);
|
||||
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
generation::Shadow,
|
||||
model::table::{SimValue, Table},
|
||||
model::table::SimValue, runner::env::SimulatorTables,
|
||||
};
|
||||
|
||||
use super::select::Select;
|
||||
@@ -24,10 +24,10 @@ pub(crate) enum Insert {
|
||||
impl Shadow for Insert {
|
||||
type Result = anyhow::Result<Vec<Vec<SimValue>>>;
|
||||
|
||||
fn shadow(&self, tables: &mut Vec<Table>) -> Self::Result {
|
||||
fn shadow(&self, tables: &mut SimulatorTables) -> Self::Result {
|
||||
match self {
|
||||
Insert::Values { table, values } => {
|
||||
if let Some(t) = tables.iter_mut().find(|t| &t.name == table) {
|
||||
if let Some(t) = tables.tables.iter_mut().find(|t| &t.name == table) {
|
||||
t.rows.extend(values.clone());
|
||||
} else {
|
||||
return Err(anyhow::anyhow!(
|
||||
@@ -38,7 +38,7 @@ impl Shadow for Insert {
|
||||
}
|
||||
Insert::Select { table, select } => {
|
||||
let rows = select.shadow(tables)?;
|
||||
if let Some(t) = tables.iter_mut().find(|t| &t.name == table) {
|
||||
if let Some(t) = tables.tables.iter_mut().find(|t| &t.name == table) {
|
||||
t.rows.extend(rows);
|
||||
} else {
|
||||
return Err(anyhow::anyhow!(
|
||||
|
||||
@@ -12,12 +12,8 @@ use update::Update;
|
||||
|
||||
use crate::{
|
||||
generation::Shadow,
|
||||
model::table::{SimValue, Table},
|
||||
model::{
|
||||
query::transaction::{Begin, Commit, Rollback},
|
||||
table::SimValue,
|
||||
},
|
||||
runner::env::SimulatorEnv,
|
||||
model::{query::transaction::{Begin, Commit, Rollback}, table::SimValue},
|
||||
runner::env::SimulatorTables,
|
||||
};
|
||||
|
||||
pub mod create;
|
||||
@@ -79,7 +75,7 @@ impl Query {
|
||||
impl Shadow for Query {
|
||||
type Result = anyhow::Result<Vec<Vec<SimValue>>>;
|
||||
|
||||
fn shadow(&self, env: &mut Vec<Table>) -> Self::Result {
|
||||
fn shadow(&self, env: &mut SimulatorTables) -> Self::Result {
|
||||
match self {
|
||||
Query::Create(create) => create.shadow(env),
|
||||
Query::Insert(insert) => insert.shadow(env),
|
||||
@@ -88,9 +84,9 @@ impl Shadow for Query {
|
||||
Query::Update(update) => update.shadow(env),
|
||||
Query::Drop(drop) => drop.shadow(env),
|
||||
Query::CreateIndex(create_index) => Ok(create_index.shadow(env)),
|
||||
Query::Begin(begin) => begin.shadow(env),
|
||||
Query::Commit(commit) => commit.shadow(env),
|
||||
Query::Rollback(rollback) => rollback.shadow(env),
|
||||
Query::Begin(begin) => Ok(begin.shadow(env)),
|
||||
Query::Commit(commit) => Ok(commit.shadow(env)),
|
||||
Query::Rollback(rollback) => Ok(rollback.shadow(env)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::{
|
||||
model::{
|
||||
query::EmptyContext,
|
||||
table::{SimValue, Table},
|
||||
},
|
||||
}, runner::env::SimulatorTables,
|
||||
};
|
||||
|
||||
use super::predicate::Predicate;
|
||||
@@ -253,7 +253,9 @@ impl JoinTable {
|
||||
|
||||
impl Shadow for FromClause {
|
||||
type Result = anyhow::Result<JoinTable>;
|
||||
fn shadow(&self, tables: &mut Vec<Table>) -> Self::Result {
|
||||
fn shadow(&self, env: &mut SimulatorTables) -> Self::Result {
|
||||
let tables = &mut env.tables;
|
||||
|
||||
let first_table = tables
|
||||
.iter()
|
||||
.find(|t| t.name == self.table)
|
||||
@@ -309,7 +311,7 @@ impl Shadow for FromClause {
|
||||
impl Shadow for SelectInner {
|
||||
type Result = anyhow::Result<JoinTable>;
|
||||
|
||||
fn shadow(&self, env: &mut Vec<Table>) -> Self::Result {
|
||||
fn shadow(&self, env: &mut SimulatorTables) -> Self::Result {
|
||||
let mut join_table = self.from.shadow(env)?;
|
||||
let as_table = join_table.clone().into_table();
|
||||
for row in &mut join_table.rows {
|
||||
@@ -336,7 +338,7 @@ impl Shadow for SelectInner {
|
||||
impl Shadow for Select {
|
||||
type Result = anyhow::Result<Vec<Vec<SimValue>>>;
|
||||
|
||||
fn shadow(&self, env: &mut Vec<Table>) -> Self::Result {
|
||||
fn shadow(&self, env: &mut SimulatorTables) -> Self::Result {
|
||||
let first_result = self.body.select.shadow(env)?;
|
||||
|
||||
let mut rows = first_result.into_table().rows;
|
||||
|
||||
@@ -2,7 +2,11 @@ use std::fmt::Display;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{model::table::SimValue, runner::env::SimulatorEnv};
|
||||
use crate::{
|
||||
generation::Shadow,
|
||||
model::table::SimValue,
|
||||
runner::env::SimulatorTables,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub(crate) struct Begin {
|
||||
@@ -15,24 +19,27 @@ pub(crate) struct Commit;
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub(crate) struct Rollback;
|
||||
|
||||
impl Begin {
|
||||
pub(crate) fn shadow(&self, env: &mut SimulatorEnv) -> Vec<Vec<SimValue>> {
|
||||
env.tables_snapshot = Some(env.tables.clone());
|
||||
impl Shadow for Begin {
|
||||
type Result = Vec<Vec<SimValue>>;
|
||||
fn shadow(&self, tables: &mut SimulatorTables) -> Self::Result {
|
||||
tables.snapshot = Some(tables.tables.clone());
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
impl Commit {
|
||||
pub(crate) fn shadow(&self, env: &mut SimulatorEnv) -> Vec<Vec<SimValue>> {
|
||||
env.tables_snapshot = None;
|
||||
impl Shadow for Commit {
|
||||
type Result = Vec<Vec<SimValue>>;
|
||||
fn shadow(&self, tables: &mut SimulatorTables) -> Self::Result {
|
||||
tables.snapshot = None;
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
impl Rollback {
|
||||
pub(crate) fn shadow(&self, env: &mut SimulatorEnv) -> Vec<Vec<SimValue>> {
|
||||
if let Some(tables) = env.tables_snapshot.take() {
|
||||
env.tables = tables;
|
||||
impl Shadow for Rollback {
|
||||
type Result = Vec<Vec<SimValue>>;
|
||||
fn shadow(&self, tables: &mut SimulatorTables) -> Self::Result {
|
||||
if let Some(tables_) = tables.snapshot.take() {
|
||||
tables.tables = tables_;
|
||||
}
|
||||
vec![]
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
generation::Shadow,
|
||||
model::table::{SimValue, Table},
|
||||
model::table::SimValue, runner::env::SimulatorTables,
|
||||
};
|
||||
|
||||
use super::predicate::Predicate;
|
||||
@@ -19,8 +19,8 @@ pub(crate) struct Update {
|
||||
impl Shadow for Update {
|
||||
type Result = anyhow::Result<Vec<Vec<SimValue>>>;
|
||||
|
||||
fn shadow(&self, tables: &mut Vec<Table>) -> Self::Result {
|
||||
let table = tables.iter_mut().find(|t| t.name == self.table);
|
||||
fn shadow(&self, tables: &mut SimulatorTables) -> Self::Result {
|
||||
let table = tables.tables.iter_mut().find(|t| t.name == self.table);
|
||||
|
||||
let table = if let Some(table) = table {
|
||||
table
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::fmt::Display;
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
use std::panic::UnwindSafe;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
@@ -27,9 +28,39 @@ pub(crate) enum SimulationPhase {
|
||||
Shrink,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct SimulatorTables {
|
||||
pub(crate) tables: Vec<Table>,
|
||||
pub(crate) snapshot: Option<Vec<Table>>,
|
||||
}
|
||||
impl SimulatorTables {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
tables: Vec::new(),
|
||||
snapshot: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn clear(&mut self) {
|
||||
self.tables.clear();
|
||||
self.snapshot = None;
|
||||
}
|
||||
|
||||
pub(crate) fn push(&mut self, table: Table) {
|
||||
self.tables.push(table);
|
||||
}
|
||||
}
|
||||
impl Deref for SimulatorTables {
|
||||
type Target = Vec<Table>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.tables
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct SimulatorEnv {
|
||||
pub(crate) opts: SimulatorOpts,
|
||||
pub(crate) tables: Vec<Table>,
|
||||
pub(crate) connections: Vec<SimConnection>,
|
||||
pub(crate) io: Arc<SimulatorIO>,
|
||||
pub(crate) db: Arc<Database>,
|
||||
@@ -37,7 +68,7 @@ pub(crate) struct SimulatorEnv {
|
||||
pub(crate) paths: Paths,
|
||||
pub(crate) type_: SimulationType,
|
||||
pub(crate) phase: SimulationPhase,
|
||||
pub tables_snapshot: Option<Vec<Table>>,
|
||||
pub(crate) tables: SimulatorTables,
|
||||
}
|
||||
|
||||
impl UnwindSafe for SimulatorEnv {}
|
||||
@@ -56,7 +87,6 @@ impl SimulatorEnv {
|
||||
paths: self.paths.clone(),
|
||||
type_: self.type_,
|
||||
phase: self.phase,
|
||||
tables_snapshot: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,7 +276,7 @@ impl SimulatorEnv {
|
||||
|
||||
SimulatorEnv {
|
||||
opts,
|
||||
tables: Vec::new(),
|
||||
tables: SimulatorTables::new(),
|
||||
connections,
|
||||
paths,
|
||||
rng,
|
||||
@@ -254,7 +284,6 @@ impl SimulatorEnv {
|
||||
db,
|
||||
type_: simulation_type,
|
||||
phase: SimulationPhase::Test,
|
||||
tables_snapshot: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -896,6 +896,7 @@ pub struct FromClause {
|
||||
pub select: Option<Box<SelectTable>>, // FIXME mandatory
|
||||
/// `JOIN`ed tabled
|
||||
pub joins: Option<Vec<JoinedSelectTable>>,
|
||||
/// A default join operator
|
||||
pub op: Option<JoinOperator>, // FIXME transient
|
||||
}
|
||||
impl FromClause {
|
||||
|
||||
Reference in New Issue
Block a user