Files
turso/sql_generation/generation/table.rs

64 lines
2.1 KiB
Rust

use std::sync::atomic::{AtomicU64, Ordering};
use indexmap::IndexSet;
use rand::Rng;
use crate::generation::{pick, readable_name_custom, Arbitrary, GenerationContext};
use crate::model::table::{Column, ColumnType, Name, Table};
static COUNTER: AtomicU64 = AtomicU64::new(0);
impl Arbitrary for Name {
fn arbitrary<R: Rng + ?Sized, C: GenerationContext>(rng: &mut R, _c: &C) -> Self {
let base = readable_name_custom("_", rng).replace("-", "_");
let id = COUNTER.fetch_add(1, Ordering::Relaxed);
Name(format!("{base}_{id}"))
}
}
impl Arbitrary for Table {
fn arbitrary<R: Rng + ?Sized, C: GenerationContext>(rng: &mut R, context: &C) -> Self {
let opts = context.opts().table.clone();
let name = Name::arbitrary(rng, context).0;
let large_table =
opts.large_table.enable && rng.random_bool(opts.large_table.large_table_prob);
let column_size = if large_table {
rng.random_range(opts.large_table.column_range)
} else {
rng.random_range(opts.column_range)
} as usize;
let mut column_set = IndexSet::with_capacity(column_size);
for col in std::iter::repeat_with(|| Column::arbitrary(rng, context)) {
column_set.insert(col);
if column_set.len() == column_size {
break;
}
}
Table {
rows: Vec::new(),
name,
columns: Vec::from_iter(column_set),
indexes: vec![],
}
}
}
impl Arbitrary for Column {
fn arbitrary<R: Rng + ?Sized, C: GenerationContext>(rng: &mut R, context: &C) -> Self {
let name = Name::arbitrary(rng, context).0;
let column_type = ColumnType::arbitrary(rng, context);
Self {
name,
column_type,
constraints: vec![], // TODO: later implement arbitrary here for ColumnConstraint
}
}
}
impl Arbitrary for ColumnType {
fn arbitrary<R: Rng + ?Sized, C: GenerationContext>(rng: &mut R, _context: &C) -> Self {
pick(&[Self::Integer, Self::Float, Self::Text, Self::Blob], rng).to_owned()
}
}