Rustでデータベースを設計しよう1

### Column
カラムは、カラム名と制約が1対1になるので、hashmapを使用する

fn main() {
    let mut columns = HashMap::new();
    columns.insert("id", "integer");
    columns.insert("name", "text");
    columns.insert("age", "integer");

    println!("{:?}", columns);
}

{“name”: “text”, “age”: “integer”, “id”: “integer”}

構造体で書くと以下のようになるが、かなり冗長だ。

#[derive(Debug)]
struct Column {
    name: String,
    constraint: String,
}

#[derive(Debug)]
struct Columns {
    columns: Vec<Column>,
}

fn main() {
    let columns = Columns {
        columns: vec![
            Column {
                name: "id".to_string(),
                constraint: "integer".to_string(),
            },
            Column {
                name: "name".to_string(),
                constraint: "text".to_string(),
            },
            Column {
                name: "age".to_string(),
                constraint: "integer".to_string(),
            },
        ]
    };

    println!("{:?}", columns);
}

### Table
テーブルに対して、上記のカラムがある

#[derive(Debug)]
struct Column {
    name: String,
    constraint: String,
}

#[derive(Debug)]
struct Columns {
    columns: Vec<Column>,
}

#[derive(Debug)]
struct Table {
    name: String,
    columns: Columns,
}


fn main() {
    let columns = Columns {
        columns: vec![
            Column {
                name: "id".to_string(),
                constraint: "integer".to_string(),
            },
            Column {
                name: "name".to_string(),
                constraint: "text".to_string(),
            },
            Column {
                name: "age".to_string(),
                constraint: "integer".to_string(),
            },
        ]
    };

    let table = Table {
        name: "users".to_string(),
        columns: columns,
    };
    println!("{:?}", table);
}

Table { name: “users”, columns: Columns { columns: [Column { name: “id”, constraint: “integer” }, Column { name: “name”, constraint: “text” }, Column { name: “age”, constraint: “integer” }] } }

### 実データを挿入する

#[derive(Debug)]
struct Column {
    name: String,
    constraint: String,
}

#[derive(Debug)]
struct Columns {
    columns: Vec<Column>,
}

#[derive(Debug)]
struct Table {
    name: String,
    columns: Columns,
    rows: Vec<Vec<String>>,
}


fn main() {
    let columns = Columns {
        columns: vec![
            Column {
                name: "id".to_string(),
                constraint: "integer".to_string(),
            },
            Column {
                name: "name".to_string(),
                constraint: "text".to_string(),
            },
            Column {
                name: "age".to_string(),
                constraint: "integer".to_string(),
            },
        ]
    };

    let rows = vec![
        vec!["1".to_string(), "Alice".to_string(), "30".to_string()],
        vec!["2".to_string(), "Bob".to_string(), "25".to_string()],
    ];

    let table = Table {
        name: "users".to_string(),
        columns: columns,
        rows: rows,
    };
    println!("{:?}", table);
}

### データ型をenumで定義する

#[derive(Debug, Clone)]
enum Value {
    Integer(i32),
    Float(f64),
    Text(String),
    Boolean(bool),
    Date(NaiveDate),
    DateTime(NaiveDateTime),
    Time(NaiveTime),
    Null,
    Binary(Vec<u8>),
    UUID(Uuid),
    Json(JsonValue),
    Decimal(Decimal),
}

データ挿入の書き方は以下のようになる。

    let rows = vec![
        vec![Value::Integer(1), Value::Text("Alice".to_string()), Value::Integer(30)],
        vec![Value::Integer(2), Value::Text("Bob".to_string()), Value::Integer(25)],
    ];

Table { name: “users”, columns: Columns { columns: [Column { name: “id”, constraint: “integer” }, Column { name: “name”, constraint: “text” }, Column { name: “age”, constraint: “integer” }] }, rows: [[Integer(1), Text(“Alice”), Integer(30)], [Integer(2), Text(“Bob”), Integer(25)]] }

データ挿入のところをimplで書きたい。