mirror of
https://github.com/vlang/v.git
synced 2025-08-03 17:57:59 -04:00
breaking,orm: add table attrs; add table/field comment support for mysql and pg (#24744)
This commit is contained in:
parent
d52bac1301
commit
d4097212b3
@ -37,6 +37,13 @@ struct TestDefaultAttribute {
|
|||||||
created_at string @[default: 'CURRENT_TIMESTAMP'; sql_type: 'TIMESTAMP']
|
created_at string @[default: 'CURRENT_TIMESTAMP'; sql_type: 'TIMESTAMP']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@[comment: 'This is a table comment']
|
||||||
|
struct TestCommentAttribute {
|
||||||
|
id string @[primary; sql: serial]
|
||||||
|
name string @[comment: 'real user name']
|
||||||
|
created_at string @[default: 'CURRENT_TIMESTAMP'; sql_type: 'TIMESTAMP']
|
||||||
|
}
|
||||||
|
|
||||||
fn test_mysql_orm() {
|
fn test_mysql_orm() {
|
||||||
$if !network ? {
|
$if !network ? {
|
||||||
eprintln('> Skipping test ${@FN}, since `-d network` is not passed.')
|
eprintln('> Skipping test ${@FN}, since `-d network` is not passed.')
|
||||||
@ -47,13 +54,17 @@ fn test_mysql_orm() {
|
|||||||
host: '127.0.0.1'
|
host: '127.0.0.1'
|
||||||
port: 3306
|
port: 3306
|
||||||
username: 'root'
|
username: 'root'
|
||||||
password: ''
|
password: '12345678'
|
||||||
dbname: 'mysql'
|
dbname: 'mysql'
|
||||||
)!
|
)!
|
||||||
defer {
|
defer {
|
||||||
db.close()
|
db.close()
|
||||||
}
|
}
|
||||||
db.create('Test', [
|
table := orm.Table{
|
||||||
|
name: 'Test'
|
||||||
|
}
|
||||||
|
db.drop(table) or {}
|
||||||
|
db.create(table, [
|
||||||
orm.TableField{
|
orm.TableField{
|
||||||
name: 'id'
|
name: 'id'
|
||||||
typ: typeof[int]().idx
|
typ: typeof[int]().idx
|
||||||
@ -80,13 +91,13 @@ fn test_mysql_orm() {
|
|||||||
},
|
},
|
||||||
]) or { panic(err) }
|
]) or { panic(err) }
|
||||||
|
|
||||||
db.insert('Test', orm.QueryData{
|
db.insert(table, orm.QueryData{
|
||||||
fields: ['name', 'age']
|
fields: ['name', 'age']
|
||||||
data: [orm.string_to_primitive('Louis'), orm.int_to_primitive(101)]
|
data: [orm.string_to_primitive('Louis'), orm.int_to_primitive(101)]
|
||||||
}) or { panic(err) }
|
}) or { panic(err) }
|
||||||
|
|
||||||
res := db.select(orm.SelectConfig{
|
res := db.select(orm.SelectConfig{
|
||||||
table: 'Test'
|
table: table
|
||||||
has_where: true
|
has_where: true
|
||||||
fields: ['id', 'name', 'age']
|
fields: ['id', 'name', 'age']
|
||||||
types: [typeof[int]().idx, typeof[string]().idx, typeof[i64]().idx]
|
types: [typeof[int]().idx, typeof[string]().idx, typeof[i64]().idx]
|
||||||
@ -272,4 +283,49 @@ fn test_mysql_orm() {
|
|||||||
'COLUMN_DEFAULT': 'CURRENT_TIMESTAMP'
|
'COLUMN_DEFAULT': 'CURRENT_TIMESTAMP'
|
||||||
}]
|
}]
|
||||||
assert information_schema_column_default_sql == result_defaults.maps()
|
assert information_schema_column_default_sql == result_defaults.maps()
|
||||||
|
|
||||||
|
/** test comment attribute
|
||||||
|
*/
|
||||||
|
sql db {
|
||||||
|
create table TestCommentAttribute
|
||||||
|
}!
|
||||||
|
|
||||||
|
mut column_comments := db.query("
|
||||||
|
SELECT COLUMN_COMMENT
|
||||||
|
FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_NAME = 'TestCommentAttribute'
|
||||||
|
ORDER BY ORDINAL_POSITION
|
||||||
|
") or {
|
||||||
|
println(err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mut table_comment := db.query("
|
||||||
|
SELECT TABLE_COMMENT
|
||||||
|
FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE TABLE_NAME = 'TestCommentAttribute'
|
||||||
|
") or {
|
||||||
|
println(err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sql db {
|
||||||
|
drop table TestCommentAttribute
|
||||||
|
}!
|
||||||
|
|
||||||
|
information_schema_column_comment_sql := [{
|
||||||
|
'COLUMN_COMMENT': ''
|
||||||
|
}, {
|
||||||
|
'COLUMN_COMMENT': 'real user name'
|
||||||
|
}, {
|
||||||
|
'COLUMN_COMMENT': ''
|
||||||
|
}]
|
||||||
|
assert information_schema_column_comment_sql == column_comments.maps()
|
||||||
|
|
||||||
|
information_schema_table_comment_sql := [
|
||||||
|
{
|
||||||
|
'TABLE_COMMENT': 'This is a table comment'
|
||||||
|
},
|
||||||
|
]
|
||||||
|
assert information_schema_table_comment_sql == table_comment.maps()
|
||||||
}
|
}
|
||||||
|
@ -122,8 +122,8 @@ pub fn (db DB) select(config orm.SelectConfig, data orm.QueryData, where orm.Que
|
|||||||
}
|
}
|
||||||
|
|
||||||
// insert is used internally by V's ORM for processing `INSERT ` queries
|
// insert is used internally by V's ORM for processing `INSERT ` queries
|
||||||
pub fn (db DB) insert(table string, data orm.QueryData) ! {
|
pub fn (db DB) insert(table orm.Table, data orm.QueryData) ! {
|
||||||
mut converted_primitive_array := db.convert_query_data_to_primitives(table, data)!
|
mut converted_primitive_array := db.convert_query_data_to_primitives(table.name, data)!
|
||||||
|
|
||||||
converted_primitive_data := orm.QueryData{
|
converted_primitive_data := orm.QueryData{
|
||||||
fields: data.fields
|
fields: data.fields
|
||||||
@ -139,13 +139,13 @@ pub fn (db DB) insert(table string, data orm.QueryData) ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update is used internally by V's ORM for processing `UPDATE ` queries
|
// update is used internally by V's ORM for processing `UPDATE ` queries
|
||||||
pub fn (db DB) update(table string, data orm.QueryData, where orm.QueryData) ! {
|
pub fn (db DB) update(table orm.Table, data orm.QueryData, where orm.QueryData) ! {
|
||||||
query, _ := orm.orm_stmt_gen(.default, table, '`', .update, false, '?', 1, data, where)
|
query, _ := orm.orm_stmt_gen(.default, table, '`', .update, false, '?', 1, data, where)
|
||||||
mysql_stmt_worker(db, query, data, where)!
|
mysql_stmt_worker(db, query, data, where)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete is used internally by V's ORM for processing `DELETE ` queries
|
// delete is used internally by V's ORM for processing `DELETE ` queries
|
||||||
pub fn (db DB) delete(table string, where orm.QueryData) ! {
|
pub fn (db DB) delete(table orm.Table, where orm.QueryData) ! {
|
||||||
query, _ := orm.orm_stmt_gen(.default, table, '`', .delete, false, '?', 1, orm.QueryData{},
|
query, _ := orm.orm_stmt_gen(.default, table, '`', .delete, false, '?', 1, orm.QueryData{},
|
||||||
where)
|
where)
|
||||||
mysql_stmt_worker(db, query, orm.QueryData{}, where)!
|
mysql_stmt_worker(db, query, orm.QueryData{}, where)!
|
||||||
@ -160,16 +160,15 @@ pub fn (db DB) last_id() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create is used internally by V's ORM for processing table creation queries (DDL)
|
// create is used internally by V's ORM for processing table creation queries (DDL)
|
||||||
pub fn (db DB) create(table string, fields []orm.TableField) ! {
|
pub fn (db DB) create(table orm.Table, fields []orm.TableField) ! {
|
||||||
query := orm.orm_table_gen(table, '`', true, 0, fields, mysql_type_from_v, false) or {
|
query := orm.orm_table_gen(.mysql, table, '`', true, 0, fields, mysql_type_from_v,
|
||||||
return err
|
false) or { return err }
|
||||||
}
|
|
||||||
mysql_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
mysql_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
||||||
}
|
}
|
||||||
|
|
||||||
// drop is used internally by V's ORM for processing table destroying queries (DDL)
|
// drop is used internally by V's ORM for processing table destroying queries (DDL)
|
||||||
pub fn (db DB) drop(table string) ! {
|
pub fn (db DB) drop(table orm.Table) ! {
|
||||||
query := 'DROP TABLE `${table}`;'
|
query := 'DROP TABLE `${table.name}`;'
|
||||||
mysql_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
mysql_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,20 +31,20 @@ pub fn (db DB) select(config orm.SelectConfig, data orm.QueryData, where orm.Que
|
|||||||
// sql stmt
|
// sql stmt
|
||||||
|
|
||||||
// insert is used internally by V's ORM for processing `INSERT ` queries
|
// insert is used internally by V's ORM for processing `INSERT ` queries
|
||||||
pub fn (db DB) insert(table string, data orm.QueryData) ! {
|
pub fn (db DB) insert(table orm.Table, data orm.QueryData) ! {
|
||||||
query, converted_data := orm.orm_stmt_gen(.default, table, '"', .insert, true, '$',
|
query, converted_data := orm.orm_stmt_gen(.default, table, '"', .insert, true, '$',
|
||||||
1, data, orm.QueryData{})
|
1, data, orm.QueryData{})
|
||||||
pg_stmt_worker(db, query, converted_data, orm.QueryData{})!
|
pg_stmt_worker(db, query, converted_data, orm.QueryData{})!
|
||||||
}
|
}
|
||||||
|
|
||||||
// update is used internally by V's ORM for processing `UPDATE ` queries
|
// update is used internally by V's ORM for processing `UPDATE ` queries
|
||||||
pub fn (db DB) update(table string, data orm.QueryData, where orm.QueryData) ! {
|
pub fn (db DB) update(table orm.Table, data orm.QueryData, where orm.QueryData) ! {
|
||||||
query, _ := orm.orm_stmt_gen(.default, table, '"', .update, true, '$', 1, data, where)
|
query, _ := orm.orm_stmt_gen(.default, table, '"', .update, true, '$', 1, data, where)
|
||||||
pg_stmt_worker(db, query, data, where)!
|
pg_stmt_worker(db, query, data, where)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete is used internally by V's ORM for processing `DELETE ` queries
|
// delete is used internally by V's ORM for processing `DELETE ` queries
|
||||||
pub fn (db DB) delete(table string, where orm.QueryData) ! {
|
pub fn (db DB) delete(table orm.Table, where orm.QueryData) ! {
|
||||||
query, _ := orm.orm_stmt_gen(.default, table, '"', .delete, true, '$', 1, orm.QueryData{},
|
query, _ := orm.orm_stmt_gen(.default, table, '"', .delete, true, '$', 1, orm.QueryData{},
|
||||||
where)
|
where)
|
||||||
pg_stmt_worker(db, query, orm.QueryData{}, where)!
|
pg_stmt_worker(db, query, orm.QueryData{}, where)!
|
||||||
@ -60,14 +60,21 @@ pub fn (db DB) last_id() int {
|
|||||||
// DDL (table creation/destroying etc)
|
// DDL (table creation/destroying etc)
|
||||||
|
|
||||||
// create is used internally by V's ORM for processing table creation queries (DDL)
|
// create is used internally by V's ORM for processing table creation queries (DDL)
|
||||||
pub fn (db DB) create(table string, fields []orm.TableField) ! {
|
pub fn (db DB) create(table orm.Table, fields []orm.TableField) ! {
|
||||||
query := orm.orm_table_gen(table, '"', true, 0, fields, pg_type_from_v, false) or { return err }
|
query := orm.orm_table_gen(.pg, table, '"', true, 0, fields, pg_type_from_v, false) or {
|
||||||
pg_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
return err
|
||||||
|
}
|
||||||
|
stmts := query.split(';')
|
||||||
|
for stmt in stmts {
|
||||||
|
if stmt != '' {
|
||||||
|
pg_stmt_worker(db, stmt + ';', orm.QueryData{}, orm.QueryData{})!
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// drop is used internally by V's ORM for processing table destroying queries (DDL)
|
// drop is used internally by V's ORM for processing table destroying queries (DDL)
|
||||||
pub fn (db DB) drop(table string) ! {
|
pub fn (db DB) drop(table orm.Table) ! {
|
||||||
query := 'DROP TABLE "${table}";'
|
query := 'DROP TABLE "${table.name}";'
|
||||||
pg_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
pg_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,13 @@ struct TestDefaultAttribute {
|
|||||||
created_at string @[default: 'CURRENT_TIMESTAMP'; sql_type: 'TIMESTAMP']
|
created_at string @[default: 'CURRENT_TIMESTAMP'; sql_type: 'TIMESTAMP']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@[comment: 'This is a table comment']
|
||||||
|
struct TestCommentAttribute {
|
||||||
|
id string @[primary; sql: serial]
|
||||||
|
name string @[comment: 'real user name']
|
||||||
|
created_at string @[default: 'CURRENT_TIMESTAMP'; sql_type: 'TIMESTAMP']
|
||||||
|
}
|
||||||
|
|
||||||
fn test_pg_orm() {
|
fn test_pg_orm() {
|
||||||
$if !network ? {
|
$if !network ? {
|
||||||
eprintln('> Skipping test ${@FN}, since `-d network` is not passed.')
|
eprintln('> Skipping test ${@FN}, since `-d network` is not passed.')
|
||||||
@ -46,15 +53,18 @@ fn test_pg_orm() {
|
|||||||
host: 'localhost'
|
host: 'localhost'
|
||||||
user: 'postgres'
|
user: 'postgres'
|
||||||
password: '12345678'
|
password: '12345678'
|
||||||
dbname: 'test'
|
dbname: 'postgres'
|
||||||
) or { panic(err) }
|
) or { panic(err) }
|
||||||
|
|
||||||
defer {
|
defer {
|
||||||
db.close()
|
db.close()
|
||||||
}
|
}
|
||||||
db.drop('Test')!
|
table := orm.Table{
|
||||||
|
name: 'Test'
|
||||||
|
}
|
||||||
|
db.drop(table) or {}
|
||||||
|
|
||||||
db.create('Test', [
|
db.create(table, [
|
||||||
orm.TableField{
|
orm.TableField{
|
||||||
name: 'id'
|
name: 'id'
|
||||||
typ: typeof[string]().idx
|
typ: typeof[string]().idx
|
||||||
@ -94,13 +104,13 @@ fn test_pg_orm() {
|
|||||||
},
|
},
|
||||||
]) or { panic(err) }
|
]) or { panic(err) }
|
||||||
|
|
||||||
db.insert('Test', orm.QueryData{
|
db.insert(table, orm.QueryData{
|
||||||
fields: ['name', 'age']
|
fields: ['name', 'age']
|
||||||
data: [orm.string_to_primitive('Louis'), orm.int_to_primitive(101)]
|
data: [orm.string_to_primitive('Louis'), orm.int_to_primitive(101)]
|
||||||
}) or { panic(err) }
|
}) or { panic(err) }
|
||||||
|
|
||||||
res := db.select(orm.SelectConfig{
|
res := db.select(orm.SelectConfig{
|
||||||
table: 'Test'
|
table: table
|
||||||
is_count: false
|
is_count: false
|
||||||
has_where: true
|
has_where: true
|
||||||
has_order: false
|
has_order: false
|
||||||
@ -143,7 +153,7 @@ fn test_pg_orm() {
|
|||||||
*/
|
*/
|
||||||
sql db {
|
sql db {
|
||||||
drop table TestCustomSqlType
|
drop table TestCustomSqlType
|
||||||
}!
|
} or {}
|
||||||
|
|
||||||
sql db {
|
sql db {
|
||||||
create table TestCustomSqlType
|
create table TestCustomSqlType
|
||||||
@ -232,4 +242,60 @@ fn test_pg_orm() {
|
|||||||
drop table TestDefaultAttribute
|
drop table TestDefaultAttribute
|
||||||
}!
|
}!
|
||||||
assert ['gen_random_uuid()', '', 'CURRENT_TIMESTAMP'] == information_schema_defaults_results
|
assert ['gen_random_uuid()', '', 'CURRENT_TIMESTAMP'] == information_schema_defaults_results
|
||||||
|
|
||||||
|
/** test comment attribute
|
||||||
|
*/
|
||||||
|
sql db {
|
||||||
|
create table TestCommentAttribute
|
||||||
|
}!
|
||||||
|
|
||||||
|
mut column_comments := db.exec("
|
||||||
|
SELECT
|
||||||
|
a.attname AS column_name,
|
||||||
|
col_description(a.attrelid, a.attnum) AS column_comment
|
||||||
|
FROM pg_attribute a
|
||||||
|
JOIN pg_class c ON c.oid = a.attrelid
|
||||||
|
JOIN pg_namespace n ON n.oid = c.relnamespace
|
||||||
|
WHERE c.relname = 'TestCommentAttribute'
|
||||||
|
AND n.nspname = 'public'
|
||||||
|
AND a.attnum > 0
|
||||||
|
AND NOT a.attisdropped
|
||||||
|
ORDER BY a.attnum
|
||||||
|
") or {
|
||||||
|
println(err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
mut table_comment := db.exec("
|
||||||
|
SELECT
|
||||||
|
nspname AS schema_name,
|
||||||
|
relname AS table_name,
|
||||||
|
obj_description(pc.oid) AS table_comment
|
||||||
|
FROM pg_class pc
|
||||||
|
JOIN pg_namespace pn ON pn.oid = pc.relnamespace
|
||||||
|
WHERE pc.relkind = 'r' AND pc.relname = 'TestCommentAttribute'
|
||||||
|
ORDER BY schema_name, table_name
|
||||||
|
") or {
|
||||||
|
println(err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sql db {
|
||||||
|
drop table TestCommentAttribute
|
||||||
|
}!
|
||||||
|
|
||||||
|
mut information_schema_column_comment_results := []string{}
|
||||||
|
|
||||||
|
for comment in column_comments {
|
||||||
|
x := comment.vals[1]
|
||||||
|
information_schema_column_comment_results << x or { '' }
|
||||||
|
}
|
||||||
|
assert information_schema_column_comment_results == ['', 'real user name', '']
|
||||||
|
|
||||||
|
mut information_schema_table_comment_result := []string{}
|
||||||
|
for comment in table_comment {
|
||||||
|
x := comment.vals[2]
|
||||||
|
information_schema_table_comment_result << x or { '' }
|
||||||
|
}
|
||||||
|
assert information_schema_table_comment_result == ['This is a table comment']
|
||||||
}
|
}
|
||||||
|
@ -52,20 +52,20 @@ pub fn (db DB) select(config orm.SelectConfig, data orm.QueryData, where orm.Que
|
|||||||
// sql stmt
|
// sql stmt
|
||||||
|
|
||||||
// insert is used internally by V's ORM for processing `INSERT ` queries
|
// insert is used internally by V's ORM for processing `INSERT ` queries
|
||||||
pub fn (db DB) insert(table string, data orm.QueryData) ! {
|
pub fn (db DB) insert(table orm.Table, data orm.QueryData) ! {
|
||||||
query, converted_data := orm.orm_stmt_gen(.sqlite, table, '`', .insert, true, '?',
|
query, converted_data := orm.orm_stmt_gen(.sqlite, table, '`', .insert, true, '?',
|
||||||
1, data, orm.QueryData{})
|
1, data, orm.QueryData{})
|
||||||
sqlite_stmt_worker(db, query, converted_data, orm.QueryData{})!
|
sqlite_stmt_worker(db, query, converted_data, orm.QueryData{})!
|
||||||
}
|
}
|
||||||
|
|
||||||
// update is used internally by V's ORM for processing `UPDATE ` queries
|
// update is used internally by V's ORM for processing `UPDATE ` queries
|
||||||
pub fn (db DB) update(table string, data orm.QueryData, where orm.QueryData) ! {
|
pub fn (db DB) update(table orm.Table, data orm.QueryData, where orm.QueryData) ! {
|
||||||
query, _ := orm.orm_stmt_gen(.sqlite, table, '`', .update, true, '?', 1, data, where)
|
query, _ := orm.orm_stmt_gen(.sqlite, table, '`', .update, true, '?', 1, data, where)
|
||||||
sqlite_stmt_worker(db, query, data, where)!
|
sqlite_stmt_worker(db, query, data, where)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete is used internally by V's ORM for processing `DELETE ` queries
|
// delete is used internally by V's ORM for processing `DELETE ` queries
|
||||||
pub fn (db DB) delete(table string, where orm.QueryData) ! {
|
pub fn (db DB) delete(table orm.Table, where orm.QueryData) ! {
|
||||||
query, _ := orm.orm_stmt_gen(.sqlite, table, '`', .delete, true, '?', 1, orm.QueryData{},
|
query, _ := orm.orm_stmt_gen(.sqlite, table, '`', .delete, true, '?', 1, orm.QueryData{},
|
||||||
where)
|
where)
|
||||||
sqlite_stmt_worker(db, query, orm.QueryData{}, where)!
|
sqlite_stmt_worker(db, query, orm.QueryData{}, where)!
|
||||||
@ -81,16 +81,15 @@ pub fn (db DB) last_id() int {
|
|||||||
// DDL (table creation/destroying etc)
|
// DDL (table creation/destroying etc)
|
||||||
|
|
||||||
// create is used internally by V's ORM for processing table creation queries (DDL)
|
// create is used internally by V's ORM for processing table creation queries (DDL)
|
||||||
pub fn (db DB) create(table string, fields []orm.TableField) ! {
|
pub fn (db DB) create(table orm.Table, fields []orm.TableField) ! {
|
||||||
query := orm.orm_table_gen(table, '`', true, 0, fields, sqlite_type_from_v, false) or {
|
query := orm.orm_table_gen(.sqlite, table, '`', true, 0, fields, sqlite_type_from_v,
|
||||||
return err
|
false) or { return err }
|
||||||
}
|
|
||||||
sqlite_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
sqlite_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
||||||
}
|
}
|
||||||
|
|
||||||
// drop is used internally by V's ORM for processing table destroying queries (DDL)
|
// drop is used internally by V's ORM for processing table destroying queries (DDL)
|
||||||
pub fn (db DB) drop(table string) ! {
|
pub fn (db DB) drop(table orm.Table) ! {
|
||||||
query := 'DROP TABLE `${table}`;'
|
query := 'DROP TABLE `${table.name}`;'
|
||||||
sqlite_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
sqlite_stmt_worker(db, query, orm.QueryData{}, orm.QueryData{})!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,10 @@ fn test_sqlite_orm() {
|
|||||||
defer {
|
defer {
|
||||||
db.close() or { panic(err) }
|
db.close() or { panic(err) }
|
||||||
}
|
}
|
||||||
db.create('Test', [
|
table := orm.Table{
|
||||||
|
name: 'Test'
|
||||||
|
}
|
||||||
|
db.create(table, [
|
||||||
orm.TableField{
|
orm.TableField{
|
||||||
name: 'id'
|
name: 'id'
|
||||||
typ: typeof[int]().idx
|
typ: typeof[int]().idx
|
||||||
@ -59,13 +62,13 @@ fn test_sqlite_orm() {
|
|||||||
},
|
},
|
||||||
]) or { panic(err) }
|
]) or { panic(err) }
|
||||||
|
|
||||||
db.insert('Test', orm.QueryData{
|
db.insert(table, orm.QueryData{
|
||||||
fields: ['name', 'age']
|
fields: ['name', 'age']
|
||||||
data: [orm.string_to_primitive('Louis'), orm.i64_to_primitive(100)]
|
data: [orm.string_to_primitive('Louis'), orm.i64_to_primitive(100)]
|
||||||
}) or { panic(err) }
|
}) or { panic(err) }
|
||||||
|
|
||||||
res := db.select(orm.SelectConfig{
|
res := db.select(orm.SelectConfig{
|
||||||
table: 'Test'
|
table: table
|
||||||
has_where: true
|
has_where: true
|
||||||
fields: ['id', 'name', 'age']
|
fields: ['id', 'name', 'age']
|
||||||
types: [typeof[int]().idx, typeof[string]().idx, typeof[i64]().idx]
|
types: [typeof[int]().idx, typeof[string]().idx, typeof[i64]().idx]
|
||||||
|
@ -91,6 +91,8 @@ pub enum OrderType {
|
|||||||
|
|
||||||
pub enum SQLDialect {
|
pub enum SQLDialect {
|
||||||
default
|
default
|
||||||
|
mysql
|
||||||
|
pg
|
||||||
sqlite
|
sqlite
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +155,12 @@ pub:
|
|||||||
right Primitive
|
right Primitive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Table {
|
||||||
|
pub mut:
|
||||||
|
name string
|
||||||
|
attrs []VAttribute
|
||||||
|
}
|
||||||
|
|
||||||
pub struct TableField {
|
pub struct TableField {
|
||||||
pub mut:
|
pub mut:
|
||||||
name string
|
name string
|
||||||
@ -163,7 +171,7 @@ pub mut:
|
|||||||
is_arr bool
|
is_arr bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// table - Table name
|
// table - Table struct
|
||||||
// is_count - Either the data will be returned or an integer with the count
|
// is_count - Either the data will be returned or an integer with the count
|
||||||
// has_where - Select all or use a where expr
|
// has_where - Select all or use a where expr
|
||||||
// has_order - Order the results
|
// has_order - Order the results
|
||||||
@ -176,7 +184,7 @@ pub mut:
|
|||||||
// types - Types to select
|
// types - Types to select
|
||||||
pub struct SelectConfig {
|
pub struct SelectConfig {
|
||||||
pub mut:
|
pub mut:
|
||||||
table string
|
table Table
|
||||||
is_count bool
|
is_count bool
|
||||||
has_where bool
|
has_where bool
|
||||||
has_order bool
|
has_order bool
|
||||||
@ -200,11 +208,11 @@ pub mut:
|
|||||||
pub interface Connection {
|
pub interface Connection {
|
||||||
mut:
|
mut:
|
||||||
select(config SelectConfig, data QueryData, where QueryData) ![][]Primitive
|
select(config SelectConfig, data QueryData, where QueryData) ![][]Primitive
|
||||||
insert(table string, data QueryData) !
|
insert(table Table, data QueryData) !
|
||||||
update(table string, data QueryData, where QueryData) !
|
update(table Table, data QueryData, where QueryData) !
|
||||||
delete(table string, where QueryData) !
|
delete(table Table, where QueryData) !
|
||||||
create(table string, fields []TableField) !
|
create(table Table, fields []TableField) !
|
||||||
drop(table string) !
|
drop(table Table) !
|
||||||
last_id() int
|
last_id() int
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +221,7 @@ mut:
|
|||||||
// num - Stmt uses nums at prepared statements (? or ?1)
|
// num - Stmt uses nums at prepared statements (? or ?1)
|
||||||
// qm - Character for prepared statement (qm for question mark, as in sqlite)
|
// qm - Character for prepared statement (qm for question mark, as in sqlite)
|
||||||
// start_pos - When num is true, it's the start position of the counter
|
// start_pos - When num is true, it's the start position of the counter
|
||||||
pub fn orm_stmt_gen(sql_dialect SQLDialect, table string, q string, kind StmtKind, num bool, qm string,
|
pub fn orm_stmt_gen(sql_dialect SQLDialect, table Table, q string, kind StmtKind, num bool, qm string,
|
||||||
start_pos int, data QueryData, where QueryData) (string, QueryData) {
|
start_pos int, data QueryData, where QueryData) (string, QueryData) {
|
||||||
mut str := ''
|
mut str := ''
|
||||||
mut c := start_pos
|
mut c := start_pos
|
||||||
@ -257,7 +265,7 @@ pub fn orm_stmt_gen(sql_dialect SQLDialect, table string, q string, kind StmtKin
|
|||||||
c++
|
c++
|
||||||
}
|
}
|
||||||
|
|
||||||
str += 'INSERT INTO ${q}${table}${q} '
|
str += 'INSERT INTO ${q}${table.name}${q} '
|
||||||
|
|
||||||
are_values_empty := values.len == 0
|
are_values_empty := values.len == 0
|
||||||
|
|
||||||
@ -272,7 +280,7 @@ pub fn orm_stmt_gen(sql_dialect SQLDialect, table string, q string, kind StmtKin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.update {
|
.update {
|
||||||
str += 'UPDATE ${q}${table}${q} SET '
|
str += 'UPDATE ${q}${table.name}${q} SET '
|
||||||
for i, field in data.fields {
|
for i, field in data.fields {
|
||||||
str += '${q}${field}${q} = '
|
str += '${q}${field}${q} = '
|
||||||
if data.data.len > i {
|
if data.data.len > i {
|
||||||
@ -310,7 +318,7 @@ pub fn orm_stmt_gen(sql_dialect SQLDialect, table string, q string, kind StmtKin
|
|||||||
str += ' WHERE '
|
str += ' WHERE '
|
||||||
}
|
}
|
||||||
.delete {
|
.delete {
|
||||||
str += 'DELETE FROM ${q}${table}${q} WHERE '
|
str += 'DELETE FROM ${q}${table.name}${q} WHERE '
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// where
|
// where
|
||||||
@ -319,7 +327,7 @@ pub fn orm_stmt_gen(sql_dialect SQLDialect, table string, q string, kind StmtKin
|
|||||||
}
|
}
|
||||||
str += ';'
|
str += ';'
|
||||||
$if trace_orm_stmt ? {
|
$if trace_orm_stmt ? {
|
||||||
eprintln('> orm_stmt sql_dialect: ${sql_dialect} | table: ${table} | kind: ${kind} | query: ${str}')
|
eprintln('> orm_stmt sql_dialect: ${sql_dialect} | table: ${table.name} | kind: ${kind} | query: ${str}')
|
||||||
}
|
}
|
||||||
$if trace_orm ? {
|
$if trace_orm ? {
|
||||||
eprintln('> orm: ${str}')
|
eprintln('> orm: ${str}')
|
||||||
@ -352,7 +360,7 @@ pub fn orm_select_gen(cfg SelectConfig, q string, num bool, qm string, start_pos
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
str += ' FROM ${q}${cfg.table}${q}'
|
str += ' FROM ${q}${cfg.table.name}${q}'
|
||||||
|
|
||||||
mut c := start_pos
|
mut c := start_pos
|
||||||
|
|
||||||
@ -441,19 +449,19 @@ fn gen_where_clause(where QueryData, q string, qm string, num bool, mut c &int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generates an sql table stmt, from universal parameter
|
// Generates an sql table stmt, from universal parameter
|
||||||
// table - Table name
|
// table - Table struct
|
||||||
// q - see orm_stmt_gen
|
// q - see orm_stmt_gen
|
||||||
// defaults - enables default values in stmt
|
// defaults - enables default values in stmt
|
||||||
// def_unique_len - sets default unique length for texts
|
// def_unique_len - sets default unique length for texts
|
||||||
// fields - See TableField
|
// fields - See TableField
|
||||||
// sql_from_v - Function which maps type indices to sql type names
|
// sql_from_v - Function which maps type indices to sql type names
|
||||||
// alternative - Needed for msdb
|
// alternative - Needed for msdb
|
||||||
pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int, fields []TableField, sql_from_v fn (int) !string,
|
pub fn orm_table_gen(sql_dialect SQLDialect, table Table, q string, defaults bool, def_unique_len int, fields []TableField, sql_from_v fn (int) !string,
|
||||||
alternative bool) !string {
|
alternative bool) !string {
|
||||||
mut str := 'CREATE TABLE IF NOT EXISTS ${q}${table}${q} ('
|
mut str := 'CREATE TABLE IF NOT EXISTS ${q}${table.name}${q} ('
|
||||||
|
|
||||||
if alternative {
|
if alternative {
|
||||||
str = 'IF NOT EXISTS (SELECT * FROM sysobjects WHERE name=${q}${table}${q} and xtype=${q}U${q}) CREATE TABLE ${q}${table}${q} ('
|
str = 'IF NOT EXISTS (SELECT * FROM sysobjects WHERE name=${q}${table.name}${q} and xtype=${q}U${q}) CREATE TABLE ${q}${table.name}${q} ('
|
||||||
}
|
}
|
||||||
|
|
||||||
mut fs := []string{}
|
mut fs := []string{}
|
||||||
@ -461,6 +469,19 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int,
|
|||||||
mut unique := map[string][]string{}
|
mut unique := map[string][]string{}
|
||||||
mut primary := ''
|
mut primary := ''
|
||||||
mut primary_typ := 0
|
mut primary_typ := 0
|
||||||
|
mut table_comment := ''
|
||||||
|
mut field_comments := map[string]string{}
|
||||||
|
|
||||||
|
for attr in table.attrs {
|
||||||
|
match attr.name {
|
||||||
|
'comment' {
|
||||||
|
if attr.arg != '' && attr.kind == .string {
|
||||||
|
table_comment = attr.arg.replace('"', '\\"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for field in fields {
|
for field in fields {
|
||||||
if field.is_arr {
|
if field.is_arr {
|
||||||
@ -473,6 +494,7 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int,
|
|||||||
mut unique_len := 0
|
mut unique_len := 0
|
||||||
mut references_table := ''
|
mut references_table := ''
|
||||||
mut references_field := ''
|
mut references_field := ''
|
||||||
|
mut field_comment := ''
|
||||||
mut field_name := sql_field_name(field)
|
mut field_name := sql_field_name(field)
|
||||||
mut col_typ := sql_from_v(sql_field_type(field)) or {
|
mut col_typ := sql_from_v(sql_field_type(field)) or {
|
||||||
field_name = '${field_name}_id'
|
field_name = '${field_name}_id'
|
||||||
@ -540,6 +562,12 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
'comment' {
|
||||||
|
if attr.arg != '' && attr.kind == .string {
|
||||||
|
field_comment = attr.arg.replace("'", "\\'")
|
||||||
|
field_comments[field_name] = field_comment
|
||||||
|
}
|
||||||
|
}
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -548,12 +576,15 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int,
|
|||||||
}
|
}
|
||||||
mut stmt := ''
|
mut stmt := ''
|
||||||
if col_typ == '' {
|
if col_typ == '' {
|
||||||
return error('Unknown type (${field.typ}) for field ${field.name} in struct ${table}')
|
return error('Unknown type (${field.typ}) for field ${field.name} in struct ${table.name}')
|
||||||
}
|
}
|
||||||
stmt = '${q}${field_name}${q} ${col_typ}'
|
stmt = '${q}${field_name}${q} ${col_typ}'
|
||||||
if defaults && default_val != '' {
|
if defaults && default_val != '' {
|
||||||
stmt += ' DEFAULT ${default_val}'
|
stmt += ' DEFAULT ${default_val}'
|
||||||
}
|
}
|
||||||
|
if sql_dialect == .mysql && field_comment != '' {
|
||||||
|
stmt += " COMMENT '${field_comment}'"
|
||||||
|
}
|
||||||
if !nullable {
|
if !nullable {
|
||||||
stmt += ' NOT NULL'
|
stmt += ' NOT NULL'
|
||||||
}
|
}
|
||||||
@ -591,9 +622,22 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int,
|
|||||||
|
|
||||||
fs << unique_fields
|
fs << unique_fields
|
||||||
str += fs.join(', ')
|
str += fs.join(', ')
|
||||||
str += ');'
|
str += ')'
|
||||||
|
if sql_dialect == .mysql && table_comment != '' {
|
||||||
|
str += " COMMENT = '${table_comment}'"
|
||||||
|
}
|
||||||
|
str += ';'
|
||||||
|
|
||||||
|
if sql_dialect == .pg {
|
||||||
|
if table_comment != '' {
|
||||||
|
str += "\nCOMMENT ON TABLE \"${table.name}\" IS '${table_comment}';"
|
||||||
|
}
|
||||||
|
for f, c in field_comments {
|
||||||
|
str += "\nCOMMENT ON COLUMN \"${table.name}\".\"${f}\" IS '${c}';"
|
||||||
|
}
|
||||||
|
}
|
||||||
$if trace_orm_create ? {
|
$if trace_orm_create ? {
|
||||||
eprintln('> orm_create table: ${table} | query: ${str}')
|
eprintln('> orm_create table: ${table.name} | query: ${str}')
|
||||||
}
|
}
|
||||||
$if trace_orm ? {
|
$if trace_orm ? {
|
||||||
eprintln('> orm: ${str}')
|
eprintln('> orm: ${str}')
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
import orm
|
import orm
|
||||||
|
|
||||||
fn test_orm_stmt_gen_update() {
|
fn test_orm_stmt_gen_update() {
|
||||||
query_and, _ := orm.orm_stmt_gen(.default, 'Test', "'", .update, true, '?', 0, orm.QueryData{
|
table := orm.Table{
|
||||||
|
name: 'Test'
|
||||||
|
}
|
||||||
|
query_and, _ := orm.orm_stmt_gen(.default, table, "'", .update, true, '?', 0, orm.QueryData{
|
||||||
fields: ['test', 'a']
|
fields: ['test', 'a']
|
||||||
data: []
|
data: []
|
||||||
types: []
|
types: []
|
||||||
@ -17,7 +20,7 @@ fn test_orm_stmt_gen_update() {
|
|||||||
})
|
})
|
||||||
assert query_and == "UPDATE 'Test' SET 'test' = ?0, 'a' = ?1 WHERE 'id' >= ?2 AND 'name' = ?3;"
|
assert query_and == "UPDATE 'Test' SET 'test' = ?0, 'a' = ?1 WHERE 'id' >= ?2 AND 'name' = ?3;"
|
||||||
|
|
||||||
query_or, _ := orm.orm_stmt_gen(.default, 'Test', "'", .update, true, '?', 0, orm.QueryData{
|
query_or, _ := orm.orm_stmt_gen(.default, table, "'", .update, true, '?', 0, orm.QueryData{
|
||||||
fields: ['test', 'a']
|
fields: ['test', 'a']
|
||||||
data: []
|
data: []
|
||||||
types: []
|
types: []
|
||||||
@ -33,7 +36,10 @@ fn test_orm_stmt_gen_update() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn test_orm_stmt_gen_insert() {
|
fn test_orm_stmt_gen_insert() {
|
||||||
query, _ := orm.orm_stmt_gen(.default, 'Test', "'", .insert, true, '?', 0, orm.QueryData{
|
table := orm.Table{
|
||||||
|
name: 'Test'
|
||||||
|
}
|
||||||
|
query, _ := orm.orm_stmt_gen(.default, table, "'", .insert, true, '?', 0, orm.QueryData{
|
||||||
fields: ['test', 'a']
|
fields: ['test', 'a']
|
||||||
data: []
|
data: []
|
||||||
types: []
|
types: []
|
||||||
@ -43,7 +49,10 @@ fn test_orm_stmt_gen_insert() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn test_orm_stmt_gen_delete() {
|
fn test_orm_stmt_gen_delete() {
|
||||||
query_and, _ := orm.orm_stmt_gen(.default, 'Test', "'", .delete, true, '?', 0, orm.QueryData{
|
table := orm.Table{
|
||||||
|
name: 'Test'
|
||||||
|
}
|
||||||
|
query_and, _ := orm.orm_stmt_gen(.default, table, "'", .delete, true, '?', 0, orm.QueryData{
|
||||||
fields: ['test', 'a']
|
fields: ['test', 'a']
|
||||||
data: []
|
data: []
|
||||||
types: []
|
types: []
|
||||||
@ -57,7 +66,7 @@ fn test_orm_stmt_gen_delete() {
|
|||||||
})
|
})
|
||||||
assert query_and == "DELETE FROM 'Test' WHERE 'id' >= ?0 AND 'name' = ?1;"
|
assert query_and == "DELETE FROM 'Test' WHERE 'id' >= ?0 AND 'name' = ?1;"
|
||||||
|
|
||||||
query_or, _ := orm.orm_stmt_gen(.default, 'Test', "'", .delete, true, '?', 0, orm.QueryData{
|
query_or, _ := orm.orm_stmt_gen(.default, table, "'", .delete, true, '?', 0, orm.QueryData{
|
||||||
fields: ['test', 'a']
|
fields: ['test', 'a']
|
||||||
data: []
|
data: []
|
||||||
types: []
|
types: []
|
||||||
@ -78,7 +87,9 @@ fn get_select_fields() []string {
|
|||||||
|
|
||||||
fn test_orm_select_gen() {
|
fn test_orm_select_gen() {
|
||||||
query := orm.orm_select_gen(orm.SelectConfig{
|
query := orm.orm_select_gen(orm.SelectConfig{
|
||||||
table: 'test_table'
|
table: orm.Table{
|
||||||
|
name: 'test_table'
|
||||||
|
}
|
||||||
fields: get_select_fields()
|
fields: get_select_fields()
|
||||||
}, "'", true, '?', 0, orm.QueryData{})
|
}, "'", true, '?', 0, orm.QueryData{})
|
||||||
|
|
||||||
@ -87,7 +98,9 @@ fn test_orm_select_gen() {
|
|||||||
|
|
||||||
fn test_orm_select_gen_with_limit() {
|
fn test_orm_select_gen_with_limit() {
|
||||||
query := orm.orm_select_gen(orm.SelectConfig{
|
query := orm.orm_select_gen(orm.SelectConfig{
|
||||||
table: 'test_table'
|
table: orm.Table{
|
||||||
|
name: 'test_table'
|
||||||
|
}
|
||||||
fields: get_select_fields()
|
fields: get_select_fields()
|
||||||
has_limit: true
|
has_limit: true
|
||||||
}, "'", true, '?', 0, orm.QueryData{})
|
}, "'", true, '?', 0, orm.QueryData{})
|
||||||
@ -97,7 +110,9 @@ fn test_orm_select_gen_with_limit() {
|
|||||||
|
|
||||||
fn test_orm_select_gen_with_where() {
|
fn test_orm_select_gen_with_where() {
|
||||||
query := orm.orm_select_gen(orm.SelectConfig{
|
query := orm.orm_select_gen(orm.SelectConfig{
|
||||||
table: 'test_table'
|
table: orm.Table{
|
||||||
|
name: 'test_table'
|
||||||
|
}
|
||||||
fields: get_select_fields()
|
fields: get_select_fields()
|
||||||
has_where: true
|
has_where: true
|
||||||
}, "'", true, '?', 0, orm.QueryData{
|
}, "'", true, '?', 0, orm.QueryData{
|
||||||
@ -111,7 +126,9 @@ fn test_orm_select_gen_with_where() {
|
|||||||
|
|
||||||
fn test_orm_select_gen_with_order() {
|
fn test_orm_select_gen_with_order() {
|
||||||
query := orm.orm_select_gen(orm.SelectConfig{
|
query := orm.orm_select_gen(orm.SelectConfig{
|
||||||
table: 'test_table'
|
table: orm.Table{
|
||||||
|
name: 'test_table'
|
||||||
|
}
|
||||||
fields: get_select_fields()
|
fields: get_select_fields()
|
||||||
has_order: true
|
has_order: true
|
||||||
order_type: .desc
|
order_type: .desc
|
||||||
@ -122,7 +139,9 @@ fn test_orm_select_gen_with_order() {
|
|||||||
|
|
||||||
fn test_orm_select_gen_with_offset() {
|
fn test_orm_select_gen_with_offset() {
|
||||||
query := orm.orm_select_gen(orm.SelectConfig{
|
query := orm.orm_select_gen(orm.SelectConfig{
|
||||||
table: 'test_table'
|
table: orm.Table{
|
||||||
|
name: 'test_table'
|
||||||
|
}
|
||||||
fields: get_select_fields()
|
fields: get_select_fields()
|
||||||
has_offset: true
|
has_offset: true
|
||||||
}, "'", true, '?', 0, orm.QueryData{})
|
}, "'", true, '?', 0, orm.QueryData{})
|
||||||
@ -132,7 +151,9 @@ fn test_orm_select_gen_with_offset() {
|
|||||||
|
|
||||||
fn test_orm_select_gen_with_all() {
|
fn test_orm_select_gen_with_all() {
|
||||||
query := orm.orm_select_gen(orm.SelectConfig{
|
query := orm.orm_select_gen(orm.SelectConfig{
|
||||||
table: 'test_table'
|
table: orm.Table{
|
||||||
|
name: 'test_table'
|
||||||
|
}
|
||||||
fields: get_select_fields()
|
fields: get_select_fields()
|
||||||
has_limit: true
|
has_limit: true
|
||||||
has_order: true
|
has_order: true
|
||||||
@ -149,7 +170,10 @@ fn test_orm_select_gen_with_all() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn test_orm_table_gen() {
|
fn test_orm_table_gen() {
|
||||||
query := orm.orm_table_gen('test_table', "'", true, 0, [
|
table := orm.Table{
|
||||||
|
name: 'test_table'
|
||||||
|
}
|
||||||
|
query := orm.orm_table_gen(.default, table, "'", true, 0, [
|
||||||
orm.TableField{
|
orm.TableField{
|
||||||
name: 'id'
|
name: 'id'
|
||||||
typ: typeof[int]().idx
|
typ: typeof[int]().idx
|
||||||
@ -181,7 +205,7 @@ fn test_orm_table_gen() {
|
|||||||
], sql_type_from_v, false) or { panic(err) }
|
], sql_type_from_v, false) or { panic(err) }
|
||||||
assert query == "CREATE TABLE IF NOT EXISTS 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT, 'abc' INT64 DEFAULT 6754, PRIMARY KEY('id'));"
|
assert query == "CREATE TABLE IF NOT EXISTS 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT, 'abc' INT64 DEFAULT 6754, PRIMARY KEY('id'));"
|
||||||
|
|
||||||
alt_query := orm.orm_table_gen('test_table', "'", true, 0, [
|
alt_query := orm.orm_table_gen(.default, table, "'", true, 0, [
|
||||||
orm.TableField{
|
orm.TableField{
|
||||||
name: 'id'
|
name: 'id'
|
||||||
typ: typeof[int]().idx
|
typ: typeof[int]().idx
|
||||||
@ -213,7 +237,7 @@ fn test_orm_table_gen() {
|
|||||||
], sql_type_from_v, true) or { panic(err) }
|
], sql_type_from_v, true) or { panic(err) }
|
||||||
assert alt_query == "IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='test_table' and xtype='U') CREATE TABLE 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT, 'abc' INT64 DEFAULT 6754, PRIMARY KEY('id'));"
|
assert alt_query == "IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='test_table' and xtype='U') CREATE TABLE 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT, 'abc' INT64 DEFAULT 6754, PRIMARY KEY('id'));"
|
||||||
|
|
||||||
unique_query := orm.orm_table_gen('test_table', "'", true, 0, [
|
unique_query := orm.orm_table_gen(.default, table, "'", true, 0, [
|
||||||
orm.TableField{
|
orm.TableField{
|
||||||
name: 'id'
|
name: 'id'
|
||||||
typ: typeof[int]().idx
|
typ: typeof[int]().idx
|
||||||
@ -248,7 +272,7 @@ fn test_orm_table_gen() {
|
|||||||
], sql_type_from_v, false) or { panic(err) }
|
], sql_type_from_v, false) or { panic(err) }
|
||||||
assert unique_query == "CREATE TABLE IF NOT EXISTS 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT NOT NULL, 'abc' INT64 DEFAULT 6754 NOT NULL, PRIMARY KEY('id'), UNIQUE('test'));"
|
assert unique_query == "CREATE TABLE IF NOT EXISTS 'test_table' ('id' SERIAL DEFAULT 10, 'test' TEXT NOT NULL, 'abc' INT64 DEFAULT 6754 NOT NULL, PRIMARY KEY('id'), UNIQUE('test'));"
|
||||||
|
|
||||||
mult_unique_query := orm.orm_table_gen('test_table', "'", true, 0, [
|
mult_unique_query := orm.orm_table_gen(.default, table, "'", true, 0, [
|
||||||
orm.TableField{
|
orm.TableField{
|
||||||
name: 'id'
|
name: 'id'
|
||||||
typ: typeof[int]().idx
|
typ: typeof[int]().idx
|
||||||
|
@ -25,7 +25,7 @@ pub fn new_query[T](conn Connection) &QueryBuilder[T] {
|
|||||||
valid_sql_field_names: meta.map(sql_field_name(it))
|
valid_sql_field_names: meta.map(sql_field_name(it))
|
||||||
conn: conn
|
conn: conn
|
||||||
config: SelectConfig{
|
config: SelectConfig{
|
||||||
table: table_name_from_struct[T]()
|
table: table_from_struct[T]()
|
||||||
}
|
}
|
||||||
data: QueryData{}
|
data: QueryData{}
|
||||||
where: QueryData{}
|
where: QueryData{}
|
||||||
@ -35,9 +35,9 @@ pub fn new_query[T](conn Connection) &QueryBuilder[T] {
|
|||||||
// reset reset a query object, but keep the connection and table name
|
// reset reset a query object, but keep the connection and table name
|
||||||
pub fn (qb_ &QueryBuilder[T]) reset() &QueryBuilder[T] {
|
pub fn (qb_ &QueryBuilder[T]) reset() &QueryBuilder[T] {
|
||||||
mut qb := unsafe { qb_ }
|
mut qb := unsafe { qb_ }
|
||||||
old_table_name := qb.config.table
|
old_table := qb.config.table
|
||||||
qb.config = SelectConfig{
|
qb.config = SelectConfig{
|
||||||
table: old_table_name
|
table: old_table
|
||||||
}
|
}
|
||||||
qb.data = QueryData{}
|
qb.data = QueryData{}
|
||||||
qb.where = QueryData{}
|
qb.where = QueryData{}
|
||||||
@ -366,15 +366,20 @@ pub fn (qb_ &QueryBuilder[T]) set(assign string, values ...Primitive) !&QueryBui
|
|||||||
return qb
|
return qb
|
||||||
}
|
}
|
||||||
|
|
||||||
// table_name_from_struct get table name from struct
|
// table_from_struct get table from struct
|
||||||
fn table_name_from_struct[T]() string {
|
fn table_from_struct[T]() Table {
|
||||||
mut table_name := T.name
|
mut table_name := T.name
|
||||||
|
mut attrs := []VAttribute{}
|
||||||
$for a in T.attributes {
|
$for a in T.attributes {
|
||||||
$if a.name == 'table' && a.has_arg {
|
$if a.name == 'table' && a.has_arg {
|
||||||
table_name = a.arg
|
table_name = a.arg
|
||||||
}
|
}
|
||||||
|
attrs << a
|
||||||
|
}
|
||||||
|
return Table{
|
||||||
|
name: table_name
|
||||||
|
attrs: attrs
|
||||||
}
|
}
|
||||||
return table_name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct_meta return a struct's fields info
|
// struct_meta return a struct's fields info
|
||||||
|
@ -25,14 +25,14 @@ fn (mut db Database) select(config orm.SelectConfig, data orm.QueryData, where o
|
|||||||
}
|
}
|
||||||
|
|
||||||
// insert is used internally by V's ORM for processing `INSERT` queries
|
// insert is used internally by V's ORM for processing `INSERT` queries
|
||||||
fn (mut db Database) insert(table string, data orm.QueryData) ! {
|
fn (mut db Database) insert(table orm.Table, data orm.QueryData) ! {
|
||||||
query, _ := orm.orm_stmt_gen(.sqlite, table, '', .insert, false, '?', 1, data, orm.QueryData{})
|
query, _ := orm.orm_stmt_gen(.sqlite, table, '', .insert, false, '?', 1, data, orm.QueryData{})
|
||||||
|
|
||||||
db.query(query)!
|
db.query(query)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// update is used internally by V's ORM for processing `UPDATE` queries
|
// update is used internally by V's ORM for processing `UPDATE` queries
|
||||||
fn (mut db Database) update(table string, data orm.QueryData, where orm.QueryData) ! {
|
fn (mut db Database) update(table orm.Table, data orm.QueryData, where orm.QueryData) ! {
|
||||||
mut query, _ := orm.orm_stmt_gen(.sqlite, table, '', .update, true, ':', 1, data,
|
mut query, _ := orm.orm_stmt_gen(.sqlite, table, '', .update, true, ':', 1, data,
|
||||||
where)
|
where)
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ fn (mut db Database) update(table string, data orm.QueryData, where orm.QueryDat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// delete is used internally by V's ORM for processing `DELETE ` queries
|
// delete is used internally by V's ORM for processing `DELETE ` queries
|
||||||
fn (mut db Database) delete(table string, where orm.QueryData) ! {
|
fn (mut db Database) delete(table orm.Table, where orm.QueryData) ! {
|
||||||
query, converted := orm.orm_stmt_gen(.sqlite, table, '', .delete, true, ':', 1, orm.QueryData{},
|
query, converted := orm.orm_stmt_gen(.sqlite, table, '', .delete, true, ':', 1, orm.QueryData{},
|
||||||
where)
|
where)
|
||||||
|
|
||||||
@ -66,16 +66,15 @@ fn sqlite_type_from_v(typ int) !string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create is used internally by V's ORM for processing table creation queries (DDL)
|
// create is used internally by V's ORM for processing table creation queries (DDL)
|
||||||
fn (mut db Database) create(table string, fields []orm.TableField) ! {
|
fn (mut db Database) create(table orm.Table, fields []orm.TableField) ! {
|
||||||
mut query := orm.orm_table_gen(table, '', true, 0, fields, sqlite_type_from_v, false) or {
|
mut query := orm.orm_table_gen(.sqlite, table, '', true, 0, fields, sqlite_type_from_v,
|
||||||
return err
|
false) or { return err }
|
||||||
}
|
|
||||||
db.query(query)!
|
db.query(query)!
|
||||||
}
|
}
|
||||||
|
|
||||||
// drop is used internally by V's ORM for processing table destroying queries (DDL)
|
// drop is used internally by V's ORM for processing table destroying queries (DDL)
|
||||||
fn (mut db Database) drop(table string) ! {
|
fn (mut db Database) drop(table orm.Table) ! {
|
||||||
query := 'DROP TABLE ${table};'
|
query := 'DROP TABLE ${table.name};'
|
||||||
$if trace_orm ? {
|
$if trace_orm ? {
|
||||||
eprintln('> vsql drop: ${query}')
|
eprintln('> vsql drop: ${query}')
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ fn (db MockDB) select(config orm.SelectConfig, data orm.QueryData, where orm.Que
|
|||||||
return db.db.select(config, data, where)
|
return db.db.select(config, data, where)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (db MockDB) insert(table string, data orm.QueryData) ! {
|
fn (db MockDB) insert(table orm.Table, data orm.QueryData) ! {
|
||||||
mut st := db.st
|
mut st := db.st
|
||||||
last, qdata := orm.orm_stmt_gen(.sqlite, table, '`', .insert, false, '?', 1, data,
|
last, qdata := orm.orm_stmt_gen(.sqlite, table, '`', .insert, false, '?', 1, data,
|
||||||
orm.QueryData{})
|
orm.QueryData{})
|
||||||
@ -41,7 +41,7 @@ fn (db MockDB) insert(table string, data orm.QueryData) ! {
|
|||||||
return db.db.insert(table, data)
|
return db.db.insert(table, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (db MockDB) update(table string, data orm.QueryData, where orm.QueryData) ! {
|
fn (db MockDB) update(table orm.Table, data orm.QueryData, where orm.QueryData) ! {
|
||||||
mut st := db.st
|
mut st := db.st
|
||||||
st.last, _ = orm.orm_stmt_gen(.sqlite, table, '`', .update, false, '?', 1, data, where)
|
st.last, _ = orm.orm_stmt_gen(.sqlite, table, '`', .update, false, '?', 1, data, where)
|
||||||
st.data = data.data
|
st.data = data.data
|
||||||
@ -49,7 +49,7 @@ fn (db MockDB) update(table string, data orm.QueryData, where orm.QueryData) ! {
|
|||||||
return db.db.update(table, data, where)
|
return db.db.update(table, data, where)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (db MockDB) delete(table string, where orm.QueryData) ! {
|
fn (db MockDB) delete(table orm.Table, where orm.QueryData) ! {
|
||||||
mut st := db.st
|
mut st := db.st
|
||||||
st.last, _ = orm.orm_stmt_gen(.sqlite, table, '`', .delete, false, '?', 1, orm.QueryData{},
|
st.last, _ = orm.orm_stmt_gen(.sqlite, table, '`', .delete, false, '?', 1, orm.QueryData{},
|
||||||
where)
|
where)
|
||||||
@ -82,13 +82,14 @@ fn mock_type_from_v(typ int) !string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (db MockDB) create(table string, fields []orm.TableField) ! {
|
fn (db MockDB) create(table orm.Table, fields []orm.TableField) ! {
|
||||||
mut st := db.st
|
mut st := db.st
|
||||||
st.last = orm.orm_table_gen(table, '`', true, 0, fields, mock_type_from_v, false)!
|
st.last = orm.orm_table_gen(.sqlite, table, '`', true, 0, fields, mock_type_from_v,
|
||||||
|
false)!
|
||||||
return db.db.create(table, fields)
|
return db.db.create(table, fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (db MockDB) drop(table string) ! {
|
fn (db MockDB) drop(table orm.Table) ! {
|
||||||
return db.db.drop(table)
|
return db.db.drop(table)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ fn (mut g Gen) sql_insert_expr(node ast.SqlExpr) {
|
|||||||
connection_var_name := g.new_tmp_var()
|
connection_var_name := g.new_tmp_var()
|
||||||
g.write_orm_connection_init(connection_var_name, &node.db_expr)
|
g.write_orm_connection_init(connection_var_name, &node.db_expr)
|
||||||
table_name := g.get_table_name_by_struct_type(node.table_expr.typ)
|
table_name := g.get_table_name_by_struct_type(node.table_expr.typ)
|
||||||
|
table_attrs := g.get_table_attrs_by_struct_type(node.table_expr.typ)
|
||||||
result_var_name := g.new_tmp_var()
|
result_var_name := g.new_tmp_var()
|
||||||
g.sql_table_name = g.table.sym(node.table_expr.typ).name
|
g.sql_table_name = g.table.sym(node.table_expr.typ).name
|
||||||
|
|
||||||
@ -55,10 +56,11 @@ fn (mut g Gen) sql_insert_expr(node ast.SqlExpr) {
|
|||||||
hack_stmt_line := ast.SqlStmtLine{
|
hack_stmt_line := ast.SqlStmtLine{
|
||||||
object_var: node.inserted_var
|
object_var: node.inserted_var
|
||||||
fields: node.fields
|
fields: node.fields
|
||||||
|
table_expr: node.table_expr
|
||||||
// sub_structs: node.sub_structs
|
// sub_structs: node.sub_structs
|
||||||
}
|
}
|
||||||
g.write_orm_insert(hack_stmt_line, table_name, connection_var_name, result_var_name,
|
g.write_orm_insert(hack_stmt_line, table_name, connection_var_name, result_var_name,
|
||||||
node.or_expr)
|
node.or_expr, table_attrs)
|
||||||
|
|
||||||
g.write2(left, 'orm__Connection_name_table[${connection_var_name}._typ]._method_last_id(${connection_var_name}._object)')
|
g.write2(left, 'orm__Connection_name_table[${connection_var_name}._typ]._method_last_id(${connection_var_name}._object)')
|
||||||
}
|
}
|
||||||
@ -93,6 +95,7 @@ fn (mut g Gen) sql_stmt_line(stmt_line ast.SqlStmtLine, connection_var_name stri
|
|||||||
g.sql_last_stmt_out_len = g.out.len
|
g.sql_last_stmt_out_len = g.out.len
|
||||||
mut node := stmt_line
|
mut node := stmt_line
|
||||||
table_name := g.get_table_name_by_struct_type(node.table_expr.typ)
|
table_name := g.get_table_name_by_struct_type(node.table_expr.typ)
|
||||||
|
table_attrs := g.get_table_attrs_by_struct_type(node.table_expr.typ)
|
||||||
result_var_name := g.new_tmp_var()
|
result_var_name := g.new_tmp_var()
|
||||||
g.sql_table_name = g.table.sym(node.table_expr.typ).name
|
g.sql_table_name = g.table.sym(node.table_expr.typ).name
|
||||||
|
|
||||||
@ -101,15 +104,18 @@ fn (mut g Gen) sql_stmt_line(stmt_line ast.SqlStmtLine, connection_var_name stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
if node.kind == .create {
|
if node.kind == .create {
|
||||||
g.write_orm_create_table(node, table_name, connection_var_name, result_var_name)
|
g.write_orm_create_table(node, table_name, connection_var_name, result_var_name,
|
||||||
|
table_attrs)
|
||||||
} else if node.kind == .drop {
|
} else if node.kind == .drop {
|
||||||
g.write_orm_drop_table(table_name, connection_var_name, result_var_name)
|
g.write_orm_drop_table(node, table_name, connection_var_name, result_var_name,
|
||||||
|
table_attrs)
|
||||||
} else if node.kind == .insert {
|
} else if node.kind == .insert {
|
||||||
g.write_orm_insert(node, table_name, connection_var_name, result_var_name, or_expr)
|
g.write_orm_insert(node, table_name, connection_var_name, result_var_name, or_expr,
|
||||||
|
table_attrs)
|
||||||
} else if node.kind == .update {
|
} else if node.kind == .update {
|
||||||
g.write_orm_update(node, table_name, connection_var_name, result_var_name)
|
g.write_orm_update(node, table_name, connection_var_name, result_var_name, table_attrs)
|
||||||
} else if node.kind == .delete {
|
} else if node.kind == .delete {
|
||||||
g.write_orm_delete(node, table_name, connection_var_name, result_var_name)
|
g.write_orm_delete(node, table_name, connection_var_name, result_var_name, table_attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
g.or_block(result_var_name, or_expr, ast.int_type.set_flag(.result))
|
g.or_block(result_var_name, or_expr, ast.int_type.set_flag(.result))
|
||||||
@ -138,14 +144,54 @@ fn (mut g Gen) write_orm_connection_init(connection_var_name string, db_expr &as
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// write_orm_table_struct writes C code for the orm.Table struct
|
||||||
|
fn (mut g Gen) write_orm_table_struct(typ ast.Type) {
|
||||||
|
table_name := g.get_table_name_by_struct_type(typ)
|
||||||
|
table_attrs := g.get_table_attrs_by_struct_type(typ)
|
||||||
|
|
||||||
|
g.writeln('((orm__Table){')
|
||||||
|
g.indent++
|
||||||
|
g.writeln('.name = _S("${table_name}"),')
|
||||||
|
g.writeln('.attrs = new_array_from_c_array(${table_attrs.len}, ${table_attrs.len}, sizeof(VAttribute),')
|
||||||
|
g.indent++
|
||||||
|
|
||||||
|
if table_attrs.len > 0 {
|
||||||
|
g.write('_MOV((VAttribute[${table_attrs.len}]){')
|
||||||
|
g.indent++
|
||||||
|
for attr in table_attrs {
|
||||||
|
g.write('(VAttribute){')
|
||||||
|
g.indent++
|
||||||
|
name1 := util.smart_quote(attr.name, false)
|
||||||
|
name := cescape_nonascii(name1)
|
||||||
|
g.write(' .name = _S("${name}"),')
|
||||||
|
g.write(' .has_arg = ${attr.has_arg},')
|
||||||
|
arg1 := util.smart_quote(attr.arg, false)
|
||||||
|
arg := cescape_nonascii(arg1)
|
||||||
|
g.write(' .arg = _S("${arg}"),')
|
||||||
|
g.write(' .kind = ${int(attr.kind)},')
|
||||||
|
g.indent--
|
||||||
|
g.write('},')
|
||||||
|
}
|
||||||
|
g.indent--
|
||||||
|
g.writeln('})')
|
||||||
|
} else {
|
||||||
|
g.writeln('NULL // No attrs')
|
||||||
|
}
|
||||||
|
g.indent--
|
||||||
|
g.writeln(')')
|
||||||
|
g.indent--
|
||||||
|
g.write('})')
|
||||||
|
}
|
||||||
|
|
||||||
// write_orm_create_table writes C code that calls ORM functions for creating tables.
|
// write_orm_create_table writes C code that calls ORM functions for creating tables.
|
||||||
fn (mut g Gen) write_orm_create_table(node ast.SqlStmtLine, table_name string, connection_var_name string,
|
fn (mut g Gen) write_orm_create_table(node ast.SqlStmtLine, table_name string, connection_var_name string,
|
||||||
result_var_name string) {
|
result_var_name string, table_attrs []ast.Attr) {
|
||||||
g.writeln('// sql { create table `${table_name}` }')
|
g.writeln('// sql { create table `${table_name}` }')
|
||||||
g.writeln('${result_name}_void ${result_var_name} = orm__Connection_name_table[${connection_var_name}._typ]._method_create(')
|
g.writeln('${result_name}_void ${result_var_name} = orm__Connection_name_table[${connection_var_name}._typ]._method_create(')
|
||||||
g.indent++
|
g.indent++
|
||||||
g.writeln('${connection_var_name}._object, // Connection object')
|
g.writeln('${connection_var_name}._object, // Connection object')
|
||||||
g.writeln('_S("${table_name}"),')
|
g.write_orm_table_struct(node.table_expr.typ)
|
||||||
|
g.writeln(',')
|
||||||
g.writeln('new_array_from_c_array(${node.fields.len}, ${node.fields.len}, sizeof(orm__TableField),')
|
g.writeln('new_array_from_c_array(${node.fields.len}, ${node.fields.len}, sizeof(orm__TableField),')
|
||||||
g.indent++
|
g.indent++
|
||||||
|
|
||||||
@ -213,19 +259,19 @@ fn (mut g Gen) write_orm_create_table(node ast.SqlStmtLine, table_name string, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write_orm_drop_table writes C code that calls ORM functions for dropping tables.
|
// write_orm_drop_table writes C code that calls ORM functions for dropping tables.
|
||||||
fn (mut g Gen) write_orm_drop_table(table_name string, connection_var_name string, result_var_name string) {
|
fn (mut g Gen) write_orm_drop_table(node ast.SqlStmtLine, table_name string, connection_var_name string, result_var_name string, table_attrs []ast.Attr) {
|
||||||
g.writeln('// sql { drop table `${table_name}` }')
|
g.writeln('// sql { drop table `${table_name}` }')
|
||||||
g.writeln('${result_name}_void ${result_var_name} = orm__Connection_name_table[${connection_var_name}._typ]._method_drop(')
|
g.writeln('${result_name}_void ${result_var_name} = orm__Connection_name_table[${connection_var_name}._typ]._method_drop(')
|
||||||
g.indent++
|
g.indent++
|
||||||
g.writeln('${connection_var_name}._object, // Connection object')
|
g.writeln('${connection_var_name}._object, // Connection object')
|
||||||
g.writeln('_S("${table_name}")')
|
g.write_orm_table_struct(node.table_expr.typ)
|
||||||
g.indent--
|
g.indent--
|
||||||
g.writeln(');')
|
g.writeln(');')
|
||||||
}
|
}
|
||||||
|
|
||||||
// write_orm_insert writes C code that calls ORM functions for inserting structs into a table.
|
// write_orm_insert writes C code that calls ORM functions for inserting structs into a table.
|
||||||
fn (mut g Gen) write_orm_insert(node &ast.SqlStmtLine, table_name string, connection_var_name string, result_var_name string,
|
fn (mut g Gen) write_orm_insert(node &ast.SqlStmtLine, table_name string, connection_var_name string, result_var_name string,
|
||||||
or_expr &ast.OrExpr) {
|
or_expr &ast.OrExpr, table_attrs []ast.Attr) {
|
||||||
last_ids_variable_name := g.new_tmp_var()
|
last_ids_variable_name := g.new_tmp_var()
|
||||||
|
|
||||||
g.writeln('Array_orm__Primitive ${last_ids_variable_name} = __new_array_with_default_noscan(0, 0, sizeof(orm__Primitive), 0);')
|
g.writeln('Array_orm__Primitive ${last_ids_variable_name} = __new_array_with_default_noscan(0, 0, sizeof(orm__Primitive), 0);')
|
||||||
@ -234,12 +280,13 @@ fn (mut g Gen) write_orm_insert(node &ast.SqlStmtLine, table_name string, connec
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write_orm_update writes C code that calls ORM functions for updating rows.
|
// write_orm_update writes C code that calls ORM functions for updating rows.
|
||||||
fn (mut g Gen) write_orm_update(node &ast.SqlStmtLine, table_name string, connection_var_name string, result_var_name string) {
|
fn (mut g Gen) write_orm_update(node &ast.SqlStmtLine, table_name string, connection_var_name string, result_var_name string, table_attrs []ast.Attr) {
|
||||||
g.writeln('// sql { update `${table_name}` }')
|
g.writeln('// sql { update `${table_name}` }')
|
||||||
g.writeln('${result_name}_void ${result_var_name} = orm__Connection_name_table[${connection_var_name}._typ]._method_update(')
|
g.writeln('${result_name}_void ${result_var_name} = orm__Connection_name_table[${connection_var_name}._typ]._method_update(')
|
||||||
g.indent++
|
g.indent++
|
||||||
g.writeln('${connection_var_name}._object, // Connection object')
|
g.writeln('${connection_var_name}._object, // Connection object')
|
||||||
g.writeln('_S("${table_name}"),')
|
g.write_orm_table_struct(node.table_expr.typ)
|
||||||
|
g.writeln(',')
|
||||||
g.writeln('(orm__QueryData){')
|
g.writeln('(orm__QueryData){')
|
||||||
g.indent++
|
g.indent++
|
||||||
g.writeln('.kinds = __new_array_with_default_noscan(0, 0, sizeof(orm__OperationKind), 0),')
|
g.writeln('.kinds = __new_array_with_default_noscan(0, 0, sizeof(orm__OperationKind), 0),')
|
||||||
@ -285,12 +332,13 @@ fn (mut g Gen) write_orm_update(node &ast.SqlStmtLine, table_name string, connec
|
|||||||
}
|
}
|
||||||
|
|
||||||
// write_orm_delete writes C code that calls ORM functions for deleting rows.
|
// write_orm_delete writes C code that calls ORM functions for deleting rows.
|
||||||
fn (mut g Gen) write_orm_delete(node &ast.SqlStmtLine, table_name string, connection_var_name string, result_var_name string) {
|
fn (mut g Gen) write_orm_delete(node &ast.SqlStmtLine, table_name string, connection_var_name string, result_var_name string, table_attrs []ast.Attr) {
|
||||||
g.writeln('// sql { delete from `${table_name}` }')
|
g.writeln('// sql { delete from `${table_name}` }')
|
||||||
g.writeln('${result_name}_void ${result_var_name} = orm__Connection_name_table[${connection_var_name}._typ]._method__v_delete(')
|
g.writeln('${result_name}_void ${result_var_name} = orm__Connection_name_table[${connection_var_name}._typ]._method__v_delete(')
|
||||||
g.indent++
|
g.indent++
|
||||||
g.writeln('${connection_var_name}._object, // Connection object')
|
g.writeln('${connection_var_name}._object, // Connection object')
|
||||||
g.writeln('_S("${table_name}"),')
|
g.write_orm_table_struct(node.table_expr.typ)
|
||||||
|
g.writeln(',')
|
||||||
g.write_orm_where(node.where_expr)
|
g.write_orm_where(node.where_expr)
|
||||||
g.indent--
|
g.indent--
|
||||||
g.writeln(');')
|
g.writeln(');')
|
||||||
@ -381,7 +429,8 @@ fn (mut g Gen) write_orm_insert_with_last_ids(node ast.SqlStmtLine, connection_v
|
|||||||
g.writeln('${result_name}_void ${res} = orm__Connection_name_table[${connection_var_name}._typ]._method_insert(')
|
g.writeln('${result_name}_void ${res} = orm__Connection_name_table[${connection_var_name}._typ]._method_insert(')
|
||||||
g.indent++
|
g.indent++
|
||||||
g.writeln('${connection_var_name}._object, // Connection object')
|
g.writeln('${connection_var_name}._object, // Connection object')
|
||||||
g.writeln('_S("${table_name}"),')
|
g.write_orm_table_struct(node.table_expr.typ)
|
||||||
|
g.writeln(',')
|
||||||
g.writeln('(orm__QueryData){')
|
g.writeln('(orm__QueryData){')
|
||||||
g.indent++
|
g.indent++
|
||||||
g.writeln('.fields = new_array_from_c_array(${fields.len}, ${fields.len}, sizeof(string),')
|
g.writeln('.fields = new_array_from_c_array(${fields.len}, ${fields.len}, sizeof(string),')
|
||||||
@ -880,7 +929,6 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re
|
|||||||
|
|
||||||
select_result_var_name := g.new_tmp_var()
|
select_result_var_name := g.new_tmp_var()
|
||||||
table_name := g.get_table_name_by_struct_type(node.table_expr.typ)
|
table_name := g.get_table_name_by_struct_type(node.table_expr.typ)
|
||||||
escaped_table_name := cescape_nonascii(util.smart_quote(table_name, false))
|
|
||||||
g.sql_table_name = g.table.sym(node.table_expr.typ).name
|
g.sql_table_name = g.table.sym(node.table_expr.typ).name
|
||||||
|
|
||||||
g.writeln('// sql { select from `${table_name}` }')
|
g.writeln('// sql { select from `${table_name}` }')
|
||||||
@ -889,7 +937,9 @@ fn (mut g Gen) write_orm_select(node ast.SqlExpr, connection_var_name string, re
|
|||||||
g.writeln('${connection_var_name}._object, // Connection object')
|
g.writeln('${connection_var_name}._object, // Connection object')
|
||||||
g.writeln('(orm__SelectConfig){')
|
g.writeln('(orm__SelectConfig){')
|
||||||
g.indent++
|
g.indent++
|
||||||
g.writeln('.table = _S("${escaped_table_name}"),')
|
g.writeln('.table = ')
|
||||||
|
g.write_orm_table_struct(node.table_expr.typ)
|
||||||
|
g.writeln(',')
|
||||||
g.writeln('.is_count = ${node.is_count},')
|
g.writeln('.is_count = ${node.is_count},')
|
||||||
g.writeln('.has_where = ${node.has_where},')
|
g.writeln('.has_where = ${node.has_where},')
|
||||||
g.writeln('.has_order = ${node.has_order},')
|
g.writeln('.has_order = ${node.has_order},')
|
||||||
@ -1246,6 +1296,13 @@ fn (g &Gen) get_db_expr_type(expr ast.Expr) ?ast.Type {
|
|||||||
return none
|
return none
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get_table_attrs_by_struct_type returns the struct attrs.
|
||||||
|
fn (g &Gen) get_table_attrs_by_struct_type(typ ast.Type) []ast.Attr {
|
||||||
|
sym := g.table.sym(typ)
|
||||||
|
info := sym.struct_info()
|
||||||
|
return info.attrs
|
||||||
|
}
|
||||||
|
|
||||||
// get_table_name_by_struct_type converts the struct type to a table name.
|
// get_table_name_by_struct_type converts the struct type to a table name.
|
||||||
fn (g &Gen) get_table_name_by_struct_type(typ ast.Type) string {
|
fn (g &Gen) get_table_name_by_struct_type(typ ast.Type) string {
|
||||||
sym := g.table.sym(typ)
|
sym := g.table.sym(typ)
|
||||||
@ -1255,8 +1312,8 @@ fn (g &Gen) get_table_name_by_struct_type(typ ast.Type) string {
|
|||||||
if attr := info.attrs.find_first('table') {
|
if attr := info.attrs.find_first('table') {
|
||||||
table_name = attr.arg
|
table_name = attr.arg
|
||||||
}
|
}
|
||||||
|
escaped_table_name := cescape_nonascii(util.smart_quote(table_name, false))
|
||||||
return table_name
|
return escaped_table_name
|
||||||
}
|
}
|
||||||
|
|
||||||
// get_orm_current_table_field returns the current processing table's struct field by name.
|
// get_orm_current_table_field returns the current processing table's struct field by name.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user