Rustでデータベースを設計しよう8(create tableのパーサ)

use regex::Regex;

fn main() {
    
    let text = "CREATE TABLE users (
        id integer,
        name text,
        age integer,
    );";
    println!("{}", text);

    let table_re = Regex::new(r"(?i)create\s+table\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\((?s)(.*?)\)").unwrap();

    if let Some(caps) = table_re.captures(text) {
        let table_name = &caps[1];
        let columns_str = &caps[2];
        println!("table name: {}", table_name);

        let column_re = Regex::new(r"(?i)([a-zA-Z_][a-zA-Z0-9_]*)\s+([a-zA-Z0-9()]+)").unwrap();

        for line in columns_str.lines() {
            if let Some(col_caps) = column_re.captures(line.trim()) {
                let column_name = &col_caps[1];
                let column_type = &col_caps[2];
                println!(" column name: {}, type: {}", column_name, column_type);
            }
        }
    } else {
        println!("CREATE TABLE 文ではありません");
    }
}

CREATE TABLE users (
id integer,
name text,
age integer,
);
table name: users
column name: id, type: integer
column name: name, type: text
column name: age, type: integer

これにprimary keyなどのconstrainも追加したい…

fn main() {
    
    let text = "CREATE TABLE users (
        id integer primarykey,
        name text not null,
        age integer
    );";
    println!("{}", text);

    let table_re = Regex::new(r"(?is)create\s+table\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\((.*?)\)").unwrap();

    if let Some(caps) = table_re.captures(text) {
        let table_name = &caps[1];
        let columns_str = &caps[2];
        println!("table name: {}", table_name);

        let column_re = Regex::new(r"(?i)^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s+([a-zA-Z0-9()]+)(?:\s+(.*))?[,]?$").unwrap();

        for line in columns_str.lines() {

            let line = line.trim();
            if line.is_empty() {
                continue;
            }


            if let Some(col_caps) = column_re.captures(line) {
                let column_name = &col_caps[1];
                let column_type = &col_caps[2];
                let constraint = col_caps.get(3).map_or("", |m| m.as_str()).trim();
                println!(" column name: {}, type: {}, constraint: {}", column_name, column_type, if constraint.is_empty() { "None" } else { constraint });
            } else {
                println!(" ignored row: {}", line);
            }
        }
    } else {
        println!("CREATE TABLE 文ではありません");
    }
}

CREATE TABLE users (
id integer primarykey,
name text not null,
age integer
);
table name: users
column name: id, type: integer, constraint: primarykey,
column name: name, type: text, constraint: not null,
column name: age, type: integer, constraint: None