iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 24
1

22: Implement Table insert

2018/11/7

It's very recommended to reade on Gitbook for better syntax support and better layout.

As I did the basic infrastructure of components, there are still lots of methods that I need to implement.

I choose Table first, and I write the insert_row method for it. Note that it still stores data in memory. It should also write to file in the future.

!FILENAME component/table.rs

    /// `insert` row into the table
    /// `key` and `value` are `&str`, and will be formated to the right type.
    pub fn insert(&mut self, row: Vec<(&str, &str)>) -> Result<(), TableError> {
        let mut new_row = Row::new();

        // insert data into row
        for (key, value) in row {
            match self.fields.get(key) {
                Some(field) => {
                    if field.not_null && value == "null" {
                        return Err(TableError::InsertFieldNotNullMismatched(field.clone().name));
                    }
                    new_row.0.insert(key.to_string(), value.to_string());
                }
                None => return Err(TableError::InsertFieldNotExisted(key.to_string())),
            }
        }

        // check if the row fits the field
        for (key, field) in self.fields.iter() {
            match new_row.0.get(key) {
                Some(_) => {}
                None => {
                    match field.clone().default {
                        // if the attribute has default value, then insert with the default value.
                        Some(value) => new_row.0.insert(key.to_string(), value.to_string()),
                        None => return Err(TableError::InsertFieldDefaultMismatched(key.to_string())),
                    };
                }
            };
        }

        self.rows.push(new_row);

        Ok(())
    }

there are also some tests for it.

!FILENAME component/table.rs

    fn test_insert_row() {
        let mut table = Table::new("table_1");
        table.fields.insert(
            "attr_1".to_string(),
            Field::new(
                "attr_1",
                DataType::Int,
                true,                    // not_null is true
                Some("123".to_string()), // default is 123
                field::Checker::None,
            ),
        );
        table.fields.insert(
            "attr_2".to_string(),
            Field::new(
                "attr_2",
                DataType::Int,
                true, // not_null is true
                None, // no default
                field::Checker::None,
            ),
        );
        table.fields.insert(
            "attr_3".to_string(),
            Field::new(
                "attr_3",
                DataType::Int,
                false, // not null is false
                None,  // no default
                field::Checker::None,
            ),
        );

        println!("correct data");
        let data = vec![("attr_1", "123"), ("attr_2", "123"), ("attr_3", "123")];
        assert!(table.insert_row(data).is_ok());

        println!("`attr_2` is null while its not_null is true");
        let data = vec![("attr_1", "123"), ("attr_2", "null"), ("attr_3", "123")];
        assert!(table.insert_row(data).is_err());

        println!("`attr_3` is null while its not_null is false");
        let data = vec![("attr_1", "123"), ("attr_2", "123"), ("attr_3", "null")];
        assert!(table.insert_row(data).is_ok());

        println!("none given value `attr_2` while its default is None");
        let data = vec![("attr_1", "123"), ("attr_3", "123")];
        assert!(table.insert_row(data).is_err());

        println!("none given value `attr_1` while it has default");
        let data = vec![("attr_2", "123"), ("attr_3", "123")];
        assert!(table.insert_row(data).is_ok());

        println!("fields mismatched");
        let data = vec![
            ("attr_1", "123"),
            ("attr_2", "123"),
            ("attr_3", "123"),
            ("attr_4", "123"),
        ];
        assert!(table.insert_row(data).is_err());
        let data = vec![("attr_1", "123")];
        assert!(table.insert_row(data).is_err());
    }

Quick Link
1.StellarSQL Repository
2.Gitbook of this series

Author
Liu, An-Chi (劉安齊). A software engineer, who loves writing code and promoting CS to people. Welcome to follow me at Facebook Page. More information on Personal Site and Github.


上一篇
StellarSQL 22: Update Components of Database
下一篇
StellarSQL 24: Different Client Design of DBMS
系列文
Let's build a DBMS: StellarSQL -- a minimal SQL DBMS written in Rust30

尚未有邦友留言

立即登入留言