diff --git a/vlib/orm/orm_test.v b/vlib/orm/orm_test.v index 25233f7b1f..b9a0c83f37 100644 --- a/vlib/orm/orm_test.v +++ b/vlib/orm/orm_test.v @@ -1,6 +1,7 @@ import os import pg import term +import sqlite struct Modules { id int @@ -10,7 +11,30 @@ struct Modules { //nr_downloads int } -fn test_orm() { +fn test_orm_sqlite() { + db := sqlite.connect(':memory:') or { panic(err) } + /* + db.exec("drop table if exists users") + db.exec("create table users (id integer primary key, name text default '');") + + db.exec("insert into users (name) values ('Sam')") + db.exec("insert into users (name) values ('Peter')") + db.exec("insert into users (name) values ('Kate')") + nr_users := sql db { + //select count from modules + } + assert nr_users == 3 + println('nr_users=') + println(nr_users) + //nr_modules := db.select count from modules + //nr_modules := db.select count from Modules where id == 1 + //nr_modules := db.select count from Modules where + //name == 'Bob' && id == 1 + */ +} + + +fn test_orm_pg() { dbname := os.getenv('VDB_NAME') dbuser := os.getenv('VDB_USER') if dbname == '' || dbuser == '' { @@ -18,6 +42,7 @@ fn test_orm() { return } db := pg.connect(dbname: dbname, user: dbuser) or { panic(err) } + _ = db /* //nr_modules := db.select count from modules //nr_modules := db.select count from Modules where id == 1 diff --git a/vlib/sqlite/sqlite.v b/vlib/sqlite/sqlite.v index 96da51d462..4d0619e821 100644 --- a/vlib/sqlite/sqlite.v +++ b/vlib/sqlite/sqlite.v @@ -27,9 +27,11 @@ fn C.sqlite3_finalize() fn C.sqlite3_column_count(voidptr) int // Opens the connection with a database. -pub fn connect(path string) DB { +pub fn connect(path string) ?DB { db := &C.sqlite3(0) - C.sqlite3_open(path.str, &db) + if C.sqlite3_open(path.str, &db) != 0 { + return error('sqlite db error') + } return DB{ conn: db } diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 0fe52b3cd0..5cd81406ff 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -11,9 +11,9 @@ pub type TypeDecl = AliasTypeDecl | FnTypeDecl | SumTypeDecl pub type Expr = AnonFn | ArrayInit | AsCast | AssignExpr | Assoc | BoolLiteral | CallExpr | CastExpr | CharLiteral | ComptimeCall | ConcatExpr | EnumVal | FloatLiteral | Ident | IfExpr | - IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | MapInit | MatchExpr | None | OrExpr | - ParExpr | PostfixExpr | PrefixExpr | RangeExpr | SelectorExpr | SizeOf | StringInterLiteral | - StringLiteral | StructInit | Type | TypeOf | Likely + IfGuardExpr | IndexExpr | InfixExpr | IntegerLiteral | Likely | MapInit | MatchExpr | None | + OrExpr | ParExpr | PostfixExpr | PrefixExpr | RangeExpr | SelectorExpr | SizeOf | SqlExpr | + StringInterLiteral | StringLiteral | StructInit | Type | TypeOf pub type Stmt = AssertStmt | AssignStmt | Attr | Block | BranchStmt | Comment | CompIf | ConstDecl | DeferStmt | EnumDecl | ExprStmt | FnDecl | ForCStmt | ForInStmt | ForStmt | GlobalDecl | GoStmt | @@ -764,8 +764,8 @@ pub: pub struct Likely { pub: - expr Expr - pos token.Position + expr Expr + pos token.Position is_likely bool // false for _unlikely_ } @@ -796,7 +796,6 @@ pub: method_name string left Expr is_vweb bool - // vweb_stmts []Stmt vweb_tmpl File pub mut: sym table.TypeSymbol @@ -804,8 +803,12 @@ pub mut: pub struct None { pub: - pos token.Position - foo int // todo + pos token.Position + foo int // todo +} + +pub struct SqlExpr { + typ table.Type } [inline] diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 6c4e36a78a..7c5303bfab 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -10,7 +10,6 @@ import v.pref import v.token import v.util import v.depgraph -import term // NB: keywords after 'new' are reserved in C++ const ( @@ -1481,6 +1480,9 @@ fn (mut g Gen) expr(node ast.Expr) { ast.None { g.write('opt_none()') } + ast.OrExpr { + // this should never appear here + } ast.ParExpr { g.write('(') g.expr(it.expr) @@ -1501,6 +1503,9 @@ fn (mut g Gen) expr(node ast.Expr) { // g.write(')') g.is_amp = false } + ast.RangeExpr { + // Only used in IndexExpr + } ast.SizeOf { mut styp := it.type_name if it.type_name == '' { @@ -1521,6 +1526,9 @@ fn (mut g Gen) expr(node ast.Expr) { */ g.write('sizeof($styp)') } + ast.SqlExpr { + g.write('// sql expression') + } ast.StringLiteral { if it.is_raw { escaped_val := it.val.replace_each(['"', '\\"', '\\', '\\\\']) @@ -1583,10 +1591,10 @@ fn (mut g Gen) expr(node ast.Expr) { g.expr(it.expr) g.write(')') } - else { + //else { // #printf("node=%d\n", node.typ); - println(term.red('cgen.expr(): bad node ' + typeof(node))) - } + //println(term.red('cgen.expr(): bad node ' + typeof(node))) + //} } } diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v index a36c370f3c..589a197ec5 100644 --- a/vlib/v/gen/js/js.v +++ b/vlib/v/gen/js/js.v @@ -613,6 +613,9 @@ fn (mut g JsGen) expr(node ast.Expr) { ast.SizeOf { // TODO } + ast.SqlExpr{ + // TODO + } ast.StringInterLiteral { g.gen_string_inter_literal(it) } diff --git a/vlib/v/parser/pratt.v b/vlib/v/parser/pratt.v index e43d9aa6a5..6db833a6f6 100644 --- a/vlib/v/parser/pratt.v +++ b/vlib/v/parser/pratt.v @@ -19,8 +19,12 @@ pub fn (mut p Parser) expr(precedence int) ast.Expr { node = p.parse_assign_ident() } .name { - node = p.name_expr() - p.is_stmt_ident = is_stmt_ident + if p.tok.lit == 'sql' && p.peek_tok.kind == .name { + node = p.sql_expr() + } else { + node = p.name_expr() + p.is_stmt_ident = is_stmt_ident + } } .string { node = p.string_expr() diff --git a/vlib/v/parser/sql.v b/vlib/v/parser/sql.v new file mode 100644 index 0000000000..fff8dc14a0 --- /dev/null +++ b/vlib/v/parser/sql.v @@ -0,0 +1,10 @@ +// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. +module parser + +import v.ast + +fn (mut p Parser) sql_expr() ast.SqlExpr { + return ast.SqlExpr{} +}