Skip to main content

pg2sqlite_core/ir/
model.rs

1/// Core IR model types for representing parsed DDL schemas.
2use super::expr::Expr;
3use super::ident::{Ident, QualifiedName};
4use super::types::{PgType, SqliteType};
5
6/// The top-level schema model containing all parsed DDL objects.
7#[derive(Debug, Clone, Default)]
8pub struct SchemaModel {
9    pub tables: Vec<Table>,
10    pub indexes: Vec<Index>,
11    pub sequences: Vec<Sequence>,
12    pub enums: Vec<EnumDef>,
13    pub domains: Vec<DomainDef>,
14    pub alter_constraints: Vec<AlterConstraint>,
15}
16
17/// A parsed CREATE TABLE statement.
18#[derive(Debug, Clone)]
19pub struct Table {
20    pub name: QualifiedName,
21    pub columns: Vec<Column>,
22    pub constraints: Vec<TableConstraint>,
23}
24
25/// A column definition within a table.
26#[derive(Debug, Clone)]
27pub struct Column {
28    pub name: Ident,
29    pub pg_type: PgType,
30    pub sqlite_type: Option<SqliteType>,
31    pub not_null: bool,
32    pub default: Option<Expr>,
33    pub is_primary_key: bool,
34    pub is_unique: bool,
35    pub references: Option<ForeignKeyRef>,
36    pub check: Option<Expr>,
37}
38
39/// Table-level constraint.
40#[derive(Debug, Clone)]
41pub enum TableConstraint {
42    PrimaryKey {
43        name: Option<Ident>,
44        columns: Vec<Ident>,
45    },
46    Unique {
47        name: Option<Ident>,
48        columns: Vec<Ident>,
49    },
50    ForeignKey {
51        name: Option<Ident>,
52        columns: Vec<Ident>,
53        ref_table: QualifiedName,
54        ref_columns: Vec<Ident>,
55        on_delete: Option<FkAction>,
56        on_update: Option<FkAction>,
57        deferrable: bool,
58    },
59    Check {
60        name: Option<Ident>,
61        expr: Expr,
62    },
63}
64
65/// An ALTER TABLE ... ADD CONSTRAINT that needs merging.
66#[derive(Debug, Clone)]
67pub struct AlterConstraint {
68    pub table: QualifiedName,
69    pub constraint: TableConstraint,
70}
71
72/// Foreign key reference from a column-level constraint.
73#[derive(Debug, Clone)]
74pub struct ForeignKeyRef {
75    pub table: QualifiedName,
76    pub column: Option<Ident>,
77    pub on_delete: Option<FkAction>,
78    pub on_update: Option<FkAction>,
79}
80
81/// Foreign key referential action.
82#[derive(Debug, Clone, Copy, PartialEq, Eq)]
83pub enum FkAction {
84    Cascade,
85    SetNull,
86    SetDefault,
87    Restrict,
88    NoAction,
89}
90
91impl std::fmt::Display for FkAction {
92    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93        match self {
94            FkAction::Cascade => write!(f, "CASCADE"),
95            FkAction::SetNull => write!(f, "SET NULL"),
96            FkAction::SetDefault => write!(f, "SET DEFAULT"),
97            FkAction::Restrict => write!(f, "RESTRICT"),
98            FkAction::NoAction => write!(f, "NO ACTION"),
99        }
100    }
101}
102
103/// A CREATE INDEX statement.
104#[derive(Debug, Clone)]
105pub struct Index {
106    pub name: Ident,
107    pub table: QualifiedName,
108    pub columns: Vec<IndexColumn>,
109    pub unique: bool,
110    pub method: Option<IndexMethod>,
111    pub where_clause: Option<Expr>,
112}
113
114/// A column or expression in an index.
115#[derive(Debug, Clone)]
116pub enum IndexColumn {
117    Column(Ident),
118    Expression(Expr),
119}
120
121/// Index access method.
122#[derive(Debug, Clone, Copy, PartialEq, Eq)]
123pub enum IndexMethod {
124    Btree,
125    Hash,
126    Gin,
127    Gist,
128    SpGist,
129    Brin,
130}
131
132impl std::fmt::Display for IndexMethod {
133    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134        match self {
135            IndexMethod::Btree => write!(f, "btree"),
136            IndexMethod::Hash => write!(f, "hash"),
137            IndexMethod::Gin => write!(f, "gin"),
138            IndexMethod::Gist => write!(f, "gist"),
139            IndexMethod::SpGist => write!(f, "spgist"),
140            IndexMethod::Brin => write!(f, "brin"),
141        }
142    }
143}
144
145/// A CREATE SEQUENCE statement.
146#[derive(Debug, Clone)]
147pub struct Sequence {
148    pub name: QualifiedName,
149    pub owned_by: Option<(QualifiedName, Ident)>,
150}
151
152/// A CREATE TYPE ... AS ENUM statement.
153#[derive(Debug, Clone)]
154pub struct EnumDef {
155    pub name: QualifiedName,
156    pub values: Vec<String>,
157}
158
159/// A CREATE DOMAIN statement.
160#[derive(Debug, Clone)]
161pub struct DomainDef {
162    pub name: QualifiedName,
163    pub base_type: PgType,
164    pub not_null: bool,
165    pub default: Option<Expr>,
166    pub check: Option<Expr>,
167}