-
Notifications
You must be signed in to change notification settings - Fork 207
Add statement_timeout=
method
#463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
6c4e155
046bd67
11a94dc
50f1ef0
c6bf834
3681b2a
c0d5144
e3f95ca
3ebee19
b819265
3ba847c
870f3b9
bf1f0e6
c8007e7
ae76a01
cd47d9b
13d4067
31e44c1
bd0267e
6456dec
832fe6a
c80aeef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -259,6 +259,45 @@ busy_handler(int argc, VALUE *argv, VALUE self) | |
return self; | ||
} | ||
|
||
static int | ||
rb_sqlite3_statement_timeout(void *context) | ||
{ | ||
sqlite3RubyPtr ctx = (sqlite3RubyPtr)context; | ||
struct timespec currentTime; | ||
clock_gettime(CLOCK_MONOTONIC, ¤tTime); | ||
|
||
if (ctx->stmt_deadline == 0) { | ||
ctx->stmt_deadline = currentTime.tv_sec * 1e9 + currentTime.tv_nsec + (long long)ctx->stmt_timeout * 1e6; | ||
|
||
} else { | ||
long long timeDiff = ctx->stmt_deadline - (currentTime.tv_sec * 1e9 + currentTime.tv_nsec); | ||
|
||
if (timeDiff < 0) { return 1; } | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
/* call-seq: db.statement_timeout = ms | ||
* | ||
* Indicates that if a query lasts longer than the indicated number of | ||
* milliseconds, SQLite should interrupt that query and return an error. | ||
* By default, SQLite does not interrupt queries. To restore the default | ||
* behavior, send 0 as the +ms+ parameter. | ||
*/ | ||
static VALUE | ||
set_statement_timeout(VALUE self, VALUE milliseconds) | ||
{ | ||
sqlite3RubyPtr ctx; | ||
TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx); | ||
|
||
ctx->stmt_timeout = NUM2INT(milliseconds); | ||
int n = NUM2INT(milliseconds) == 0 ? -1 : 1000; | ||
|
||
sqlite3_progress_handler(ctx->db, n, rb_sqlite3_statement_timeout, (void *)ctx); | ||
|
||
return self; | ||
} | ||
|
||
/* call-seq: last_insert_row_id | ||
* | ||
* Obtains the unique row ID of the last row to be inserted by this Database | ||
|
@@ -875,6 +914,9 @@ init_sqlite3_database(void) | |
rb_define_method(cSqlite3Database, "authorizer=", set_authorizer, 1); | ||
rb_define_method(cSqlite3Database, "busy_handler", busy_handler, -1); | ||
rb_define_method(cSqlite3Database, "busy_timeout=", set_busy_timeout, 1); | ||
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK | ||
rb_define_method(cSqlite3Database, "statement_timeout=", set_statement_timeout, 1); | ||
#endif | ||
rb_define_method(cSqlite3Database, "extended_result_codes=", set_extended_result_codes, 1); | ||
rb_define_method(cSqlite3Database, "transaction_active?", transaction_active_p, 0); | ||
rb_define_private_method(cSqlite3Database, "exec_batch", exec_batch, 2); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see it being reset anywhere. I suspect you need to reset the deadline before every query.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great point! The place in
Statement
where I had already access to the database struct was inprepare
, so I reset it there. Does that make sense?