diff --git a/vlib/db/mysql/orm.v b/vlib/db/mysql/orm.v index fef217057c..b836852cc0 100644 --- a/vlib/db/mysql/orm.v +++ b/vlib/db/mysql/orm.v @@ -134,20 +134,20 @@ pub fn (db Connection) insert(table string, data orm.QueryData) ! { is_and: [] } - query, converted_data := orm.orm_stmt_gen(table, '`', .insert, false, '?', 1, converted_primitive_data, - orm.QueryData{}) + query, converted_data := orm.orm_stmt_gen(.default, table, '`', .insert, false, '?', + 1, converted_primitive_data, orm.QueryData{}) mysql_stmt_worker(db, query, converted_data, orm.QueryData{})! } // update is used internally by V's ORM for processing `UPDATE ` queries pub fn (db Connection) update(table string, data orm.QueryData, where orm.QueryData) ! { - query, _ := orm.orm_stmt_gen(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)! } // delete is used internally by V's ORM for processing `DELETE ` queries pub fn (db Connection) delete(table string, where orm.QueryData) ! { - query, _ := orm.orm_stmt_gen(table, '`', .delete, false, '?', 1, orm.QueryData{}, + query, _ := orm.orm_stmt_gen(.default, table, '`', .delete, false, '?', 1, orm.QueryData{}, where) mysql_stmt_worker(db, query, orm.QueryData{}, where)! } diff --git a/vlib/db/pg/orm.v b/vlib/db/pg/orm.v index e21272c7e8..1467276529 100644 --- a/vlib/db/pg/orm.v +++ b/vlib/db/pg/orm.v @@ -33,20 +33,21 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu // insert is used internally by V's ORM for processing `INSERT ` queries pub fn (db DB) insert(table string, data orm.QueryData) ! { - query, converted_data := orm.orm_stmt_gen(table, '"', .insert, true, '$', 1, data, - orm.QueryData{}) + query, converted_data := orm.orm_stmt_gen(.default, table, '"', .insert, true, '$', + 1, data, orm.QueryData{}) pg_stmt_worker(db, query, converted_data, orm.QueryData{})! } // 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) ! { - query, _ := orm.orm_stmt_gen(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)! } // delete is used internally by V's ORM for processing `DELETE ` queries pub fn (db DB) delete(table string, where orm.QueryData) ! { - query, _ := orm.orm_stmt_gen(table, '"', .delete, true, '$', 1, orm.QueryData{}, where) + query, _ := orm.orm_stmt_gen(.default, table, '"', .delete, true, '$', 1, orm.QueryData{}, + where) pg_stmt_worker(db, query, orm.QueryData{}, where)! } diff --git a/vlib/db/sqlite/orm.v b/vlib/db/sqlite/orm.v index 19c1b1bade..52cc7eb46c 100644 --- a/vlib/db/sqlite/orm.v +++ b/vlib/db/sqlite/orm.v @@ -53,20 +53,21 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu // insert is used internally by V's ORM for processing `INSERT ` queries pub fn (db DB) insert(table string, data orm.QueryData) ! { - query, converted_data := orm.orm_stmt_gen(table, '`', .insert, true, '?', 1, data, - orm.QueryData{}) + query, converted_data := orm.orm_stmt_gen(.sqlite, table, '`', .insert, true, '?', + 1, data, orm.QueryData{}) sqlite_stmt_worker(db, query, converted_data, orm.QueryData{})! } // 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) ! { - query, _ := orm.orm_stmt_gen(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)! } // delete is used internally by V's ORM for processing `DELETE ` queries pub fn (db DB) delete(table string, where orm.QueryData) ! { - query, _ := orm.orm_stmt_gen(table, '`', .delete, true, '?', 1, orm.QueryData{}, where) + query, _ := orm.orm_stmt_gen(.sqlite, table, '`', .delete, true, '?', 1, orm.QueryData{}, + where) sqlite_stmt_worker(db, query, orm.QueryData{}, where)! } diff --git a/vlib/mysql/orm.v b/vlib/mysql/orm.v index e0b2e2c9f8..92ca2993ab 100644 --- a/vlib/mysql/orm.v +++ b/vlib/mysql/orm.v @@ -132,18 +132,18 @@ pub fn (db Connection) insert(table string, data orm.QueryData) ! { is_and: [] } - query, converted_data := orm.orm_stmt_gen(table, '`', .insert, false, '?', 1, converted_primitive_data, - orm.QueryData{}) + query, converted_data := orm.orm_stmt_gen(.default, table, '`', .insert, false, '?', + 1, converted_primitive_data, orm.QueryData{}) mysql_stmt_worker(db, query, converted_data, orm.QueryData{})! } pub fn (db Connection) update(table string, data orm.QueryData, where orm.QueryData) ! { - query, _ := orm.orm_stmt_gen(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)! } pub fn (db Connection) delete(table string, where orm.QueryData) ! { - query, _ := orm.orm_stmt_gen(table, '`', .delete, false, '?', 1, orm.QueryData{}, + query, _ := orm.orm_stmt_gen(.default, table, '`', .delete, false, '?', 1, orm.QueryData{}, where) mysql_stmt_worker(db, query, orm.QueryData{}, where)! } diff --git a/vlib/orm/orm.v b/vlib/orm/orm.v index 66b70bd467..80bf2b57fd 100644 --- a/vlib/orm/orm.v +++ b/vlib/orm/orm.v @@ -79,6 +79,11 @@ pub enum OrderType { desc } +pub enum SQLDialect { + default + sqlite +} + fn (kind OperationKind) to_str() string { str := match kind { .neq { '!=' } @@ -181,9 +186,9 @@ pub interface Connection { // Generates an sql stmt, from universal parameter // q - The quotes character, which can be different in every type, so it's variable // num - Stmt uses nums at prepared statements (? or ?1) -// qm - Character for prepared statment, qm because of quotation mark like in sqlite +// qm - Character for prepared statement, qm because of quotation mark like in sqlite // start_pos - When num is true, it's the start position of the counter -pub fn orm_stmt_gen(table string, q string, kind StmtKind, num bool, qm string, start_pos int, data QueryData, where QueryData) (string, QueryData) { +pub fn orm_stmt_gen(sql_dialect SQLDialect, table string, q string, kind StmtKind, num bool, qm string, start_pos int, data QueryData, where QueryData) (string, QueryData) { mut str := '' mut c := start_pos mut data_fields := []string{} @@ -217,11 +222,19 @@ pub fn orm_stmt_gen(table string, q string, kind StmtKind, num bool, qm string, c++ } - str += 'INSERT INTO ${q}${table}${q} (' - str += select_fields.join(', ') - str += ') VALUES (' - str += values.join(', ') - str += ')' + str += 'INSERT INTO ${q}${table}${q} ' + + are_values_empty := values.len == 0 + + if sql_dialect == .sqlite && are_values_empty { + str += 'DEFAULT VALUES' + } else { + str += '(' + str += select_fields.join(', ') + str += ') VALUES (' + str += values.join(', ') + str += ')' + } } .update { str += 'UPDATE ${q}${table}${q} SET ' diff --git a/vlib/orm/orm_fn_test.v b/vlib/orm/orm_fn_test.v index e824ff1caa..67ffb778ef 100644 --- a/vlib/orm/orm_fn_test.v +++ b/vlib/orm/orm_fn_test.v @@ -1,7 +1,7 @@ import orm fn test_orm_stmt_gen_update() { - query, _ := orm.orm_stmt_gen('Test', "'", .update, true, '?', 0, orm.QueryData{ + query, _ := orm.orm_stmt_gen(.default, 'Test', "'", .update, true, '?', 0, orm.QueryData{ fields: ['test', 'a'] data: [] types: [] @@ -16,7 +16,7 @@ fn test_orm_stmt_gen_update() { } fn test_orm_stmt_gen_insert() { - query, _ := orm.orm_stmt_gen('Test', "'", .insert, true, '?', 0, orm.QueryData{ + query, _ := orm.orm_stmt_gen(.default, 'Test', "'", .insert, true, '?', 0, orm.QueryData{ fields: ['test', 'a'] data: [] types: [] @@ -26,7 +26,7 @@ fn test_orm_stmt_gen_insert() { } fn test_orm_stmt_gen_delete() { - query, _ := orm.orm_stmt_gen('Test', "'", .delete, true, '?', 0, orm.QueryData{ + query, _ := orm.orm_stmt_gen(.default, 'Test', "'", .delete, true, '?', 0, orm.QueryData{ fields: ['test', 'a'] data: [] types: [] diff --git a/vlib/orm/orm_insert_test.v b/vlib/orm/orm_insert_test.v index 8ee51a41c4..dcbc1fc04e 100644 --- a/vlib/orm/orm_insert_test.v +++ b/vlib/orm/orm_insert_test.v @@ -21,12 +21,33 @@ mut: text string } +struct Account { + id int [primary; sql: serial] +} + pub fn insert_parent(db sqlite.DB, mut parent Parent) { sql db { insert parent into Parent } } +fn test_insert_empty_object() { + db := sqlite.connect(':memory:') or { panic(err) } + + account := Account{} + + sql db { + create table Account + insert account into Account + } + + accounts := sql db { + select from Account + } + + assert accounts.len == 1 +} + fn test_orm_insert_mut_object() { db := sqlite.connect(':memory:') or { panic(err) } diff --git a/vlib/pg/orm.v b/vlib/pg/orm.v index 0c8799b4f3..6bc62c0365 100644 --- a/vlib/pg/orm.v +++ b/vlib/pg/orm.v @@ -31,18 +31,19 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu // sql stmt pub fn (db DB) insert(table string, data orm.QueryData) ! { - query, converted_data := orm.orm_stmt_gen(table, '"', .insert, true, '$', 1, data, - orm.QueryData{}) + query, converted_data := orm.orm_stmt_gen(.default, table, '"', .insert, true, '$', + 1, data, orm.QueryData{}) pg_stmt_worker(db, query, converted_data, orm.QueryData{})! } pub fn (db DB) update(table string, data orm.QueryData, where orm.QueryData) ! { - query, _ := orm.orm_stmt_gen(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)! } pub fn (db DB) delete(table string, where orm.QueryData) ! { - query, _ := orm.orm_stmt_gen(table, '"', .delete, true, '$', 1, orm.QueryData{}, where) + query, _ := orm.orm_stmt_gen(.default, table, '"', .delete, true, '$', 1, orm.QueryData{}, + where) pg_stmt_worker(db, query, orm.QueryData{}, where)! } diff --git a/vlib/sqlite/orm.v b/vlib/sqlite/orm.v index 07b76a0646..6f8e114097 100644 --- a/vlib/sqlite/orm.v +++ b/vlib/sqlite/orm.v @@ -53,18 +53,19 @@ pub fn (db DB) @select(config orm.SelectConfig, data orm.QueryData, where orm.Qu // sql stmt pub fn (db DB) insert(table string, data orm.QueryData) ! { - query, converted_data := orm.orm_stmt_gen(table, '`', .insert, true, '?', 1, data, - orm.QueryData{}) + query, converted_data := orm.orm_stmt_gen(.sqlite, table, '`', .insert, true, '?', + 1, data, orm.QueryData{}) sqlite_stmt_worker(db, query, converted_data, orm.QueryData{})! } pub fn (db DB) update(table string, data orm.QueryData, where orm.QueryData) ! { - query, _ := orm.orm_stmt_gen(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)! } pub fn (db DB) delete(table string, where orm.QueryData) ! { - query, _ := orm.orm_stmt_gen(table, '`', .delete, true, '?', 1, orm.QueryData{}, where) + query, _ := orm.orm_stmt_gen(.sqlite, table, '`', .delete, true, '?', 1, orm.QueryData{}, + where) sqlite_stmt_worker(db, query, orm.QueryData{}, where)! }