Fix README example; Begin implementing insert
This commit is contained in:
parent
7fef56f90d
commit
75f16a3afe
@ -193,7 +193,9 @@ Querying a table is similar to SQL.
|
||||
|
||||
```dust
|
||||
names = select name from animals
|
||||
youngins = select species from animals where age <= 10
|
||||
youngins = select species from animals {
|
||||
age <= 10
|
||||
}
|
||||
```
|
||||
|
||||
The keywords `table` and `insert` make sure that all of the memory used to hold the rows is allocated at once, so it is good practice to group your rows together instead of using a call for each row.
|
||||
|
@ -15,12 +15,29 @@ test_select = select <text bool> from my_table
|
||||
(assert_equal test_select, test_table)
|
||||
|
||||
test_table = table <text number bool> [
|
||||
["a", 1, true]
|
||||
["a", 3, true]
|
||||
[1, true]
|
||||
[3, true]
|
||||
]
|
||||
|
||||
test_select_where = select <> from my_table {
|
||||
test_select_where = select <number, bool> from my_table {
|
||||
text == "a"
|
||||
}
|
||||
|
||||
(assert_equal test_select_where, test_table)
|
||||
|
||||
test_table = table <text number bool> [
|
||||
["a", 1, true]
|
||||
["b", 2, true]
|
||||
["a", 3, true]
|
||||
["c", 4, true]
|
||||
["d", 5, true]
|
||||
["e", 6, true]
|
||||
]
|
||||
|
||||
insert into my_table [
|
||||
["c", 4, true]
|
||||
["d", 5, true]
|
||||
["e", 6, true]
|
||||
]
|
||||
|
||||
(assert_equal test_table, my_table)
|
||||
|
40
src/abstract_tree/insert.rs
Normal file
40
src/abstract_tree/insert.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tree_sitter::Node;
|
||||
|
||||
use crate::{AbstractTree, Expression, Identifier, Item, Result, Value, VariableMap};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
|
||||
pub struct Insert {
|
||||
identifier: Identifier,
|
||||
expression: Expression,
|
||||
}
|
||||
|
||||
impl AbstractTree for Insert {
|
||||
fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
|
||||
let identifier_node = node.child(1).unwrap();
|
||||
let identifier = Identifier::from_syntax_node(source, identifier_node)?;
|
||||
let expression_node = node.child(3).unwrap();
|
||||
let expression = Expression::from_syntax_node(source, expression_node)?;
|
||||
|
||||
Ok(Insert {
|
||||
identifier,
|
||||
expression,
|
||||
})
|
||||
}
|
||||
|
||||
fn run(&self, source: &str, context: &mut VariableMap) -> Result<Value> {
|
||||
let table_name = self.identifier.inner().clone();
|
||||
let mut table = self.identifier.run(source, context)?.as_table()?.clone();
|
||||
let new_rows = self.expression.run(source, context)?.into_inner_list()?;
|
||||
|
||||
table.reserve(new_rows.len());
|
||||
|
||||
for row in new_rows {
|
||||
table.insert(row.into_inner_list()?)?;
|
||||
}
|
||||
|
||||
context.set_value(table_name, Value::Table(table))?;
|
||||
|
||||
Ok(Value::Empty)
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ pub mod r#for;
|
||||
pub mod function_call;
|
||||
pub mod identifier;
|
||||
pub mod if_else;
|
||||
pub mod insert;
|
||||
pub mod item;
|
||||
pub mod logic;
|
||||
pub mod r#match;
|
||||
@ -29,8 +30,8 @@ pub mod r#while;
|
||||
|
||||
pub use {
|
||||
assignment::*, expression::*, filter::*, find::*, function_call::*, identifier::*, if_else::*,
|
||||
item::*, logic::*, math::*, r#async::*, r#for::*, r#match::*, r#while::*, remove::*, select::*,
|
||||
statement::*, tool::*, transform::*, value_node::*,
|
||||
insert::*, item::*, logic::*, math::*, r#async::*, r#for::*, r#match::*, r#while::*, remove::*,
|
||||
select::*, statement::*, tool::*, transform::*, value_node::*,
|
||||
};
|
||||
|
||||
use tree_sitter::Node;
|
||||
|
@ -2,8 +2,8 @@ use serde::{Deserialize, Serialize};
|
||||
use tree_sitter::Node;
|
||||
|
||||
use crate::{
|
||||
AbstractTree, Assignment, Async, Error, Expression, Filter, Find, For, IfElse, Match, Remove,
|
||||
Result, Select, Transform, Value, VariableMap, While,
|
||||
AbstractTree, Assignment, Async, Error, Expression, Filter, Find, For, IfElse, Insert, Match,
|
||||
Remove, Result, Select, Transform, Value, VariableMap, While,
|
||||
};
|
||||
|
||||
/// Abstract representation of a statement.
|
||||
@ -24,6 +24,7 @@ pub enum Statement {
|
||||
Find(Box<Find>),
|
||||
Remove(Box<Remove>),
|
||||
Select(Box<Select>),
|
||||
Insert(Box<Insert>),
|
||||
}
|
||||
|
||||
impl AbstractTree for Statement {
|
||||
@ -69,8 +70,11 @@ impl AbstractTree for Statement {
|
||||
"select" => Ok(Statement::Select(Box::new(Select::from_syntax_node(
|
||||
source, child,
|
||||
)?))),
|
||||
"insert" => Ok(Statement::Insert(Box::new(Insert::from_syntax_node(
|
||||
source, child,
|
||||
)?))),
|
||||
_ => Err(Error::UnexpectedSyntaxNode {
|
||||
expected: "assignment, expression, if...else, while, for, transform, filter, tool or async",
|
||||
expected: "assignment, expression, if...else, while, for, transform, filter, tool, async, find, remove, select or insert",
|
||||
actual: child.kind(),
|
||||
location: child.start_position(),
|
||||
relevant_source: source[child.byte_range()].to_string(),
|
||||
@ -92,6 +96,7 @@ impl AbstractTree for Statement {
|
||||
Statement::Find(find) => find.run(source, context),
|
||||
Statement::Remove(remove) => remove.run(source, context),
|
||||
Statement::Select(select) => select.run(source, context),
|
||||
Statement::Insert(insert) => insert.run(source, context),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +95,9 @@ select <number> from foobar {
|
||||
Table Insert
|
||||
==================
|
||||
|
||||
insert ['bob was here', 0] into foobar
|
||||
insert into foobar [
|
||||
['bob was here', 0]
|
||||
]
|
||||
|
||||
---
|
||||
|
||||
@ -103,11 +105,14 @@ insert ['bob was here', 0] into foobar
|
||||
(item
|
||||
(statement
|
||||
(insert
|
||||
(identifier)
|
||||
(list
|
||||
(expression
|
||||
(value
|
||||
(string)))
|
||||
(expression
|
||||
(value
|
||||
(integer))))
|
||||
(identifier)))))
|
||||
(list
|
||||
(expression
|
||||
(value
|
||||
(string)))
|
||||
(expression
|
||||
(value
|
||||
(integer)))))))))))
|
||||
|
@ -239,12 +239,9 @@ module.exports = grammar({
|
||||
|
||||
insert: $ => prec.right(seq(
|
||||
'insert',
|
||||
repeat1($.list),
|
||||
'into',
|
||||
$.identifier,
|
||||
optional(
|
||||
seq('where', $.logic)
|
||||
),
|
||||
$.expression,
|
||||
)),
|
||||
|
||||
async: $ => seq(
|
||||
|
@ -979,13 +979,6 @@
|
||||
"type": "STRING",
|
||||
"value": "insert"
|
||||
},
|
||||
{
|
||||
"type": "REPEAT1",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "list"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "into"
|
||||
@ -995,25 +988,8 @@
|
||||
"name": "identifier"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "where"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "logic"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
"type": "SYMBOL",
|
||||
"name": "expression"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1134,10 +1110,6 @@
|
||||
"type": "STRING",
|
||||
"value": "remove"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "trash"
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "write"
|
||||
|
@ -278,17 +278,13 @@
|
||||
"multiple": true,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "expression",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "list",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "logic",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -865,18 +861,10 @@
|
||||
"type": "transform",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "trash",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "true",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "where",
|
||||
"named": false
|
||||
},
|
||||
{
|
||||
"type": "while",
|
||||
"named": false
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user