extralite 1.0 → 1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9c69948d51f689ead3e4ccf008bc7b0670085d0c987d39359bb38172b9993b58
4
- data.tar.gz: 776ed4e4f95cdb405b9b3be277d0aaa5a27fcd0e84aff8f6ebb3aeece531b1cf
3
+ metadata.gz: bcad0681ac1ee598acef1989d7320f4215242dcfb3dad8857e791e313b2e673b
4
+ data.tar.gz: c26b4ed323da3ccd965a026b7d1c738723293412d226bda3c7c6795881b73239
5
5
  SHA512:
6
- metadata.gz: 472db7ae94e195e647712ce04213538b229bcfebc3f9ec22b3f8e69dceb0a5cbba9000e14147a27ed2e26231aa7c73b43585a45be369f94d8cd2507643dd88b9
7
- data.tar.gz: 6475f99ebe990b9b073f77379f58ddcd4fa0f678fb32e64b39021e3aa7b6d6f9343c8f02d69cce1826a9d156c8b0918985536732af5a11be2bda28524524e8c2
6
+ metadata.gz: f1d5ab7ba821785f24a75cfe2e0d9d9fac0dbf6f2504321e24a89a89fc783fc3a30bc10f9ee4a97340202db04a8351e730c701d11e53643b065dee5fc009014b
7
+ data.tar.gz: 31a6ad671bb88f74ae2ba02d0da1e8c23275816ce41f630e82bcb7003b7e3f06a5cd9a53abeeb215bbedee54aeac763445809d4add0906cfbce087ce2acbc5b9
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## 1.1 2021-06-02
2
+
3
+ - Add `#close`, `#closed?` methods
4
+
1
5
  ## 1.0 2021-05-27
2
6
 
3
7
  - Refactor C code
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- extralite (1.0)
4
+ extralite (1.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -1,10 +1,16 @@
1
- ## Extralite
1
+ # Extralite - a Ruby gem for working with SQLite3 databases
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/extralite.svg)](http://rubygems.org/gems/extralite)
4
+ [![Modulation Test](https://github.com/digital-fabric/extralite/workflows/Tests/badge.svg)](https://github.com/digital-fabric/extralite/actions?query=workflow%3ATests)
5
+ [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/digital-fabric/extralite/blob/master/LICENSE)
6
+
7
+ ## What is Extralite?
2
8
 
3
9
  Extralite is an extra-lightweight (~365 lines of C-code) SQLite3 wrapper for
4
10
  Ruby. It provides a single class with a minimal set of methods to interact with
5
11
  an SQLite3 database.
6
12
 
7
- ### Features
13
+ ## Features
8
14
 
9
15
  - A variety of methods for different data access patterns: row as hash, row as
10
16
  array, single single row, single column, single value.
@@ -17,7 +23,7 @@ an SQLite3 database.
17
23
  - Load extensions (loading of extensions is autmatically enabled. You can find
18
24
  some useful extensions here: https://github.com/nalgeon/sqlean.)
19
25
 
20
- ### Usage
26
+ ## Usage
21
27
 
22
28
  ```ruby
23
29
  require 'extralite'
@@ -67,14 +73,14 @@ db.filename #=> "/tmp/my.db"
67
73
  db.load_extension('/path/to/extension.so')
68
74
  ```
69
75
 
70
- ### Why not just use the sqlite3 gem?
76
+ ## Why not just use the sqlite3 gem?
71
77
 
72
78
  The sqlite3-ruby gem is a popular, solid, well-maintained project, used by
73
79
  thousands of developers. I've been doing a lot of work with SQLite3 lately, and
74
80
  wanted to have a simpler API that gives me query results in a variety of ways.
75
81
  Thus extralite was born.
76
82
 
77
- ### What about concurrency?
83
+ ## What about concurrency?
78
84
 
79
85
  Extralite currently does not release the GVL. This means that even if queries
80
86
  are executed on a separate thread, no other Ruby threads will be scheduled while
@@ -83,7 +89,7 @@ SQLite3 is busy fetching the next record.
83
89
  In the future Extralite might be changed to release the GVL each time
84
90
  `sqlite3_step` is called.
85
91
 
86
- ### Can I use it with an ORM like ActiveRecord or Sequel?
92
+ ## Can I use it with an ORM like ActiveRecord or Sequel?
87
93
 
88
94
  Not yet, but you are welcome to contribute adapters for those projects. I will
89
95
  be releasing my own not-an-ORM tool in the near future.
@@ -39,6 +39,14 @@ static VALUE Database_allocate(VALUE klass) {
39
39
  #define GetDatabase(obj, database) \
40
40
  TypedData_Get_Struct((obj), Database_t, &Database_type, (database))
41
41
 
42
+ // make sure the database is open
43
+ #define GetOpenDatabase(obj, database) { \
44
+ TypedData_Get_Struct((obj), Database_t, &Database_type, (database)); \
45
+ if (!(database)->sqlite3_db) { \
46
+ rb_raise(cError, "Database is closed"); \
47
+ } \
48
+ }
49
+
42
50
 
43
51
  VALUE Database_initialize(VALUE self, VALUE path) {
44
52
  int rc;
@@ -60,6 +68,27 @@ VALUE Database_initialize(VALUE self, VALUE path) {
60
68
  return Qnil;
61
69
  }
62
70
 
71
+ VALUE Database_close(VALUE self) {
72
+ int rc;
73
+ Database_t *db;
74
+ GetDatabase(self, db);
75
+
76
+ rc = sqlite3_close(db->sqlite3_db);
77
+ if (rc) {
78
+ rb_raise(cError, "%s", sqlite3_errmsg(db->sqlite3_db));
79
+ }
80
+
81
+ db->sqlite3_db = 0;
82
+ return self;
83
+ }
84
+
85
+ VALUE Database_closed_p(VALUE self) {
86
+ Database_t *db;
87
+ GetDatabase(self, db);
88
+
89
+ return db->sqlite3_db ? Qfalse : Qtrue;
90
+ }
91
+
63
92
  inline VALUE get_column_value(sqlite3_stmt *stmt, int col, int type) {
64
93
  switch (type) {
65
94
  case SQLITE_NULL:
@@ -214,7 +243,7 @@ VALUE safe_query_hash(VALUE arg) {
214
243
  VALUE column_names;
215
244
 
216
245
  check_arity_and_prepare_sql(ctx->argc, ctx->argv, sql);
217
- GetDatabase(ctx->self, db);
246
+ GetOpenDatabase(ctx->self, db);
218
247
 
219
248
  prepare_multi_stmt(db->sqlite3_db, &ctx->stmt, sql);
220
249
  bind_all_parameters(ctx->stmt, ctx->argc, ctx->argv);
@@ -250,7 +279,7 @@ VALUE safe_query_ary(VALUE arg) {
250
279
  VALUE sql;
251
280
 
252
281
  check_arity_and_prepare_sql(ctx->argc, ctx->argv, sql);
253
- GetDatabase(ctx->self, db);
282
+ GetOpenDatabase(ctx->self, db);
254
283
 
255
284
  prepare_multi_stmt(db->sqlite3_db, &ctx->stmt, sql);
256
285
  bind_all_parameters(ctx->stmt, ctx->argc, ctx->argv);
@@ -283,7 +312,7 @@ VALUE safe_query_single_row(VALUE arg) {
283
312
  VALUE column_names;
284
313
 
285
314
  check_arity_and_prepare_sql(ctx->argc, ctx->argv, sql);
286
- GetDatabase(ctx->self, db);
315
+ GetOpenDatabase(ctx->self, db);
287
316
 
288
317
  prepare_multi_stmt(db->sqlite3_db, &ctx->stmt, sql);
289
318
  bind_all_parameters(ctx->stmt, ctx->argc, ctx->argv);
@@ -314,7 +343,7 @@ VALUE safe_query_single_column(VALUE arg) {
314
343
  VALUE value;
315
344
 
316
345
  check_arity_and_prepare_sql(ctx->argc, ctx->argv, sql);
317
- GetDatabase(ctx->self, db);
346
+ GetOpenDatabase(ctx->self, db);
318
347
 
319
348
  prepare_multi_stmt(db->sqlite3_db, &ctx->stmt, sql);
320
349
  bind_all_parameters(ctx->stmt, ctx->argc, ctx->argv);
@@ -348,7 +377,7 @@ VALUE safe_query_single_value(VALUE arg) {
348
377
  VALUE value = Qnil;
349
378
 
350
379
  check_arity_and_prepare_sql(ctx->argc, ctx->argv, sql);
351
- GetDatabase(ctx->self, db);
380
+ GetOpenDatabase(ctx->self, db);
352
381
 
353
382
  prepare_multi_stmt(db->sqlite3_db, &ctx->stmt, sql);
354
383
  bind_all_parameters(ctx->stmt, ctx->argc, ctx->argv);
@@ -370,14 +399,14 @@ VALUE Database_query_single_value(int argc, VALUE *argv, VALUE self) {
370
399
 
371
400
  VALUE Database_last_insert_rowid(VALUE self) {
372
401
  Database_t *db;
373
- GetDatabase(self, db);
402
+ GetOpenDatabase(self, db);
374
403
 
375
404
  return INT2NUM(sqlite3_last_insert_rowid(db->sqlite3_db));
376
405
  }
377
406
 
378
407
  VALUE Database_changes(VALUE self) {
379
408
  Database_t *db;
380
- GetDatabase(self, db);
409
+ GetOpenDatabase(self, db);
381
410
 
382
411
  return INT2NUM(sqlite3_changes(db->sqlite3_db));
383
412
  }
@@ -386,7 +415,7 @@ VALUE Database_filename(int argc, VALUE *argv, VALUE self) {
386
415
  const char *db_name;
387
416
  const char *filename;
388
417
  Database_t *db;
389
- GetDatabase(self, db);
418
+ GetOpenDatabase(self, db);
390
419
 
391
420
  rb_check_arity(argc, 0, 1);
392
421
  db_name = (argc == 1) ? StringValueCStr(argv[0]) : "main";
@@ -396,14 +425,14 @@ VALUE Database_filename(int argc, VALUE *argv, VALUE self) {
396
425
 
397
426
  VALUE Database_transaction_active_p(VALUE self) {
398
427
  Database_t *db;
399
- GetDatabase(self, db);
428
+ GetOpenDatabase(self, db);
400
429
 
401
430
  return sqlite3_get_autocommit(db->sqlite3_db) ? Qfalse : Qtrue;
402
431
  }
403
432
 
404
433
  VALUE Database_load_extension(VALUE self, VALUE path) {
405
434
  Database_t *db;
406
- GetDatabase(self, db);
435
+ GetOpenDatabase(self, db);
407
436
  char *err_msg;
408
437
 
409
438
  int rc = sqlite3_load_extension(db->sqlite3_db, RSTRING_PTR(path), 0, &err_msg);
@@ -422,6 +451,8 @@ void Init_Extralite() {
422
451
  rb_define_alloc_func(cDatabase, Database_allocate);
423
452
 
424
453
  rb_define_method(cDatabase, "initialize", Database_initialize, 1);
454
+ rb_define_method(cDatabase, "close", Database_close, 0);
455
+ rb_define_method(cDatabase, "closed?", Database_closed_p, 0);
425
456
 
426
457
  rb_define_method(cDatabase, "query", Database_query_hash, -1);
427
458
  rb_define_method(cDatabase, "query_hash", Database_query_hash, -1);
@@ -1,3 +1,3 @@
1
1
  module Extralite
2
- VERSION = '1.0'
2
+ VERSION = '1.1'
3
3
  end
@@ -89,4 +89,15 @@ end
89
89
  r = @db.query('select 1 as foo; ')
90
90
  assert_equal [{ foo: 1 }], r
91
91
  end
92
+
93
+ def test_close
94
+ assert_equal false, @db.closed?
95
+ r = @db.query_single_value('select 42')
96
+ assert_equal 42, r
97
+
98
+ assert_equal @db, @db.close
99
+ assert_equal true, @db.closed?
100
+
101
+ assert_raises(Extralite::Error) { @db.query_single_value('select 42') }
102
+ end
92
103
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: extralite
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.0'
4
+ version: '1.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-27 00:00:00.000000000 Z
11
+ date: 2021-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler