mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
orm: enforce that queries always return a Result, a query-resulting array can be used as a V array in place. (#17871)
This commit is contained in:
parent
9addede0ea
commit
8452644ec3
@ -130,6 +130,7 @@ const (
|
||||
'vlib/orm/orm_string_interpolation_in_where_test.v',
|
||||
'vlib/orm/orm_interface_test.v',
|
||||
'vlib/orm/orm_mut_db_test.v',
|
||||
'vlib/orm/orm_result_test.v',
|
||||
'vlib/db/sqlite/sqlite_test.v',
|
||||
'vlib/db/sqlite/sqlite_orm_test.v',
|
||||
'vlib/db/sqlite/sqlite_vfs_lowlevel_test.v',
|
||||
@ -205,6 +206,7 @@ const (
|
||||
'vlib/orm/orm_string_interpolation_in_where_test.v',
|
||||
'vlib/orm/orm_interface_test.v',
|
||||
'vlib/orm/orm_mut_db_test.v',
|
||||
'vlib/orm/orm_result_test.v',
|
||||
'vlib/v/tests/orm_sub_struct_test.v',
|
||||
'vlib/v/tests/orm_sub_array_struct_test.v',
|
||||
'vlib/v/tests/orm_joined_tables_select_test.v',
|
||||
|
@ -4850,18 +4850,18 @@ db := sqlite.connect('customers.db')!
|
||||
// )
|
||||
sql db {
|
||||
create table Customer
|
||||
}
|
||||
}!
|
||||
|
||||
// select count(*) from customers
|
||||
nr_customers := sql db {
|
||||
select count from Customer
|
||||
}
|
||||
}!
|
||||
println('number of all customers: ${nr_customers}')
|
||||
|
||||
// V syntax can be used to build queries
|
||||
uk_customers := sql db {
|
||||
select from Customer where country == 'uk' && nr_orders > 0
|
||||
}
|
||||
}!
|
||||
println(uk_customers.len)
|
||||
for customer in uk_customers {
|
||||
println('${customer.id} - ${customer.name}')
|
||||
@ -4874,7 +4874,7 @@ new_customer := Customer{
|
||||
}
|
||||
sql db {
|
||||
insert new_customer into Customer
|
||||
}
|
||||
}!
|
||||
```
|
||||
|
||||
For more examples and the docs, see [vlib/orm](https://github.com/vlang/v/tree/master/vlib/orm).
|
||||
|
@ -70,16 +70,16 @@ fn sqlite3_array() ! {
|
||||
sql db {
|
||||
drop table Parent
|
||||
drop table Child
|
||||
}
|
||||
} or {}
|
||||
db.close() or {}
|
||||
}
|
||||
//
|
||||
|
||||
sql db {
|
||||
create table Parent
|
||||
}
|
||||
}!
|
||||
sql db {
|
||||
create table Child
|
||||
}
|
||||
}!
|
||||
par := Parent{
|
||||
name: 'test'
|
||||
children: [
|
||||
@ -93,10 +93,10 @@ fn sqlite3_array() ! {
|
||||
}
|
||||
sql db {
|
||||
insert par into Parent
|
||||
}
|
||||
}!
|
||||
parent := sql db {
|
||||
select from Parent where id == 1
|
||||
}
|
||||
}!
|
||||
eprintln(parent)
|
||||
}
|
||||
|
||||
@ -113,16 +113,16 @@ fn msql_array() ! {
|
||||
defer {
|
||||
sql db {
|
||||
drop table Parent
|
||||
}
|
||||
} or {}
|
||||
db.close()
|
||||
}
|
||||
//
|
||||
|
||||
db.query('drop table if exists Parent')!
|
||||
db.query('drop table if exists Child')!
|
||||
sql db {
|
||||
create table Parent
|
||||
create table Child
|
||||
}
|
||||
}!
|
||||
par := Parent{
|
||||
name: 'test'
|
||||
children: [
|
||||
@ -136,10 +136,10 @@ fn msql_array() ! {
|
||||
}
|
||||
sql db {
|
||||
insert par into Parent
|
||||
}
|
||||
}!
|
||||
parent := sql db {
|
||||
select from Parent where id == 1
|
||||
}
|
||||
}!
|
||||
eprintln(parent)
|
||||
}
|
||||
|
||||
@ -151,11 +151,11 @@ fn psql_array() ! {
|
||||
db.close()
|
||||
}
|
||||
db.exec_one('drop table if exists "Parent", "Child"') or { eprintln(err) }
|
||||
//
|
||||
|
||||
sql db {
|
||||
create table Parent
|
||||
create table Child
|
||||
}
|
||||
}!
|
||||
par := Parent{
|
||||
name: 'test'
|
||||
children: [
|
||||
@ -169,10 +169,10 @@ fn psql_array() ! {
|
||||
}
|
||||
sql db {
|
||||
insert par into Parent
|
||||
}
|
||||
}!
|
||||
parent := sql db {
|
||||
select from Parent where id == 1
|
||||
}
|
||||
}!
|
||||
eprintln(parent)
|
||||
}
|
||||
|
||||
@ -182,19 +182,17 @@ fn sqlite3() ! {
|
||||
defer {
|
||||
sql db {
|
||||
drop table Module
|
||||
}
|
||||
sql db {
|
||||
drop table User
|
||||
}
|
||||
} or {}
|
||||
db.close() or {}
|
||||
}
|
||||
//
|
||||
|
||||
sql db {
|
||||
create table Module
|
||||
}
|
||||
}!
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
mod := Module{
|
||||
name: 'test'
|
||||
nr_downloads: 10
|
||||
@ -206,10 +204,10 @@ fn sqlite3() ! {
|
||||
}
|
||||
sql db {
|
||||
insert mod into Module
|
||||
}
|
||||
}!
|
||||
modul := sql db {
|
||||
select from Module where id == 1
|
||||
}
|
||||
}!
|
||||
eprintln(modul)
|
||||
}
|
||||
|
||||
@ -230,13 +228,13 @@ fn msql() ! {
|
||||
}
|
||||
conn.query('DROP TABLE IF EXISTS Module') or { eprintln(err) }
|
||||
conn.query('DROP TABLE IF EXISTS User') or { eprintln(err) }
|
||||
//
|
||||
|
||||
sql conn {
|
||||
create table Module
|
||||
}
|
||||
}!
|
||||
sql conn {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
mod := Module{
|
||||
name: 'test'
|
||||
nr_downloads: 10
|
||||
@ -248,10 +246,10 @@ fn msql() ! {
|
||||
}
|
||||
sql conn {
|
||||
insert mod into Module
|
||||
}
|
||||
}!
|
||||
m := sql conn {
|
||||
select from Module where id == 1
|
||||
}
|
||||
}!
|
||||
eprintln(m)
|
||||
}
|
||||
|
||||
@ -266,7 +264,7 @@ fn psql() ! {
|
||||
sql db {
|
||||
create table Module
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
mod := Module{
|
||||
name: 'test'
|
||||
nr_downloads: 10
|
||||
@ -278,13 +276,13 @@ fn psql() ! {
|
||||
}
|
||||
sql db {
|
||||
insert mod into Module
|
||||
}
|
||||
}!
|
||||
modul := sql db {
|
||||
select from Module where id == 1
|
||||
}
|
||||
}!
|
||||
sql db {
|
||||
drop table Module
|
||||
}
|
||||
}!
|
||||
eprintln(modul)
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ pub fn (mut app App) sqlite_memory(count int) vweb.Result {
|
||||
|
||||
sql db {
|
||||
create table Task
|
||||
}
|
||||
}!
|
||||
|
||||
task_model := Task{
|
||||
title: 'a'
|
||||
@ -55,14 +55,14 @@ pub fn (mut app App) sqlite_memory(count int) vweb.Result {
|
||||
sw.start()
|
||||
sql db {
|
||||
insert task_model into Task
|
||||
}
|
||||
} or { []Task{} }
|
||||
sw.stop()
|
||||
insert_stopwatchs << int(sw.end - sw.start)
|
||||
}
|
||||
|
||||
sql db {
|
||||
drop table Task
|
||||
}
|
||||
}!
|
||||
|
||||
response := Response{
|
||||
insert: insert_stopwatchs
|
||||
|
@ -31,7 +31,7 @@ pub fn (mut app App) sqlite_memory(count int) vweb.Result {
|
||||
|
||||
sql db {
|
||||
create table Task
|
||||
}
|
||||
} or { panic(err) }
|
||||
|
||||
task_model := Task{
|
||||
title: 'a'
|
||||
@ -42,14 +42,14 @@ pub fn (mut app App) sqlite_memory(count int) vweb.Result {
|
||||
sw.start()
|
||||
sql db {
|
||||
insert task_model into Task
|
||||
}
|
||||
} or { []Task{} }
|
||||
sw.stop()
|
||||
insert_stopwatchs << int(sw.end - sw.start)
|
||||
}
|
||||
|
||||
sql db {
|
||||
drop table Task
|
||||
}
|
||||
} or { panic(err) }
|
||||
|
||||
response := Response{
|
||||
insert: insert_stopwatchs
|
||||
|
@ -50,7 +50,7 @@ pub fn (mut app App) sqlite_memory(count int) vweb.Result {
|
||||
|
||||
sql db {
|
||||
create table Task
|
||||
}
|
||||
} or { panic(err) }
|
||||
|
||||
task_model := Task{
|
||||
title: 'a'
|
||||
@ -62,7 +62,7 @@ pub fn (mut app App) sqlite_memory(count int) vweb.Result {
|
||||
sw.start()
|
||||
sql db {
|
||||
insert task_model into Task
|
||||
}
|
||||
} or { panic(err) }
|
||||
sw.stop()
|
||||
insert_stopwatchs << int(sw.end - sw.start)
|
||||
}
|
||||
@ -72,7 +72,7 @@ pub fn (mut app App) sqlite_memory(count int) vweb.Result {
|
||||
sw.start()
|
||||
result := sql db {
|
||||
select from Task
|
||||
}
|
||||
} or { []Task{} }
|
||||
sw.stop()
|
||||
eprintln(result)
|
||||
select_stopwatchs << int(sw.end - sw.start)
|
||||
@ -83,14 +83,14 @@ pub fn (mut app App) sqlite_memory(count int) vweb.Result {
|
||||
sw.start()
|
||||
sql db {
|
||||
update Task set title = 'b', status = 'finish' where id == i
|
||||
}
|
||||
} or { panic(err) }
|
||||
sw.stop()
|
||||
update_stopwatchs << int(sw.end - sw.start)
|
||||
}
|
||||
|
||||
sql db {
|
||||
drop table Task
|
||||
}
|
||||
} or { panic(err) }
|
||||
|
||||
response := Response{
|
||||
insert: insert_stopwatchs
|
||||
|
@ -36,7 +36,7 @@ fn (mut app App) service_auth(username string, password string) !string {
|
||||
|
||||
users := sql db {
|
||||
select from User where username == username
|
||||
}
|
||||
}!
|
||||
user := users.first()
|
||||
if user.username != username {
|
||||
return error('user not found')
|
||||
|
@ -37,7 +37,7 @@ fn (mut app App) service_get_all_products_from(user_id int) ![]Product {
|
||||
|
||||
results := sql db {
|
||||
select from Product where user_id == user_id
|
||||
}
|
||||
}!
|
||||
|
||||
return results
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ fn (mut app App) service_get_all_user() ![]User {
|
||||
|
||||
results := sql db {
|
||||
select from User
|
||||
}
|
||||
}!
|
||||
|
||||
return results
|
||||
}
|
||||
@ -59,7 +59,7 @@ fn (mut app App) service_get_user(id int) !User {
|
||||
|
||||
results := sql db {
|
||||
select from User where id == id
|
||||
}
|
||||
}!
|
||||
|
||||
return results.first()
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ fn (mut app App) service_auth(username string, password string) !string {
|
||||
|
||||
users := sql db {
|
||||
select from User where username == username
|
||||
}
|
||||
}!
|
||||
|
||||
if users.len == 0 {
|
||||
return error('user not found')
|
||||
|
@ -66,7 +66,7 @@ pub fn (mut app App) delete() vweb.Result {
|
||||
|
||||
sql db {
|
||||
drop table User
|
||||
}
|
||||
} or { panic(err) }
|
||||
|
||||
return app.text('Successfully deleted table')
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ fn (mut app App) service_add_user(username string, password string) !User {
|
||||
|
||||
users := sql db {
|
||||
select from User where username == username limit 1
|
||||
}
|
||||
}!
|
||||
|
||||
return users.first()
|
||||
}
|
||||
@ -50,7 +50,7 @@ fn (mut app App) service_get_user_by_id(user_id int) !User {
|
||||
|
||||
users := sql db {
|
||||
select from User where id == user_id
|
||||
}
|
||||
}!
|
||||
|
||||
return users.first()
|
||||
}
|
||||
@ -67,7 +67,7 @@ fn (mut app App) service_get_all_user() ![]User {
|
||||
|
||||
results := sql db {
|
||||
select from User
|
||||
}
|
||||
}!
|
||||
|
||||
return results
|
||||
}
|
||||
@ -84,7 +84,7 @@ fn (mut app App) service_get_by_username(username string) !User {
|
||||
|
||||
results := sql db {
|
||||
select from User where username == username
|
||||
}
|
||||
}!
|
||||
|
||||
if results.len == 0 {
|
||||
return error('User not found')
|
||||
|
@ -9,5 +9,5 @@ struct Article {
|
||||
pub fn (app &App) find_all_articles() []Article {
|
||||
return sql app.db {
|
||||
select from Article
|
||||
}
|
||||
} or { []Article{} }
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ fn main() {
|
||||
}
|
||||
sql app.db {
|
||||
create table Article
|
||||
}
|
||||
}!
|
||||
vweb.run(app, 8081)
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ pub fn (mut app App) new_article(title string, text string) vweb.Result {
|
||||
println(article)
|
||||
sql app.db {
|
||||
insert article into Article
|
||||
}
|
||||
} or {}
|
||||
|
||||
return app.redirect('/')
|
||||
}
|
||||
|
@ -116,10 +116,10 @@ fn test_mysql_orm() {
|
||||
*/
|
||||
sql db {
|
||||
create table TestCustomSqlType
|
||||
}
|
||||
}!
|
||||
|
||||
mut result_custom_sql := db.query("
|
||||
SELECT DATA_TYPE, COLUMN_TYPE
|
||||
SELECT DATA_TYPE, COLUMN_TYPE
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_NAME = 'TestCustomSqlType'
|
||||
ORDER BY ORDINAL_POSITION
|
||||
@ -161,7 +161,7 @@ fn test_mysql_orm() {
|
||||
|
||||
sql db {
|
||||
drop table TestCustomSqlType
|
||||
}
|
||||
}!
|
||||
|
||||
assert result_custom_sql.maps() == information_schema_custom_sql
|
||||
|
||||
@ -184,19 +184,19 @@ fn test_mysql_orm() {
|
||||
|
||||
sql db {
|
||||
create table TestTimeType
|
||||
}
|
||||
}!
|
||||
|
||||
sql db {
|
||||
insert model into TestTimeType
|
||||
}
|
||||
}!
|
||||
|
||||
results := sql db {
|
||||
select from TestTimeType where username == 'hitalo'
|
||||
}
|
||||
}!
|
||||
|
||||
sql db {
|
||||
drop table TestTimeType
|
||||
}
|
||||
}!
|
||||
|
||||
assert results[0].username == model.username
|
||||
assert results[0].created_at == model.created_at
|
||||
@ -207,7 +207,7 @@ fn test_mysql_orm() {
|
||||
*/
|
||||
sql db {
|
||||
create table TestDefaultAtribute
|
||||
}
|
||||
}!
|
||||
|
||||
mut result_defaults := db.query("
|
||||
SELECT COLUMN_DEFAULT
|
||||
@ -222,7 +222,7 @@ fn test_mysql_orm() {
|
||||
|
||||
sql db {
|
||||
drop table TestDefaultAtribute
|
||||
}
|
||||
}!
|
||||
|
||||
information_schema_column_default_sql := [{
|
||||
'COLUMN_DEFAULT': ''
|
||||
|
@ -137,7 +137,7 @@ fn test_pg_orm() {
|
||||
|
||||
sql db {
|
||||
create table TestCustomSqlType
|
||||
}
|
||||
}!
|
||||
|
||||
mut result_custom_sql := db.exec("
|
||||
SELECT DATA_TYPE
|
||||
@ -157,7 +157,7 @@ fn test_pg_orm() {
|
||||
|
||||
sql db {
|
||||
drop table TestCustomSqlType
|
||||
}
|
||||
}!
|
||||
|
||||
assert information_schema_data_types_results == information_schema_custom_sql
|
||||
|
||||
@ -180,19 +180,19 @@ fn test_pg_orm() {
|
||||
|
||||
sql db {
|
||||
create table TestTimeType
|
||||
}
|
||||
}!
|
||||
|
||||
sql db {
|
||||
insert model into TestTimeType
|
||||
}
|
||||
}!
|
||||
|
||||
results := sql db {
|
||||
select from TestTimeType where username == 'hitalo'
|
||||
}
|
||||
}!
|
||||
|
||||
sql db {
|
||||
drop table TestTimeType
|
||||
}
|
||||
}!
|
||||
|
||||
assert results[0].username == model.username
|
||||
assert results[0].created_at == model.created_at
|
||||
@ -203,7 +203,7 @@ fn test_pg_orm() {
|
||||
*/
|
||||
sql db {
|
||||
create table TestDefaultAtribute
|
||||
}
|
||||
}!
|
||||
|
||||
mut result_defaults := db.exec("
|
||||
SELECT column_default
|
||||
@ -221,6 +221,6 @@ fn test_pg_orm() {
|
||||
}
|
||||
sql db {
|
||||
drop table TestDefaultAtribute
|
||||
}
|
||||
}!
|
||||
assert ['gen_random_uuid()', '', 'CURRENT_TIMESTAMP'] == information_schema_defaults_results
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ fn test_sqlite_orm() {
|
||||
|
||||
sql db {
|
||||
create table TestCustomSqlType
|
||||
}
|
||||
}!
|
||||
|
||||
mut result_custom_sql, mut exec_custom_code := db.exec('
|
||||
pragma table_info(TestCustomSqlType);
|
||||
@ -119,14 +119,14 @@ fn test_sqlite_orm() {
|
||||
|
||||
sql db {
|
||||
drop table TestCustomSqlType
|
||||
}
|
||||
}!
|
||||
|
||||
/** test default attribute
|
||||
*/
|
||||
|
||||
sql db {
|
||||
create table TestDefaultAtribute
|
||||
}
|
||||
}!
|
||||
|
||||
mut result_default_sql, mut code := db.exec('
|
||||
pragma table_info(TestDefaultAtribute);
|
||||
@ -147,11 +147,11 @@ fn test_sqlite_orm() {
|
||||
|
||||
sql db {
|
||||
insert test_default_atribute into TestDefaultAtribute
|
||||
}
|
||||
}!
|
||||
|
||||
test_default_atributes := sql db {
|
||||
select from TestDefaultAtribute limit 1
|
||||
}
|
||||
}!
|
||||
|
||||
result_test_default_atribute := test_default_atributes.first()
|
||||
assert result_test_default_atribute.name == 'Hitalo'
|
||||
@ -164,7 +164,7 @@ fn test_sqlite_orm() {
|
||||
|
||||
sql db {
|
||||
drop table TestDefaultAtribute
|
||||
}
|
||||
}!
|
||||
}
|
||||
|
||||
fn test_get_affected_rows_count() {
|
||||
@ -204,26 +204,26 @@ fn test_get_affected_rows_count() {
|
||||
|
||||
all := sql db {
|
||||
select from EntityToTest
|
||||
}
|
||||
}!
|
||||
assert 1 == all.len
|
||||
|
||||
sql db {
|
||||
update EntityToTest set smth = '2' where id == 1
|
||||
}
|
||||
}!
|
||||
assert db.get_affected_rows_count() == 1
|
||||
|
||||
sql db {
|
||||
update EntityToTest set smth = '2' where id == 2
|
||||
}
|
||||
}!
|
||||
assert db.get_affected_rows_count() == 0
|
||||
|
||||
sql db {
|
||||
delete from EntityToTest where id == 2
|
||||
}
|
||||
}!
|
||||
assert db.get_affected_rows_count() == 0
|
||||
|
||||
sql db {
|
||||
delete from EntityToTest where id == 1
|
||||
}
|
||||
}!
|
||||
assert db.get_affected_rows_count() == 1
|
||||
}
|
||||
|
@ -19,10 +19,10 @@ fn (back Host) get_users() []User {
|
||||
return []
|
||||
}
|
||||
|
||||
fn create_host(db Connection) Host {
|
||||
fn create_host(db Connection) !Host {
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
|
||||
return Host{
|
||||
db: db
|
||||
@ -87,6 +87,6 @@ fn test_can_access_sqlite_result_consts() {
|
||||
}
|
||||
|
||||
fn test_alias_db() {
|
||||
create_host(sqlite.connect(':memory:')!)
|
||||
create_host(sqlite.connect(':memory:')!)!
|
||||
assert true
|
||||
}
|
||||
|
@ -23,18 +23,24 @@ fn test_create_only_one_table() {
|
||||
|
||||
sql db {
|
||||
create table Parent
|
||||
}
|
||||
}!
|
||||
|
||||
mut is_child_created := true
|
||||
mut is_note_created := true
|
||||
|
||||
_ := sql db {
|
||||
select count from Child
|
||||
} or { is_child_created = false }
|
||||
} or {
|
||||
is_child_created = false
|
||||
0
|
||||
}
|
||||
|
||||
_ := sql db {
|
||||
select count from Note
|
||||
} or { is_note_created = false }
|
||||
} or {
|
||||
is_note_created = false
|
||||
0
|
||||
}
|
||||
|
||||
assert is_child_created == false
|
||||
assert is_note_created == false
|
||||
@ -45,13 +51,13 @@ fn test_drop_only_one_table() {
|
||||
|
||||
sql db {
|
||||
create table Parent
|
||||
}
|
||||
}!
|
||||
sql db {
|
||||
create table Child
|
||||
}
|
||||
}!
|
||||
sql db {
|
||||
create table Note
|
||||
}
|
||||
}!
|
||||
|
||||
mut is_parent_dropped := false
|
||||
mut is_child_dropped := false
|
||||
@ -59,19 +65,28 @@ fn test_drop_only_one_table() {
|
||||
|
||||
sql db {
|
||||
drop table Parent
|
||||
}
|
||||
}!
|
||||
|
||||
_ := sql db {
|
||||
select count from Parent
|
||||
} or { is_parent_dropped = true }
|
||||
} or {
|
||||
is_parent_dropped = true
|
||||
0
|
||||
}
|
||||
|
||||
_ := sql db {
|
||||
select count from Child
|
||||
} or { is_child_dropped = true }
|
||||
} or {
|
||||
is_child_dropped = true
|
||||
0
|
||||
}
|
||||
|
||||
_ := sql db {
|
||||
select count from Note
|
||||
} or { is_note_dropped = true }
|
||||
} or {
|
||||
is_note_dropped = true
|
||||
0
|
||||
}
|
||||
|
||||
assert is_parent_dropped
|
||||
assert is_child_dropped == false
|
||||
|
@ -15,7 +15,7 @@ fn test_fn_calls() {
|
||||
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
|
||||
first_user := User{
|
||||
name: 'first'
|
||||
@ -30,18 +30,18 @@ fn test_fn_calls() {
|
||||
sql db {
|
||||
insert first_user into User
|
||||
insert second_user into User
|
||||
}
|
||||
}!
|
||||
|
||||
users_with_acceptable_age := sql db {
|
||||
select from User where age >= get_acceptable_age()
|
||||
}
|
||||
}!
|
||||
|
||||
assert users_with_acceptable_age.len == 1
|
||||
assert users_with_acceptable_age.first().name == 'first'
|
||||
|
||||
users_with_non_acceptable_age := sql db {
|
||||
select from User where age < get_acceptable_age()
|
||||
}
|
||||
}!
|
||||
|
||||
assert users_with_non_acceptable_age.len == 1
|
||||
assert users_with_non_acceptable_age.first().name == 'second'
|
||||
|
@ -14,20 +14,20 @@ fn test_insert_with_reserved_name() {
|
||||
}
|
||||
sql db {
|
||||
create table Bad
|
||||
}
|
||||
}!
|
||||
sql db {
|
||||
insert bad into Bad
|
||||
}
|
||||
}!
|
||||
|
||||
sql db {
|
||||
insert bad into Bad
|
||||
insert bad into Bad
|
||||
insert bad into Bad
|
||||
}
|
||||
}!
|
||||
|
||||
rows := sql db {
|
||||
select from Bad
|
||||
}
|
||||
}!
|
||||
|
||||
assert rows.len == 4
|
||||
}
|
||||
|
@ -25,10 +25,10 @@ struct Account {
|
||||
id int [primary; sql: serial]
|
||||
}
|
||||
|
||||
pub fn insert_parent(db sqlite.DB, mut parent Parent) {
|
||||
pub fn insert_parent(db sqlite.DB, mut parent Parent) ! {
|
||||
sql db {
|
||||
insert parent into Parent
|
||||
}
|
||||
}!
|
||||
}
|
||||
|
||||
fn test_insert_empty_object() {
|
||||
@ -39,11 +39,11 @@ fn test_insert_empty_object() {
|
||||
sql db {
|
||||
create table Account
|
||||
insert account into Account
|
||||
}
|
||||
}!
|
||||
|
||||
accounts := sql db {
|
||||
select from Account
|
||||
}
|
||||
}!
|
||||
|
||||
assert accounts.len == 1
|
||||
}
|
||||
@ -55,17 +55,17 @@ fn test_orm_insert_mut_object() {
|
||||
create table Parent
|
||||
create table Child
|
||||
create table Note
|
||||
}
|
||||
}!
|
||||
|
||||
mut parent := Parent{
|
||||
name: 'test'
|
||||
}
|
||||
|
||||
insert_parent(db, mut parent)
|
||||
insert_parent(db, mut parent)!
|
||||
|
||||
parents := sql db {
|
||||
select from Parent
|
||||
}
|
||||
}!
|
||||
|
||||
assert parents.len == 1
|
||||
}
|
||||
@ -77,7 +77,7 @@ fn test_orm_insert_with_multiple_child_elements() {
|
||||
create table Parent
|
||||
create table Child
|
||||
create table Note
|
||||
}
|
||||
}!
|
||||
|
||||
new_parent := Parent{
|
||||
name: 'test'
|
||||
@ -104,11 +104,11 @@ fn test_orm_insert_with_multiple_child_elements() {
|
||||
|
||||
sql db {
|
||||
insert new_parent into Parent
|
||||
}
|
||||
}!
|
||||
|
||||
parents := sql db {
|
||||
select from Parent where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
parent := parents.first()
|
||||
assert parent.children.len == new_parent.children.len
|
||||
@ -116,12 +116,12 @@ fn test_orm_insert_with_multiple_child_elements() {
|
||||
|
||||
children_count := sql db {
|
||||
select count from Child
|
||||
}
|
||||
}!
|
||||
assert children_count == new_parent.children.len
|
||||
|
||||
note_count := sql db {
|
||||
select count from Note
|
||||
}
|
||||
}!
|
||||
assert note_count == new_parent.notes.len
|
||||
|
||||
assert parent.children[0].name == 'Lisa'
|
||||
|
@ -12,7 +12,7 @@ fn test_orm_interface() {
|
||||
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
|
||||
user := User{
|
||||
name: 'test'
|
||||
@ -20,11 +20,11 @@ fn test_orm_interface() {
|
||||
|
||||
sql db {
|
||||
insert user into User
|
||||
}
|
||||
}!
|
||||
|
||||
users := sql db {
|
||||
select from User
|
||||
}
|
||||
}!
|
||||
|
||||
assert users.len == 1
|
||||
assert users.first().name == user.name
|
||||
|
@ -10,7 +10,7 @@ fn test_last_id() {
|
||||
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
|
||||
first_user := User{
|
||||
name: 'first'
|
||||
@ -23,7 +23,7 @@ fn test_last_id() {
|
||||
sql db {
|
||||
insert first_user into User
|
||||
insert second_user into User
|
||||
}
|
||||
}!
|
||||
|
||||
last_id := db.last_id()
|
||||
|
||||
|
@ -5,10 +5,10 @@ struct User {
|
||||
name string
|
||||
}
|
||||
|
||||
fn get_users(mut db sqlite.DB) []User {
|
||||
fn get_users(mut db sqlite.DB) ![]User {
|
||||
return sql db {
|
||||
select from User
|
||||
}
|
||||
}!
|
||||
}
|
||||
|
||||
fn test_orm_mut_db() {
|
||||
@ -16,7 +16,7 @@ fn test_orm_mut_db() {
|
||||
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
|
||||
first_user := User{
|
||||
name: 'first'
|
||||
@ -28,9 +28,9 @@ fn test_orm_mut_db() {
|
||||
sql db {
|
||||
insert first_user into User
|
||||
insert second_user into User
|
||||
}
|
||||
}!
|
||||
|
||||
users := get_users(mut db)
|
||||
users := get_users(mut db)!
|
||||
|
||||
assert users.len == 2
|
||||
}
|
||||
|
82
vlib/orm/orm_result_test.v
Normal file
82
vlib/orm/orm_result_test.v
Normal file
@ -0,0 +1,82 @@
|
||||
import db.sqlite
|
||||
|
||||
struct Account {
|
||||
id int [primary; sql: serial]
|
||||
name string
|
||||
}
|
||||
|
||||
struct Note {
|
||||
id int [primary; sql: serial]
|
||||
content string
|
||||
}
|
||||
|
||||
fn test_catch_table_is_not_created() {
|
||||
mut db := sqlite.connect(':memory:')!
|
||||
|
||||
mut is_inserted := true
|
||||
|
||||
account := Account{}
|
||||
|
||||
sql db {
|
||||
insert account into Account
|
||||
} or { is_inserted = false }
|
||||
|
||||
assert !is_inserted
|
||||
}
|
||||
|
||||
fn test_catch_one_of_queries() {
|
||||
mut db := sqlite.connect(':memory:')!
|
||||
|
||||
sql db {
|
||||
create table Account
|
||||
}!
|
||||
|
||||
account := Account{}
|
||||
|
||||
sql db {
|
||||
insert account into Account
|
||||
}!
|
||||
|
||||
mut are_updated := true
|
||||
|
||||
sql db {
|
||||
update Account set name = 'test' where id == 1
|
||||
update Note set content = 'test' where id == 1
|
||||
} or { are_updated = false }
|
||||
|
||||
assert !are_updated
|
||||
}
|
||||
|
||||
fn test_print_results() {
|
||||
mut db := sqlite.connect(':memory:')!
|
||||
|
||||
sql db {
|
||||
create table Account
|
||||
}!
|
||||
|
||||
account := Account{}
|
||||
|
||||
sql db {
|
||||
insert account into Account
|
||||
}!
|
||||
|
||||
count := sql db {
|
||||
select count from Account
|
||||
}!
|
||||
|
||||
println(count)
|
||||
|
||||
user := sql db {
|
||||
select from Account
|
||||
}!.first()
|
||||
|
||||
println(user)
|
||||
|
||||
users := sql db {
|
||||
select from Account
|
||||
}!
|
||||
|
||||
println(users)
|
||||
|
||||
assert true
|
||||
}
|
@ -38,20 +38,26 @@ fn test_sql_or_block_for_insert() {
|
||||
user := User{1, 'bilbo'}
|
||||
|
||||
eprintln('> inserting user 1 (first try)...')
|
||||
mut is_user_inserted := true
|
||||
|
||||
sql db {
|
||||
insert user into User
|
||||
} or {
|
||||
println('user should have been inserted, but could not, err: ${err}')
|
||||
assert false
|
||||
is_user_inserted = false
|
||||
}
|
||||
|
||||
assert is_user_inserted
|
||||
|
||||
eprintln('> inserting user 1 (second try)...')
|
||||
sql db {
|
||||
insert user into User
|
||||
} or {
|
||||
assert true
|
||||
println('user could not be inserted, err: ${err}')
|
||||
is_user_inserted = false
|
||||
}
|
||||
|
||||
assert !is_user_inserted
|
||||
eprintln('LINE: ${@LINE}')
|
||||
db.close()!
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ fn test_string_interpolation() {
|
||||
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
|
||||
user_suffix := '_user'
|
||||
|
||||
@ -25,11 +25,11 @@ fn test_string_interpolation() {
|
||||
sql db {
|
||||
insert first_user into User
|
||||
insert second_user into User
|
||||
}
|
||||
}!
|
||||
|
||||
users := sql db {
|
||||
select from User where name == 'first${user_suffix}'
|
||||
}
|
||||
}!
|
||||
|
||||
assert users.len == 1
|
||||
assert users.first().name == 'first${user_suffix}'
|
||||
|
@ -39,7 +39,7 @@ fn test_use_struct_field_as_limit() {
|
||||
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
|
||||
foo := Foo{
|
||||
age: 10
|
||||
@ -52,11 +52,11 @@ fn test_use_struct_field_as_limit() {
|
||||
|
||||
sql db {
|
||||
insert sam into User
|
||||
}
|
||||
}!
|
||||
|
||||
users := sql db {
|
||||
select from User limit foo.age
|
||||
}
|
||||
}!
|
||||
|
||||
assert users.len == 1
|
||||
}
|
||||
@ -66,10 +66,10 @@ fn test_orm() {
|
||||
|
||||
sql db {
|
||||
create table Module
|
||||
}
|
||||
}!
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
|
||||
name := 'Peter'
|
||||
|
||||
@ -93,47 +93,47 @@ fn test_orm() {
|
||||
insert sam into User
|
||||
insert peter into User
|
||||
insert k into User
|
||||
}
|
||||
}!
|
||||
|
||||
c := sql db {
|
||||
select count from User where id != 1
|
||||
}
|
||||
}!
|
||||
assert c == 2
|
||||
|
||||
nr_all_users := sql db {
|
||||
select count from User
|
||||
}
|
||||
}!
|
||||
assert nr_all_users == 3
|
||||
|
||||
nr_users1 := sql db {
|
||||
select count from User where id == 1
|
||||
}
|
||||
}!
|
||||
assert nr_users1 == 1
|
||||
|
||||
nr_peters := sql db {
|
||||
select count from User where id == 2 && name == 'Peter'
|
||||
}
|
||||
}!
|
||||
assert nr_peters == 1
|
||||
|
||||
nr_peters2 := sql db {
|
||||
select count from User where id == 2 && name == name
|
||||
}
|
||||
}!
|
||||
assert nr_peters2 == 1
|
||||
|
||||
nr_peters3 := sql db {
|
||||
select count from User where name == name
|
||||
}
|
||||
}!
|
||||
assert nr_peters3 == 1
|
||||
|
||||
peters := sql db {
|
||||
select from User where name == name
|
||||
}
|
||||
}!
|
||||
assert peters.len == 1
|
||||
assert peters[0].name == 'Peter'
|
||||
|
||||
mut users := sql db {
|
||||
select from User where name == name limit 1
|
||||
}
|
||||
}!
|
||||
|
||||
one_peter := users.first()
|
||||
assert one_peter.name == 'Peter'
|
||||
@ -141,7 +141,7 @@ fn test_orm() {
|
||||
|
||||
users = sql db {
|
||||
select from User where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
user := users.first()
|
||||
assert user.name == 'Sam'
|
||||
@ -150,7 +150,7 @@ fn test_orm() {
|
||||
|
||||
users = sql db {
|
||||
select from User where id > 0
|
||||
}
|
||||
}!
|
||||
assert users.len == 3
|
||||
assert users[0].name == 'Sam'
|
||||
assert users[1].name == 'Peter'
|
||||
@ -158,12 +158,12 @@ fn test_orm() {
|
||||
|
||||
users2 := sql db {
|
||||
select from User where id < 0
|
||||
}
|
||||
}!
|
||||
assert users2.len == 0
|
||||
|
||||
users3 := sql db {
|
||||
select from User where age == 29 || age == 31
|
||||
}
|
||||
}!
|
||||
|
||||
assert users3.len == 2
|
||||
assert users3[0].age == 29
|
||||
@ -175,11 +175,11 @@ fn test_orm() {
|
||||
}
|
||||
sql db {
|
||||
insert new_user into User
|
||||
}
|
||||
}!
|
||||
|
||||
users = sql db {
|
||||
select from User where id == 4
|
||||
}
|
||||
}!
|
||||
|
||||
x := users.first()
|
||||
assert x.age == 30
|
||||
@ -188,14 +188,14 @@ fn test_orm() {
|
||||
|
||||
users = sql db {
|
||||
select from User where id == 3
|
||||
}
|
||||
}!
|
||||
|
||||
kate := users.first()
|
||||
assert kate.is_customer == true
|
||||
|
||||
users = sql db {
|
||||
select from User where is_customer == true limit 1
|
||||
}
|
||||
}!
|
||||
|
||||
customer := users.first()
|
||||
assert customer.is_customer == true
|
||||
@ -203,22 +203,22 @@ fn test_orm() {
|
||||
|
||||
sql db {
|
||||
update User set age = 31 where name == 'Kate'
|
||||
}
|
||||
}!
|
||||
|
||||
users = sql db {
|
||||
select from User where id == 3
|
||||
}
|
||||
}!
|
||||
kate2 := users.first()
|
||||
assert kate2.age == 31
|
||||
assert kate2.name == 'Kate'
|
||||
|
||||
sql db {
|
||||
update User set age = 32, name = 'Kate N' where name == 'Kate'
|
||||
}
|
||||
}!
|
||||
|
||||
users = sql db {
|
||||
select from User where id == 3
|
||||
}
|
||||
}!
|
||||
mut kate3 := users.first()
|
||||
assert kate3.age == 32
|
||||
assert kate3.name == 'Kate N'
|
||||
@ -226,11 +226,11 @@ fn test_orm() {
|
||||
new_age := 33
|
||||
sql db {
|
||||
update User set age = new_age, name = 'Kate N' where id == 3
|
||||
}
|
||||
}!
|
||||
|
||||
users = sql db {
|
||||
select from User where id == 3
|
||||
}
|
||||
}!
|
||||
|
||||
kate3 = users.first()
|
||||
assert kate3.age == 33
|
||||
@ -239,42 +239,42 @@ fn test_orm() {
|
||||
foo := Foo{34}
|
||||
sql db {
|
||||
update User set age = foo.age, name = 'Kate N' where id == 3
|
||||
}
|
||||
}!
|
||||
|
||||
users = sql db {
|
||||
select from User where id == 3
|
||||
}
|
||||
}!
|
||||
kate3 = users.first()
|
||||
assert kate3.age == 34
|
||||
assert kate3.name == 'Kate N'
|
||||
|
||||
no_user := sql db {
|
||||
select from User where id == 30
|
||||
}
|
||||
}!
|
||||
|
||||
assert no_user.len == 0
|
||||
|
||||
two_users := sql db {
|
||||
select from User limit 2
|
||||
}
|
||||
}!
|
||||
assert two_users.len == 2
|
||||
assert two_users[0].id == 1
|
||||
|
||||
y := sql db {
|
||||
select from User limit 2 offset 1
|
||||
}
|
||||
}!
|
||||
assert y.len == 2
|
||||
assert y[0].id == 2
|
||||
|
||||
z := sql db {
|
||||
select from User order by id limit 2 offset offset_const
|
||||
}
|
||||
}!
|
||||
assert z.len == 2
|
||||
assert z[0].id == 3
|
||||
|
||||
users = sql db {
|
||||
select from User order by age desc limit 1
|
||||
}
|
||||
}!
|
||||
|
||||
oldest := users.first()
|
||||
assert oldest.age == 34
|
||||
@ -282,17 +282,17 @@ fn test_orm() {
|
||||
offs := 1
|
||||
users = sql db {
|
||||
select from User order by age desc limit 1 offset offs
|
||||
}
|
||||
}!
|
||||
|
||||
second_oldest := users.first()
|
||||
assert second_oldest.age == 31
|
||||
sql db {
|
||||
delete from User where age == 34
|
||||
}
|
||||
}!
|
||||
|
||||
users = sql db {
|
||||
select from User order by age desc limit 1
|
||||
}
|
||||
}!
|
||||
updated_oldest := users.first()
|
||||
assert updated_oldest.age == 31
|
||||
|
||||
@ -300,41 +300,41 @@ fn test_orm() {
|
||||
// db.exec('insert into User (name, age) values (NULL, 31)')
|
||||
users = sql db {
|
||||
select from User where id == 5
|
||||
}
|
||||
}!
|
||||
assert users.len == 0
|
||||
|
||||
users = sql db {
|
||||
select from User where id == 1
|
||||
}
|
||||
}!
|
||||
age_test := users.first()
|
||||
|
||||
assert age_test.age == 29
|
||||
|
||||
sql db {
|
||||
update User set age = age + 1 where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
users = sql db {
|
||||
select from User where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
mut first := users.first()
|
||||
assert first.age == 30
|
||||
|
||||
sql db {
|
||||
update User set age = age * 2 where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
users = sql db {
|
||||
select from User where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
first = users.first()
|
||||
assert first.age == 60
|
||||
|
||||
sql db {
|
||||
create table TestTime
|
||||
}
|
||||
}!
|
||||
|
||||
tnow := time.now()
|
||||
|
||||
@ -344,11 +344,11 @@ fn test_orm() {
|
||||
|
||||
sql db {
|
||||
insert time_test into TestTime
|
||||
}
|
||||
}!
|
||||
|
||||
data := sql db {
|
||||
select from TestTime where create == tnow
|
||||
}
|
||||
}!
|
||||
|
||||
assert data.len == 1
|
||||
assert tnow.unix == data[0].create.unix
|
||||
@ -357,26 +357,26 @@ fn test_orm() {
|
||||
|
||||
sql db {
|
||||
insert mod into Module
|
||||
}
|
||||
}!
|
||||
|
||||
sql db {
|
||||
update Module set test_id = 11 where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
mut modules := sql db {
|
||||
select from Module where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
assert modules.first().test_id == 11
|
||||
|
||||
t := time.now()
|
||||
sql db {
|
||||
update Module set created = t where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
modules = sql db {
|
||||
select from Module where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
// Note: usually updated_time_mod.created != t, because t has
|
||||
// its microseconds set, while the value retrieved from the DB
|
||||
@ -385,12 +385,12 @@ fn test_orm() {
|
||||
|
||||
users = sql db {
|
||||
select from User where (name == 'Sam' && is_customer == true) || id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
assert users.first() == first
|
||||
|
||||
sql db {
|
||||
drop table Module
|
||||
drop table TestTime
|
||||
}
|
||||
}!
|
||||
}
|
||||
|
@ -1767,9 +1767,8 @@ pub:
|
||||
pos token.Pos
|
||||
where_expr Expr
|
||||
update_exprs []Expr // for `update`
|
||||
// is_top_level indicates that a statement is parsed from code
|
||||
// and is not inserted by ORM for inserting in related tables.
|
||||
is_top_level bool
|
||||
// is_generated indicates a statement is generated by ORM for complex queries with related tables.
|
||||
is_generated bool
|
||||
scope &Scope = unsafe { nil }
|
||||
pub mut:
|
||||
object_var_name string // `user`
|
||||
@ -1788,8 +1787,10 @@ pub:
|
||||
has_offset bool
|
||||
has_desc bool
|
||||
is_array bool
|
||||
or_expr OrExpr
|
||||
pos token.Pos
|
||||
// is_generated indicates a statement is generated by ORM for complex queries with related tables.
|
||||
is_generated bool
|
||||
or_expr OrExpr
|
||||
pos token.Pos
|
||||
pub mut:
|
||||
typ Type
|
||||
db_expr Expr // `db` in `sql db {`
|
||||
|
@ -11,6 +11,8 @@ const (
|
||||
v_orm_prefix = 'V ORM'
|
||||
)
|
||||
|
||||
type ORMExpr = ast.SqlExpr | ast.SqlStmt
|
||||
|
||||
fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
|
||||
c.inside_sql = true
|
||||
defer {
|
||||
@ -47,12 +49,13 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
|
||||
pos: node.pos
|
||||
has_where: true
|
||||
where_expr: ast.None{}
|
||||
typ: typ
|
||||
typ: typ.set_flag(.result)
|
||||
db_expr: node.db_expr
|
||||
table_expr: ast.TypeNode{
|
||||
pos: node.table_expr.pos
|
||||
typ: typ
|
||||
}
|
||||
is_generated: true
|
||||
}
|
||||
|
||||
tmp_inside_sql := c.inside_sql
|
||||
@ -141,33 +144,21 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
|
||||
}
|
||||
c.expr(node.db_expr)
|
||||
|
||||
if node.or_expr.kind == .block {
|
||||
if node.or_expr.stmts.len == 0 {
|
||||
c.orm_error('or block needs to return a default value', node.or_expr.pos)
|
||||
}
|
||||
if node.or_expr.stmts.len > 0 && node.or_expr.stmts.last() is ast.ExprStmt {
|
||||
c.expected_or_type = node.typ
|
||||
}
|
||||
c.stmts_ending_with_expression(node.or_expr.stmts)
|
||||
c.check_expr_opt_call(node, node.typ)
|
||||
c.expected_or_type = ast.void_type
|
||||
}
|
||||
return node.typ
|
||||
c.check_orm_or_expr(node)
|
||||
|
||||
return node.typ.clear_flag(.result)
|
||||
}
|
||||
|
||||
fn (mut c Checker) sql_stmt(mut node ast.SqlStmt) ast.Type {
|
||||
node.db_expr_type = c.table.unaliased_type(c.expr(node.db_expr))
|
||||
mut typ := ast.void_type
|
||||
|
||||
for mut line in node.lines {
|
||||
a := c.sql_stmt_line(mut line)
|
||||
if a != ast.void_type {
|
||||
typ = a
|
||||
}
|
||||
c.sql_stmt_line(mut line)
|
||||
}
|
||||
if node.or_expr.kind == .block {
|
||||
c.stmts_ending_with_expression(node.or_expr.stmts)
|
||||
}
|
||||
return typ
|
||||
|
||||
c.check_orm_or_expr(node)
|
||||
|
||||
return ast.void_type
|
||||
}
|
||||
|
||||
fn (mut c Checker) sql_stmt_line(mut node ast.SqlStmtLine) ast.Type {
|
||||
@ -183,7 +174,7 @@ fn (mut c Checker) sql_stmt_line(mut node ast.SqlStmtLine) ast.Type {
|
||||
c.cur_orm_ts = old_ts
|
||||
}
|
||||
|
||||
if node.kind == .insert && node.is_top_level {
|
||||
if node.kind == .insert && !node.is_generated {
|
||||
inserting_object_name := node.object_var_name
|
||||
inserting_object := node.scope.find(inserting_object_name) or {
|
||||
c.error('undefined ident: `${inserting_object_name}`', node.pos)
|
||||
@ -238,6 +229,7 @@ fn (mut c Checker) sql_stmt_line(mut node ast.SqlStmtLine) ast.Type {
|
||||
typ: typ
|
||||
}
|
||||
object_var_name: object_var_name
|
||||
is_generated: true
|
||||
}
|
||||
tmp_inside_sql := c.inside_sql
|
||||
c.sql_stmt_line(mut n)
|
||||
@ -468,3 +460,39 @@ fn (_ &Checker) fn_return_type_flag_to_string(typ ast.Type) string {
|
||||
''
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut c Checker) check_orm_or_expr(expr ORMExpr) {
|
||||
if expr is ast.SqlExpr {
|
||||
if expr.is_generated {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return_type := if expr is ast.SqlExpr {
|
||||
expr.typ
|
||||
} else {
|
||||
ast.void_type.set_flag(.result)
|
||||
}
|
||||
|
||||
if expr.or_expr.kind == .absent {
|
||||
if c.inside_defer {
|
||||
c.error('V ORM returns a result, so it should have an `or {}` block at the end',
|
||||
expr.pos)
|
||||
} else {
|
||||
c.error('V ORM returns a result, so it should have either an `or {}` block, or `!` at the end',
|
||||
expr.pos)
|
||||
}
|
||||
} else {
|
||||
c.check_or_expr(expr.or_expr, return_type.clear_flag(.result), return_type, if expr is ast.SqlExpr {
|
||||
expr
|
||||
} else {
|
||||
ast.empty_expr
|
||||
})
|
||||
}
|
||||
|
||||
if expr.or_expr.kind == .block {
|
||||
c.expected_or_type = return_type.clear_flag(.result)
|
||||
c.stmts_ending_with_expression(expr.or_expr.stmts)
|
||||
c.expected_or_type = ast.void_type
|
||||
}
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ vlib/v/checker/tests/orm_empty_struct.vv:9:15: error: V ORM: select: empty field
|
||||
8 | _ := sql db {
|
||||
9 | select from Person
|
||||
| ~~~~~~
|
||||
10 | }
|
||||
10 | }!
|
||||
11 | }
|
||||
|
@ -7,5 +7,5 @@ fn main() {
|
||||
db := sqlite.connect(':memory:')!
|
||||
_ := sql db {
|
||||
select from Person
|
||||
}
|
||||
}!
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ vlib/v/checker/tests/orm_fn_call_with_wrong_return_type.vv:52:37: error: V ORM:
|
||||
51 | steve := sql db {
|
||||
52 | select from Parent where child == get_second_child()
|
||||
| ~~~~~~~~~~~~~~~~~~
|
||||
53 | }
|
||||
53 | }!
|
||||
54 |
|
||||
|
@ -31,7 +31,7 @@ fn main() {
|
||||
sql db {
|
||||
create table Parent
|
||||
create table Child
|
||||
}
|
||||
}!
|
||||
|
||||
new_parent := Parent{
|
||||
name: 'test'
|
||||
@ -40,17 +40,17 @@ fn main() {
|
||||
|
||||
sql db {
|
||||
insert new_parent into Parent
|
||||
}
|
||||
}!
|
||||
|
||||
first_child := get_first_child()
|
||||
|
||||
sql db {
|
||||
insert first_child into Child
|
||||
}
|
||||
}!
|
||||
|
||||
steve := sql db {
|
||||
select from Parent where child == get_second_child()
|
||||
}
|
||||
}!
|
||||
|
||||
dump(steve)
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ vlib/v/checker/tests/orm_insert_object_with_mismatched_type_error.vv:19:10: erro
|
||||
18 | create table Tiddlers
|
||||
19 | insert tiddler into Tiddlers
|
||||
| ~~~~~~~
|
||||
20 | }
|
||||
20 | }!
|
||||
21 | }
|
||||
|
@ -17,5 +17,5 @@ fn main() {
|
||||
sql db {
|
||||
create table Tiddlers
|
||||
insert tiddler into Tiddlers
|
||||
}
|
||||
}!
|
||||
}
|
||||
|
@ -4,5 +4,5 @@ vlib/v/checker/tests/orm_left_side_expr_in_infix_expr_has_no_struct_field_error.
|
||||
17 | users := sql db {
|
||||
18 | select from User where first == second
|
||||
| ~~~~~
|
||||
19 | }
|
||||
19 | }!
|
||||
20 |
|
||||
|
@ -9,14 +9,14 @@ fn main() {
|
||||
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
|
||||
first := 'first'
|
||||
second := 'second'
|
||||
|
||||
users := sql db {
|
||||
select from User where first == second
|
||||
}
|
||||
}!
|
||||
|
||||
println(users)
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ vlib/v/checker/tests/orm_limit_less_than_zero_error.vv:18:26: error: V ORM: `lim
|
||||
17 | users := sql db {
|
||||
18 | select from User limit user_limit
|
||||
| ~~~~~~~~~~
|
||||
19 | }
|
||||
19 | }!
|
||||
20 |
|
||||
|
@ -16,7 +16,7 @@ fn main() {
|
||||
|
||||
users := sql db {
|
||||
select from User limit user_limit
|
||||
}
|
||||
}!
|
||||
|
||||
println(users)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
vlib/v/checker/tests/orm_no_default_value.vv:11:4: error: V ORM: or block needs to return a default value
|
||||
vlib/v/checker/tests/orm_no_default_value.vv:11:4: error: assignment requires a non empty `or {}` block
|
||||
9 | _ := sql db {
|
||||
10 | select from Person
|
||||
11 | } or {
|
||||
|
@ -3,5 +3,5 @@ vlib/v/checker/tests/orm_not_a_struct.vv:10:15: error: V ORM: the table symbol `
|
||||
9 | _ := sql db {
|
||||
10 | select from Person
|
||||
| ~~~~~~
|
||||
11 | }
|
||||
11 | }!
|
||||
12 | }
|
||||
|
@ -8,5 +8,5 @@ fn main() {
|
||||
db := sqlite.connect(':memory:')!
|
||||
_ := sql db {
|
||||
select from Person
|
||||
}
|
||||
}!
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ vlib/v/checker/tests/orm_using_non_struct_field_in_order_by_error.vv:14:29: erro
|
||||
13 | users := sql db {
|
||||
14 | select from User order by database
|
||||
| ~~~~~~~~
|
||||
15 | }
|
||||
15 | }!
|
||||
16 |
|
||||
vlib/v/checker/tests/orm_using_non_struct_field_in_order_by_error.vv:17:2: error: `println` can not print void expressions
|
||||
15 | }
|
||||
15 | }!
|
||||
16 |
|
||||
17 | println(users)
|
||||
| ~~~~~~~~~~~~~~
|
||||
|
@ -12,7 +12,7 @@ fn main() {
|
||||
|
||||
users := sql db {
|
||||
select from User order by database
|
||||
}
|
||||
}!
|
||||
|
||||
println(users)
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ vlib/v/checker/tests/orm_using_undefined_object_in_insert_error.vv:13:10: error:
|
||||
12 | create table Node
|
||||
13 | insert bug into Node
|
||||
| ~~~
|
||||
14 | }
|
||||
14 | }!
|
||||
15 | }
|
||||
|
@ -11,5 +11,5 @@ fn main() {
|
||||
sql db {
|
||||
create table Node
|
||||
insert bug into Node
|
||||
}
|
||||
}!
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
vlib/v/checker/tests/orm_using_undefined_var_in_where_err.vv:24:35: error: undefined variable: `email`
|
||||
22 |
|
||||
22 |
|
||||
23 | _ := sql db {
|
||||
24 | select from User where email == email
|
||||
| ~~~~~
|
||||
25 | }
|
||||
25 | }!
|
||||
26 | }
|
||||
|
@ -14,13 +14,13 @@ fn main() {
|
||||
db := sqlite.connect(':memory:')!
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
m := User{}
|
||||
sql db {
|
||||
insert m into User
|
||||
}
|
||||
}!
|
||||
|
||||
_ := sql db {
|
||||
select from User where email == email
|
||||
}
|
||||
}!
|
||||
}
|
||||
|
@ -3,5 +3,5 @@ vlib/v/checker/tests/orm_wrong_where_expr_error.vv:15:26: error: V ORM: `where`
|
||||
14 | users := sql db {
|
||||
15 | select from User where 3
|
||||
| ^
|
||||
16 | }
|
||||
16 | }!
|
||||
17 |
|
||||
|
@ -9,11 +9,11 @@ fn main() {
|
||||
|
||||
sql db {
|
||||
create table User
|
||||
}
|
||||
}!
|
||||
|
||||
users := sql db {
|
||||
select from User where 3
|
||||
}
|
||||
}!
|
||||
|
||||
println(users)
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
module c
|
||||
|
||||
import v.ast
|
||||
import v.token
|
||||
import v.util
|
||||
|
||||
enum SqlExprSide {
|
||||
@ -65,11 +64,7 @@ fn (mut g Gen) sql_stmt_line(nd ast.SqlStmtLine, expr string, or_expr ast.OrExpr
|
||||
g.sql_delete(node, expr, table_name)
|
||||
}
|
||||
|
||||
if or_expr.kind == .block {
|
||||
g.or_block(res, or_expr, ast.int_type.set_flag(.result))
|
||||
} else if or_expr.kind == .absent {
|
||||
g.write_error_handling_for_orm_result(node.pos, res)
|
||||
}
|
||||
g.or_block(res, or_expr, ast.int_type.set_flag(.result))
|
||||
}
|
||||
|
||||
fn (mut g Gen) sql_create_table(node ast.SqlStmtLine, expr string, table_name string) {
|
||||
@ -554,10 +549,10 @@ fn (mut g Gen) sql_select(node ast.SqlExpr, expr string, left string, or_expr as
|
||||
}
|
||||
}
|
||||
|
||||
res := g.new_tmp_var()
|
||||
select_result_var_name := g.new_tmp_var()
|
||||
table_name := g.get_table_name(node.table_expr)
|
||||
g.sql_table_name = g.table.sym(node.table_expr.typ).name
|
||||
g.write('${result_name}_Array_Array_orm__Primitive _o${res} = orm__Connection_name_table[${expr}._typ]._method_select(${expr}._object, ')
|
||||
g.write('${result_name}_Array_Array_orm__Primitive ${select_result_var_name} = orm__Connection_name_table[${expr}._typ]._method_select(${expr}._object, ')
|
||||
g.write('(orm__SelectConfig){')
|
||||
g.write('.table = _SLIT("${table_name}"),')
|
||||
g.write('.is_count = ${node.is_count},')
|
||||
@ -650,38 +645,37 @@ fn (mut g Gen) sql_select(node ast.SqlExpr, expr string, left string, or_expr as
|
||||
}
|
||||
g.writeln(');')
|
||||
|
||||
mut tmp_left := g.new_tmp_var()
|
||||
g.writeln('${g.typ(node.typ.set_flag(.result))} ${tmp_left};')
|
||||
unwrapped_typ := node.typ.clear_flag(.result)
|
||||
unwrapped_c_typ := g.typ(unwrapped_typ)
|
||||
c_typ := g.typ(node.typ)
|
||||
|
||||
if node.or_expr.kind == .block {
|
||||
g.writeln('${tmp_left}.is_error = _o${res}.is_error;')
|
||||
g.writeln('${tmp_left}.err = _o${res}.err;')
|
||||
g.or_block(tmp_left, node.or_expr, node.typ.set_flag(.result))
|
||||
g.writeln('else {')
|
||||
g.indent++
|
||||
} else if node.or_expr.kind == .absent {
|
||||
g.write_error_handling_for_orm_result(node.pos, '_o${res}')
|
||||
}
|
||||
mut non_orm_result_var_name := g.new_tmp_var()
|
||||
g.writeln('${c_typ} ${non_orm_result_var_name};')
|
||||
g.writeln('${non_orm_result_var_name}.is_error = ${select_result_var_name}.is_error;')
|
||||
g.writeln('${non_orm_result_var_name}.err = ${select_result_var_name}.err;')
|
||||
g.or_block(non_orm_result_var_name, node.or_expr, node.typ)
|
||||
g.writeln('else {')
|
||||
g.indent++
|
||||
|
||||
g.writeln('Array_Array_orm__Primitive ${res} = (*(Array_Array_orm__Primitive*)_o${res}.data);')
|
||||
select_unwrapped_result_var_name := g.new_tmp_var()
|
||||
|
||||
g.writeln('Array_Array_orm__Primitive ${select_unwrapped_result_var_name} = (*(Array_Array_orm__Primitive*)${select_result_var_name}.data);')
|
||||
|
||||
if node.is_count {
|
||||
g.writeln('*(${g.typ(node.typ)}*) ${tmp_left}.data = *((*(orm__Primitive*) array_get((*(Array_orm__Primitive*)array_get(${res}, 0)), 0))._int);')
|
||||
if node.or_expr.kind == .block {
|
||||
g.indent--
|
||||
g.writeln('}')
|
||||
}
|
||||
g.writeln('*(${unwrapped_c_typ}*) ${non_orm_result_var_name}.data = *((*(orm__Primitive*) array_get((*(Array_orm__Primitive*)array_get(${select_unwrapped_result_var_name}, 0)), 0))._int);')
|
||||
|
||||
g.indent--
|
||||
g.writeln('}')
|
||||
} else {
|
||||
tmp := g.new_tmp_var()
|
||||
styp := g.typ(node.typ)
|
||||
idx := g.new_tmp_var()
|
||||
g.writeln('int ${idx} = 0;')
|
||||
mut typ_str := ''
|
||||
if node.is_array {
|
||||
info := g.table.sym(node.typ).array_info()
|
||||
typ_str = g.typ(info.elem_type)
|
||||
g.writeln('${styp} ${tmp}_array = __new_array(0, ${res}.len, sizeof(${typ_str}));')
|
||||
g.writeln('for (; ${idx} < ${res}.len; ${idx}++) {')
|
||||
g.writeln('${unwrapped_c_typ} ${tmp}_array = __new_array(0, ${select_unwrapped_result_var_name}.len, sizeof(${typ_str}));')
|
||||
g.writeln('for (; ${idx} < ${select_unwrapped_result_var_name}.len; ${idx}++) {')
|
||||
g.indent++
|
||||
g.write('${typ_str} ${tmp} = (${typ_str}) {')
|
||||
inf := g.table.sym(info.elem_type).struct_info()
|
||||
@ -693,7 +687,7 @@ fn (mut g Gen) sql_select(node ast.SqlExpr, expr string, left string, or_expr as
|
||||
}
|
||||
g.writeln('};')
|
||||
} else {
|
||||
g.write('${styp} ${tmp} = (${styp}){')
|
||||
g.write('${unwrapped_c_typ} ${tmp} = (${unwrapped_c_typ}){')
|
||||
info := g.table.sym(node.typ).struct_info()
|
||||
for i, field in info.fields {
|
||||
g.zero_struct_field(field)
|
||||
@ -704,10 +698,10 @@ fn (mut g Gen) sql_select(node ast.SqlExpr, expr string, left string, or_expr as
|
||||
g.writeln('};')
|
||||
}
|
||||
|
||||
g.writeln('if (${res}.len > 0) {')
|
||||
g.writeln('if (${select_unwrapped_result_var_name}.len > 0) {')
|
||||
g.indent++
|
||||
for i, field in fields {
|
||||
sel := '(*(orm__Primitive*) array_get((*(Array_orm__Primitive*) array_get(${res}, ${idx})), ${i}))'
|
||||
sel := '(*(orm__Primitive*) array_get((*(Array_orm__Primitive*) array_get(${select_unwrapped_result_var_name}, ${idx})), ${i}))'
|
||||
sym := g.table.sym(field.typ)
|
||||
if sym.kind == .struct_ && sym.name != 'time.Time' {
|
||||
mut sub := node.sub_structs[int(field.typ)]
|
||||
@ -758,7 +752,7 @@ fn (mut g Gen) sql_select(node ast.SqlExpr, expr string, left string, or_expr as
|
||||
scope: 0
|
||||
}
|
||||
mut arr := ast.SqlExpr{
|
||||
typ: field.typ
|
||||
typ: field.typ.set_flag(.result)
|
||||
is_count: sub.is_count
|
||||
db_expr: sub.db_expr
|
||||
has_where: sub.has_where
|
||||
@ -768,6 +762,7 @@ fn (mut g Gen) sql_select(node ast.SqlExpr, expr string, left string, or_expr as
|
||||
order_expr: sub.order_expr
|
||||
has_desc: sub.has_desc
|
||||
is_array: true
|
||||
is_generated: true
|
||||
pos: sub.pos
|
||||
has_limit: sub.has_limit
|
||||
limit_expr: sub.limit_expr
|
||||
@ -791,19 +786,19 @@ fn (mut g Gen) sql_select(node ast.SqlExpr, expr string, left string, or_expr as
|
||||
g.writeln('}')
|
||||
}
|
||||
|
||||
g.write('*(${g.typ(node.typ)}*) ${tmp_left}.data = ${tmp}')
|
||||
g.write('*(${unwrapped_c_typ}*) ${non_orm_result_var_name}.data = ${tmp}')
|
||||
if node.is_array {
|
||||
g.write('_array')
|
||||
}
|
||||
g.writeln(';')
|
||||
if node.or_expr.kind == .block {
|
||||
g.indent--
|
||||
g.writeln('}')
|
||||
}
|
||||
|
||||
g.indent--
|
||||
g.writeln('}')
|
||||
}
|
||||
g.write('${left} *(${g.typ(node.typ)}*) ${tmp_left}.data')
|
||||
if !g.inside_call {
|
||||
g.writeln(';')
|
||||
g.write('${left} *(${unwrapped_c_typ}*) ${non_orm_result_var_name}.data')
|
||||
|
||||
if node.is_generated {
|
||||
g.write(';')
|
||||
}
|
||||
}
|
||||
|
||||
@ -862,20 +857,6 @@ fn (mut g Gen) get_field_name(field ast.StructField) string {
|
||||
return name
|
||||
}
|
||||
|
||||
fn (mut g Gen) write_error_handling_for_orm_result(expr_pos &token.Pos, result_var_name string) {
|
||||
g.writeln('if (${result_var_name}.is_error) {')
|
||||
|
||||
if g.pref.is_debug {
|
||||
g.write_v_source_line_info(expr_pos)
|
||||
paline, pafile, pamod, pafn := g.panic_debug_info(expr_pos)
|
||||
g.write('\tpanic_debug(${paline}, tos3("${pafile}"), tos3("${pamod}"), tos3("${pafn}"), IError_str(${result_var_name}.err) );')
|
||||
} else {
|
||||
g.writeln('\t_v_panic(IError_str(${result_var_name}.err));')
|
||||
}
|
||||
|
||||
g.writeln('}')
|
||||
}
|
||||
|
||||
fn (mut g Gen) write_orm_connection_init(connection_var_name string, db_expr &ast.Expr) {
|
||||
db_expr_type := g.get_db_type(db_expr) or { verror('V ORM: unknown db type for ${db_expr}') }
|
||||
|
||||
@ -884,7 +865,7 @@ fn (mut g Gen) write_orm_connection_init(connection_var_name string, db_expr &as
|
||||
reference_sign := if is_pointer { '' } else { '&' }
|
||||
db_ctype_name = db_ctype_name.trim_right('*')
|
||||
|
||||
g.writeln('// orm')
|
||||
g.writeln('// V ORM')
|
||||
g.write('orm__Connection ${connection_var_name} = ')
|
||||
|
||||
if db_ctype_name == 'orm__Connection' {
|
||||
|
@ -85,9 +85,10 @@ fn (mut p Parser) sql_expr() ast.Expr {
|
||||
p.inside_match = false
|
||||
or_expr := p.parse_sql_or_block()
|
||||
p.inside_match = tmp_inside_match
|
||||
|
||||
return ast.SqlExpr{
|
||||
is_count: is_count
|
||||
typ: typ
|
||||
typ: typ.set_flag(.result)
|
||||
or_expr: or_expr
|
||||
db_expr: db_expr
|
||||
where_expr: where_expr
|
||||
@ -100,6 +101,7 @@ fn (mut p Parser) sql_expr() ast.Expr {
|
||||
order_expr: order_expr
|
||||
has_desc: has_desc
|
||||
is_array: if is_count { false } else { true }
|
||||
is_generated: false
|
||||
pos: pos.extend(p.prev_tok.pos())
|
||||
table_expr: ast.TypeNode{
|
||||
typ: table_type
|
||||
@ -149,21 +151,11 @@ fn (mut p Parser) parse_sql_or_block() ast.OrExpr {
|
||||
mut pos := p.tok.pos()
|
||||
|
||||
if p.tok.kind == .key_orelse {
|
||||
was_inside_or_expr := p.inside_or_expr
|
||||
p.inside_or_expr = true
|
||||
p.next()
|
||||
p.open_scope()
|
||||
p.scope.register(ast.Var{
|
||||
name: 'err'
|
||||
typ: ast.error_type
|
||||
pos: p.tok.pos()
|
||||
is_used: true
|
||||
})
|
||||
kind = .block
|
||||
stmts = p.parse_block_no_scope(false)
|
||||
pos = pos.extend(p.prev_tok.pos())
|
||||
p.close_scope()
|
||||
p.inside_or_expr = was_inside_or_expr
|
||||
stmts, pos = p.or_block(.with_err_var)
|
||||
} else if p.tok.kind == .not {
|
||||
kind = .propagate_result
|
||||
p.next()
|
||||
}
|
||||
|
||||
return ast.OrExpr{
|
||||
@ -198,6 +190,7 @@ fn (mut p Parser) parse_sql_stmt_line() ast.SqlStmtLine {
|
||||
pos: typ_pos
|
||||
}
|
||||
scope: p.scope
|
||||
is_generated: false
|
||||
}
|
||||
} else if n == 'drop' {
|
||||
kind = .drop
|
||||
@ -215,6 +208,7 @@ fn (mut p Parser) parse_sql_stmt_line() ast.SqlStmtLine {
|
||||
typ: typ
|
||||
pos: typ_pos
|
||||
}
|
||||
is_generated: false
|
||||
scope: p.scope
|
||||
}
|
||||
}
|
||||
@ -285,14 +279,14 @@ fn (mut p Parser) parse_sql_stmt_line() ast.SqlStmtLine {
|
||||
update_exprs: update_exprs
|
||||
kind: kind
|
||||
where_expr: where_expr
|
||||
is_top_level: true
|
||||
is_generated: false
|
||||
scope: p.scope
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut p Parser) check_sql_keyword(name string) ?bool {
|
||||
if p.check_name() != name {
|
||||
p.error('orm: expecting `${name}`')
|
||||
p.error('V ORM: expecting `${name}`')
|
||||
return none
|
||||
}
|
||||
return true
|
||||
|
7
vlib/v/parser/tests/orm_no_error_handler.out
Normal file
7
vlib/v/parser/tests/orm_no_error_handler.out
Normal file
@ -0,0 +1,7 @@
|
||||
vlib/v/parser/tests/orm_no_error_handler.vv:8:7: error: V ORM returns a result, so it should have either an `or {}` block, or `!` at the end
|
||||
6 | db := true
|
||||
7 |
|
||||
8 | _ := sql db {
|
||||
| ~~~~~~~~
|
||||
9 | select from User
|
||||
10 | }
|
11
vlib/v/parser/tests/orm_no_error_handler.vv
Normal file
11
vlib/v/parser/tests/orm_no_error_handler.vv
Normal file
@ -0,0 +1,11 @@
|
||||
struct User {
|
||||
id int
|
||||
}
|
||||
|
||||
fn main() {
|
||||
db := true
|
||||
|
||||
_ := sql db {
|
||||
select from User
|
||||
}
|
||||
}
|
@ -3,5 +3,5 @@ vlib/v/parser/tests/sql_undefined_variables_in_complex_exprs.vv:13:73: error: un
|
||||
12 | _ := sql _ {
|
||||
13 | select from User where (age > 18) && (city == 'London' || username == username)
|
||||
| ~~~~~~~~
|
||||
14 | }
|
||||
14 | }!
|
||||
15 | }
|
||||
|
@ -11,5 +11,5 @@ mut:
|
||||
fn main() {
|
||||
_ := sql _ {
|
||||
select from User where (age > 18) && (city == 'London' || username == username)
|
||||
}
|
||||
}!
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
================ V panic ================
|
||||
module: main
|
||||
function: main()
|
||||
message: db.sqlite.SQLError: no such table: User (1) (INSERT INTO `User` (`id`, `name`) VALUES (?1, ?2);); code: 1
|
||||
file: vlib/v/slow_tests/inout/orm_panic_for_insert_into_not_created_table.vv:16
|
||||
message: no such table: User (1) (INSERT INTO `User` (`id`, `name`) VALUES (?1, ?2);); code: 1
|
||||
file: vlib/v/slow_tests/inout/orm_panic_for_insert_into_not_created_table.vv:17
|
||||
|
@ -14,5 +14,5 @@ fn main() {
|
||||
|
||||
sql db {
|
||||
insert user into User
|
||||
}
|
||||
}!
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
================ V panic ================
|
||||
module: main
|
||||
function: main()
|
||||
message: db.sqlite.SQLError: no such table: User (1) (SELECT `id`, `name` FROM `User`;); code: 1
|
||||
file: vlib/v/slow_tests/inout/orm_panic_for_select_from_not_created_table.vv:11
|
||||
message: no such table: User (1) (SELECT `id`, `name` FROM `User`;); code: 1
|
||||
file: vlib/v/slow_tests/inout/orm_panic_for_select_from_not_created_table.vv:13
|
||||
|
@ -10,7 +10,7 @@ fn main() {
|
||||
|
||||
users := sql db {
|
||||
select from User
|
||||
}
|
||||
}!
|
||||
|
||||
println(users)
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ pub mut:
|
||||
arch []GitRepoArch [fkey: 'repo_id']
|
||||
}
|
||||
|
||||
pub fn (db &VieterDb) get_git_repos() []GitRepo {
|
||||
pub fn (db &VieterDb) get_git_repos() ![]GitRepo {
|
||||
// NB: the query here, uses the `repo` field on GitRepo,
|
||||
// while GitRepo is joined to GitRepoArch,
|
||||
// which does *not* have a `repo` field.
|
||||
@ -28,7 +28,7 @@ pub fn (db &VieterDb) get_git_repos() []GitRepo {
|
||||
// a lingering c.cur_orm_ts state. The fix was to save/restore c.cur_orm_ts .
|
||||
res := sql db.conn {
|
||||
select from GitRepo where repo == 'something' order by id
|
||||
}
|
||||
}!
|
||||
return res
|
||||
}
|
||||
|
||||
|
@ -17,10 +17,10 @@ fn test_orm_array() {
|
||||
mut db := sqlite.connect(':memory:') or { panic(err) }
|
||||
sql db {
|
||||
create table Parent
|
||||
}
|
||||
}!
|
||||
sql db {
|
||||
create table Child
|
||||
}
|
||||
}!
|
||||
|
||||
par := Parent{
|
||||
name: 'test'
|
||||
@ -36,15 +36,15 @@ fn test_orm_array() {
|
||||
|
||||
sql db {
|
||||
insert par into Parent
|
||||
}
|
||||
}!
|
||||
|
||||
parents := sql db {
|
||||
select from Parent where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
sql db {
|
||||
drop table Parent
|
||||
}
|
||||
}!
|
||||
|
||||
parent := parents.first()
|
||||
assert parent.name == par.name
|
||||
@ -57,10 +57,10 @@ fn test_orm_relationship() {
|
||||
mut db := sqlite.connect(':memory:') or { panic(err) }
|
||||
sql db {
|
||||
create table Parent
|
||||
}
|
||||
}!
|
||||
sql db {
|
||||
create table Child
|
||||
}
|
||||
}!
|
||||
|
||||
mut child := Child{
|
||||
name: 'abc'
|
||||
@ -73,11 +73,11 @@ fn test_orm_relationship() {
|
||||
|
||||
sql db {
|
||||
insert par into Parent
|
||||
}
|
||||
}!
|
||||
|
||||
mut parents := sql db {
|
||||
select from Parent where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
mut parent := parents.first()
|
||||
child.parent_id = parent.id
|
||||
@ -85,20 +85,20 @@ fn test_orm_relationship() {
|
||||
|
||||
sql db {
|
||||
insert child into Child
|
||||
}
|
||||
}!
|
||||
|
||||
child.name = 'bacon'
|
||||
|
||||
sql db {
|
||||
insert child into Child
|
||||
}
|
||||
}!
|
||||
|
||||
assert parent.name == par.name
|
||||
assert parent.children.len == 0
|
||||
|
||||
parents = sql db {
|
||||
select from Parent where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
parent = parents.first()
|
||||
assert parent.name == par.name
|
||||
@ -108,17 +108,17 @@ fn test_orm_relationship() {
|
||||
|
||||
mut children := sql db {
|
||||
select from Child
|
||||
}
|
||||
}!
|
||||
|
||||
assert children.len == 2
|
||||
|
||||
sql db {
|
||||
drop table Parent
|
||||
}
|
||||
}!
|
||||
|
||||
children = sql db {
|
||||
select from Child
|
||||
}
|
||||
}!
|
||||
|
||||
assert children.len == 2
|
||||
}
|
||||
|
@ -14,10 +14,10 @@ fn test_orm_sub_structs() {
|
||||
db := sqlite.connect(':memory:') or { panic(err) }
|
||||
sql db {
|
||||
create table Upper
|
||||
}
|
||||
}!
|
||||
sql db {
|
||||
create table SubStruct
|
||||
}
|
||||
}!
|
||||
|
||||
upper_1 := Upper{
|
||||
sub: SubStruct{
|
||||
@ -27,11 +27,11 @@ fn test_orm_sub_structs() {
|
||||
|
||||
sql db {
|
||||
insert upper_1 into Upper
|
||||
}
|
||||
}!
|
||||
|
||||
uppers := sql db {
|
||||
select from Upper where id == 1
|
||||
}
|
||||
}!
|
||||
|
||||
assert uppers.first().sub.name == upper_1.sub.name
|
||||
}
|
||||
|
@ -13,12 +13,12 @@ fn test_sql_statement_inside_fn_call() {
|
||||
db := sqlite.connect(':memory:') or { panic('failed') }
|
||||
sql db {
|
||||
create table Movie
|
||||
}
|
||||
}!
|
||||
m := Movie{1, 'Maria'}
|
||||
sql db {
|
||||
insert m into Movie
|
||||
}
|
||||
dump(x((sql db {
|
||||
}!
|
||||
dump(x(sql db {
|
||||
select from Movie where id == 1
|
||||
}).first()))
|
||||
}!.first()))
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ pub fn (mut app App) new_article() vweb.Result {
|
||||
println(article)
|
||||
sql app.db {
|
||||
insert article into Article
|
||||
}
|
||||
} or {}
|
||||
|
||||
return app.redirect('/')
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user