extralite 1.0 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
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