From f44af02e32aa8c4c7db1a9e08ae9d6ccfe9217f6 Mon Sep 17 00:00:00 2001 From: Dominik Pytlewski Date: Mon, 14 Nov 2022 15:23:42 +0100 Subject: [PATCH] sqlite: affected rows count (#16426) --- vlib/sqlite/sqlite.v | 9 ++++- vlib/sqlite/sqlite_orm_test.v | 66 +++++++++++++++++++++++++++++++++++ vlib/sqlite/sqlite_test.v | 19 ++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) diff --git a/vlib/sqlite/sqlite.v b/vlib/sqlite/sqlite.v index 84bce9684d..48d1d31570 100644 --- a/vlib/sqlite/sqlite.v +++ b/vlib/sqlite/sqlite.v @@ -122,6 +122,8 @@ fn C.sqlite3_errmsg(&C.sqlite3) &char fn C.sqlite3_free(voidptr) +fn C.sqlite3_changes(&C.sqlite3) int + // connect Opens the connection with a database. pub fn connect(path string) !DB { db := &C.sqlite3(0) @@ -166,12 +168,17 @@ fn get_int_from_stmt(stmt &C.sqlite3_stmt) int { return res } -// Returns last insert rowid +// last_insert_rowid returns last inserted rowid // https://www.sqlite.org/c3ref/last_insert_rowid.html pub fn (db &DB) last_insert_rowid() i64 { return C.sqlite3_last_insert_rowid(db.conn) } +// get_affected_rows_count returns `sqlite changes()` meaning amount of rows affected by most recent sql query +pub fn (db &DB) get_affected_rows_count() int { + return C.sqlite3_changes(db.conn) +} + // Returns a single cell with value int. pub fn (db &DB) q_int(query string) int { stmt := &C.sqlite3_stmt(0) diff --git a/vlib/sqlite/sqlite_orm_test.v b/vlib/sqlite/sqlite_orm_test.v index 363ec72d9a..59f72cc343 100644 --- a/vlib/sqlite/sqlite_orm_test.v +++ b/vlib/sqlite/sqlite_orm_test.v @@ -22,6 +22,11 @@ struct TestDefaultAtribute { created_at2 string [default: 'CURRENT_TIMESTAMP'] } +struct EntityToTest { + id int [notnull; sql_type: 'INTEGER'] + smth string [notnull; sql_type: 'TEXT'] +} + fn test_sqlite_orm() { mut db := sqlite.connect(':memory:') or { panic(err) } defer { @@ -161,3 +166,64 @@ fn test_sqlite_orm() { drop table TestDefaultAtribute } } + +fn test_get_affected_rows_count() { + mut db := sqlite.connect(':memory:') or { panic(err) } + defer { + db.close() or { panic(err) } + } + + db.exec('create table EntityToTest( + id integer not null constraint tbl_pk primary key, + smth integer + );') + + fst := EntityToTest{ + id: 1 + smth: '1' + } + + sql db { + insert fst into EntityToTest + } or { panic('first insert failed') } + + assert db.get_affected_rows_count() == 1 + + snd := EntityToTest{ + id: 1 + smth: '2' + } + + mut sndfailed := false + sql db { + insert snd into EntityToTest + } or { sndfailed = true } + + assert db.get_affected_rows_count() == 0 + assert sndfailed + + 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 +} diff --git a/vlib/sqlite/sqlite_test.v b/vlib/sqlite/sqlite_test.v index 22c5bc388d..bf7032bd7b 100644 --- a/vlib/sqlite/sqlite_test.v +++ b/vlib/sqlite/sqlite_test.v @@ -10,6 +10,7 @@ fn test_sqlite() { db.exec("create table users (id integer primary key, name text default '');") db.exec("insert into users (name) values ('Sam')") assert db.last_insert_rowid() == 1 + assert db.get_affected_rows_count() == 1 db.exec("insert into users (name) values ('Peter')") assert db.last_insert_rowid() == 2 db.exec("insert into users (name) values ('Kate')") @@ -18,6 +19,11 @@ fn test_sqlite() { assert nr_users == 3 name := db.q_string('select name from users where id = 1') assert name == 'Sam' + + // this insert will be rejected due to duplicated id + db.exec("insert into users (id,name) values (1,'Sam')") + assert db.get_affected_rows_count() == 0 + users, mut code := db.exec('select * from users') assert users.len == 3 assert code == 101 @@ -26,6 +32,19 @@ fn test_sqlite() { user := db.exec_one('select * from users where id = 3') or { panic(err) } println(user) assert user.vals.len == 2 + + db.exec("update users set name='zzzz' where name='qqqq'") + assert db.get_affected_rows_count() == 0 + + db.exec("update users set name='Peter1' where name='Peter'") + assert db.get_affected_rows_count() == 1 + + db.exec("delete from users where name='qqqq'") + assert db.get_affected_rows_count() == 0 + + db.exec("delete from users where name='Sam'") + assert db.get_affected_rows_count() == 1 + db.close() or { panic(err) } assert !db.is_open }