Skip to content

Commit

Permalink
feat: Add SQL parsing and relational object construction
Browse files Browse the repository at this point in the history
- Implement `read_desired_state` function to read and process SQL files from a directory structure.
- Add `build_relational_object` function to construct `RelationalObject` from SQL content.
- Introduce `SqlVisitor` struct to visit and extract object names from SQL statements.
- Create `Stmt` struct to represent statements with metadata.
- Implement `parse_change_stmts` function to parse SQL statements with delimiters.
- Add `determine_execution_order` function to determine execution order of relational objects based on dependencies.
- Include unit tests for `parse_change_stmts` function to ensure correct parsing behavior.

This commit enhances the ability to read, parse, and process SQL files, building a graph representation of database objects and their dependencies.

Signed-off-by: Gabriel de Maeztu <[email protected]>
  • Loading branch information
merqurio committed Aug 24, 2024
1 parent eb4fe00 commit e43e300
Showing 1 changed file with 18 additions and 14 deletions.
32 changes: 18 additions & 14 deletions src/reference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ use crate::utils::topsort::topo_sort;
use indexmap::IndexMap;
use sqlparser::dialect::GenericDialect;
use sqlparser::parser::Parser;
use sqlparser::ast::{Visit, Visitor};
use sqlparser::ast::{Visitor, ObjectName, Statement};
use std::collections::{HashMap, HashSet};
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use walkdir::WalkDir;
use core::ops::ControlFlow;

/// Reads and processes a directory containing multiple subdirectories, each representing a type of
/// database object.
Expand Down Expand Up @@ -154,7 +155,7 @@ fn build_relational_object(
.ok_or("No objects found in parsed content")?;

let mut visitor = SqlVisitor::new();
visitor.visit_statement(first_object);
visitor.pre_visit_statement(first_object); // Use pre_visit_statement method

let object_name = file_path
.file_stem()
Expand Down Expand Up @@ -207,40 +208,43 @@ impl SqlVisitor {
schema_name: String::new(),
}
}
}

impl Visitor for SqlVisitor {
type Break = ();

fn visit_statement(&mut self, stmt: &sqlparser::ast::Statement) {
fn pre_visit_statement(&mut self, stmt: &Statement) -> ControlFlow<Self::Break> {
match stmt {
sqlparser::ast::Statement::CreateTable(stmt) => {
Statement::CreateTable(stmt) => {
self.visit_object_name(&stmt.name);
}
sqlparser::ast::Statement::CreateView { name, .. } => {
Statement::CreateView { name, .. } => {
self.visit_object_name(name);
}
sqlparser::ast::Statement::CreateFunction { name, .. } => {
Statement::CreateFunction { name, .. } => {
self.visit_object_name(name);
}
sqlparser::ast::Statement::CreateProcedure { name, .. } => {
Statement::CreateProcedure { name, .. } => {
self.visit_object_name(name);
}
sqlparser::ast::Statement::CreateIndex(stmt) => {
Statement::CreateIndex(stmt) => {
if let Some(name) = &stmt.name {
self.visit_object_name(name);
}
}
sqlparser::ast::Statement::CreateSequence { name, .. } => {
Statement::CreateSequence { name, .. } => {
self.visit_object_name(name);
}
_ => {}
}
ControlFlow::Continue(())
}
}

fn visit_object_name(&mut self, name: &sqlparser::ast::ObjectName) {
impl SqlVisitor {
fn visit_object_name(&mut self, name: &ObjectName) {
self.object_name = name.to_string();
}

fn visit_schema_name(&mut self, name: &sqlparser::ast::ObjectName) {
self.schema_name = name.to_string();
}
}

/// Represents a statement with associated metadata.
Expand Down

0 comments on commit e43e300

Please sign in to comment.