diff --git a/ext/sqlite3/database.c b/ext/sqlite3/database.c index 36b75787..c1bc6307 100644 --- a/ext/sqlite3/database.c +++ b/ext/sqlite3/database.c @@ -723,6 +723,24 @@ transaction_active_p(VALUE self) return sqlite3_get_autocommit(ctx->db) ? Qfalse : Qtrue; } +/* call-seq: db.cache_misses + * + * Return the number of pager cache misses that have occurred. + * + */ +static VALUE +cache_misses(VALUE self) +{ + sqlite3RubyPtr ctx; + TypedData_Get_Struct(self, sqlite3Ruby, &database_type, ctx); + REQUIRE_OPEN_DB(ctx); + int iCur, iHi; + + sqlite3_db_status(ctx->db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHi, 0); + + return INT2NUM(iCur); +} + static int hash_callback_function(VALUE callback_ary, int count, char **data, char **columns) { @@ -877,6 +895,7 @@ init_sqlite3_database(void) rb_define_method(cSqlite3Database, "busy_timeout=", set_busy_timeout, 1); rb_define_method(cSqlite3Database, "extended_result_codes=", set_extended_result_codes, 1); rb_define_method(cSqlite3Database, "transaction_active?", transaction_active_p, 0); + rb_define_method(cSqlite3Database, "cache_misses", cache_misses, 0); rb_define_private_method(cSqlite3Database, "exec_batch", exec_batch, 2); rb_define_private_method(cSqlite3Database, "db_filename", db_filename, 1); diff --git a/test/test_database.rb b/test/test_database.rb index 04f226cd..c023f2cf 100644 --- a/test/test_database.rb +++ b/test/test_database.rb @@ -651,5 +651,20 @@ def test_default_transaction_mode ensure tf&.unlink end + + def test_cache_misses + db = SQLite3::Database.new('test.db') + db.execute("PRAGMA cache_size = -1;") + db.execute "CREATE TABLE example_table (id INTEGER PRIMARY KEY, data TEXT);" + 10.times do |i| + db.execute 'INSERT INTO example_table (data) SELECT randomblob(1000);' + end + db.execute("SELECT * FROM example_table WHERE id BETWEEN 5000 AND 6000;") + + assert_equal 28, db.cache_misses + ensure + db.close if db + File.delete( "test.db" ) + end end end