extralite 1.13.1 → 1.15

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: 887537f02a38e762c189e2c322074efc59ef28a662021f59fbfad6cc0dafc13c
4
- data.tar.gz: e519f080b81120044cd25113145fb571e5655b377e992643b5fc711a7ab6abfa
3
+ metadata.gz: 0275df0298c578e4b166e392a43e7edcc4566d08eccdfe8c76ef0fd4e2a0c244
4
+ data.tar.gz: 312f5218786eaeaa879703c403ace437b351f76fe1fd5660d3d64fe6592f1c8a
5
5
  SHA512:
6
- metadata.gz: 50fef96363c87e0f2461165bed0c608b0bf7a24d1d3d9b90fc1b741446a2685d94bd54d392bae1714984b4c95fbf925c1a839c2b70bfb62262fc3e1112c321a8
7
- data.tar.gz: ca51f38183ebc65b01b18ad4ce58885eba4481ab8804de3e70ad140e1470bfeb2c99177db6e0817fb8aa5532c532d6a848e0b20814da93f29b84f7f4fd9bdd6d
6
+ metadata.gz: 8b2052fc2ca18c5d1e61c5ada2a094a1ef5e56053ab8434b8fbb55da35bd2633dcae0131b383caf0b7a9f2990a05205d8788a72ae98ce79b69854f8b517e4c6e
7
+ data.tar.gz: cff930e31e7f6d0050f2467c2661fa8369ba259bdaf9359154da1ba9ba5dc67ca3c6f327a34dbac73f0edf3d145962c2e973e12bee9c2f323a07612c5b984c03
@@ -7,8 +7,8 @@ jobs:
7
7
  strategy:
8
8
  fail-fast: false
9
9
  matrix:
10
- os: [ubuntu-latest, macos-10.15]
11
- ruby: [2.7, 3.0, 3.1, truffleruby]
10
+ os: [ubuntu-latest, macos-latest]
11
+ ruby: ['2.7', '3.0', '3.1', truffleruby]
12
12
 
13
13
  name: >-
14
14
  ${{matrix.os}}, ${{matrix.ruby}}
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 1.15 2022-10-01
2
+
3
+ - Add `Database#pragma` method
4
+ - Add `Database#tables` method
5
+
6
+ ## 1.14 2022-02-28
7
+
8
+ - Introduce `extralite-bundle` gem for bundling SQLite, use system lib by
9
+ default.
10
+
1
11
  ## 1.13.1 2022-02-27
2
12
 
3
13
  - Fix compilation on TruffleRuby
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gemspec
3
+ gemspec name: 'extralite'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- extralite (1.13.1)
4
+ extralite (1.15)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2021 Sharon Rosner
3
+ Copyright (c) 2022 Sharon Rosner
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -25,17 +25,21 @@
25
25
 
26
26
  Extralite is a fast, extra-lightweight (about 600 lines of C-code) SQLite3
27
27
  wrapper for Ruby. It provides a minimal set of methods for interacting with an
28
- SQLite3 database, as well as prepared statements. Extralite bundles the latest
29
- version of SQLite, offering access to the latest features and enhancements.
28
+ SQLite3 database, as well as prepared statements.
29
+
30
+ Extralite comes in two flavors: the `extralite` gem which uses the
31
+ system-installed sqlite3 library, and the `extralite-bundle` gem which bundles
32
+ the latest version of SQLite
33
+ ([3.38.0](https://sqlite.org/releaselog/3_38_0.html)), offering access to the
34
+ latest features and enhancements.
30
35
 
31
36
  ## Features
32
37
 
33
- - Zero dependencies: Extralite bundles SQLite3 version
34
- [3.38.0](https://sqlite.org/releaselog/3_38_0.html) - no need to install any
35
- `libsqlite3` packages.
36
38
  - A variety of methods for different data access patterns: rows as hashes, rows
37
39
  as arrays, single row, single column, single value.
38
40
  - Prepared statements.
41
+ - Use system-installed sqlite3, or the [bundled latest version of
42
+ SQLite3](#installing-the-extralite-sqlite3-bundle).
39
43
  - Super fast - [up to 12.5x faster](#performance) than the
40
44
  [sqlite3](https://github.com/sparklemotion/sqlite3-ruby) gem (see also
41
45
  [comparison](#why-not-just-use-the-sqlite3-gem).)
@@ -61,9 +65,18 @@ gem 'extralite'
61
65
 
62
66
  You can also run `gem install extralite` if you just want to check it out.
63
67
 
64
- > **Important note**: Extralite will take a while to install (on my modest
65
- > machine it takes about a minute). This is owing to the fact that Extralite
66
- > bundles the sqlite3 code, which is compiled upon installation.
68
+ ### Installing the Extralite-SQLite3 bundle
69
+
70
+ If you don't have sqlite3 installed on your system, do not want to use the
71
+ system-installed version of SQLite3, or would like to use the latest version of
72
+ SQLite3, you can install the `extralite-bundle` gem, which integrates the
73
+ SQLite3 source code.
74
+
75
+ > **Important note**: The `extralite-bundle` will take a while to install (on my
76
+ > modest machine it takes about a minute), due to the size of the sqlite3 code.
77
+
78
+ Usage of the `extralite-bundle` gem is identical to the usage of the normal
79
+ `extralite` gem.
67
80
 
68
81
  ## Usage
69
82
 
@@ -71,7 +84,7 @@ You can also run `gem install extralite` if you just want to check it out.
71
84
  require 'extralite'
72
85
 
73
86
  # get sqlite3 version
74
- Extralite.sqlite3_version #=> "3.38.0"
87
+ Extralite.sqlite3_version #=> "3.35.2"
75
88
 
76
89
  # open a database
77
90
  db = Extralite::Database.new('/tmp/my.db')
@@ -125,6 +138,14 @@ number_of_rows_affected = db.changes
125
138
  # get db filename
126
139
  db.filename #=> "/tmp/my.db"
127
140
 
141
+ # get list of tables
142
+ db.tables #=> ['foo', 'bar']
143
+
144
+ # get and set pragmas
145
+ db.pragma(:journal_mode) #=> 'delete'
146
+ db.pragma(journal_mode: 'wal')
147
+ db.pragma(:journal_mode) #=> 'wal'
148
+
128
149
  # load an extension
129
150
  db.load_extension('/path/to/extension.so')
130
151
 
@@ -164,7 +185,7 @@ Here's a table summarizing the differences between the two gems:
164
185
 
165
186
  | |sqlite3-ruby|Extralite|
166
187
  |-|-|-|
167
- |SQLite3 dependency|depends on OS-installed libsqlite3|bundles latest version of SQLite3|
188
+ |SQLite3 dependency|depends on OS-installed libsqlite3|Use either system sqlite3 or [bundled latest version of SQLite3](#installing-the-extralite-sqlite3-bundle)|
168
189
  |API design|multiple classes|single class|
169
190
  |Query results|row as hash, row as array, single row, single value|row as hash, row as array, __single column__, single row, single value|
170
191
  |Execute multiple statements|separate API (#execute_batch)|integrated|
@@ -225,6 +246,12 @@ As those benchmarks show, Extralite is capabale of reading up to 3M rows/second
225
246
  when fetching rows as arrays, and up to 2.6M rows/second when fetching
226
247
  rows as hashes.
227
248
 
249
+ ## License
250
+
251
+ The source code for Extralite is published under the [MIT license](LICENSE). The
252
+ source code for SQLite is in the [public
253
+ domain](https://sqlite.org/copyright.html).
254
+
228
255
  ## Contributing
229
256
 
230
257
  Contributions in the form of issues, PRs or comments will be greatly
data/Rakefile CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bundler/gem_tasks'
4
3
  require 'rake/clean'
5
4
 
6
5
  require 'rake/extensiontask'
@@ -25,3 +24,23 @@ YARD::Rake::YardocTask.new do |t|
25
24
  t.files = YARD_FILES
26
25
  t.options = %w(-o doc --readme README.md)
27
26
  end
27
+
28
+ task :release do
29
+ require_relative './lib/extralite/version'
30
+ version = Extralite::VERSION
31
+
32
+ puts 'Building extralite...'
33
+ `gem build extralite.gemspec`
34
+
35
+ puts 'Building extralite-bundle...'
36
+ `gem build extralite-bundle.gemspec`
37
+
38
+ puts "Pushing extralite #{version}..."
39
+ `gem push extralite-#{version}.gem`
40
+
41
+ puts "Pushing extralite-bundle #{version}..."
42
+ `gem push extralite-bundle-#{version}.gem`
43
+
44
+ puts "Cleaning up..."
45
+ `rm *.gem`
46
+ end
@@ -31,7 +31,7 @@ void bind_hash_parameter_values(sqlite3_stmt *stmt, VALUE hash) {
31
31
 
32
32
  switch (TYPE(k)) {
33
33
  case T_FIXNUM:
34
- bind_parameter_value(stmt, NUM2INT(k), v);
34
+ bind_parameter_value(stmt, FIX2INT(k), v);
35
35
  break;
36
36
  case T_SYMBOL:
37
37
  k = rb_funcall(k, ID_TO_S, 0);
@@ -345,3 +345,7 @@ VALUE safe_query_single_value(query_ctx *ctx) {
345
345
  RB_GC_GUARD(value);
346
346
  return value;
347
347
  }
348
+
349
+ VALUE safe_query_columns(query_ctx *ctx) {
350
+ return get_column_names(ctx->stmt, sqlite3_column_count(ctx->stmt));
351
+ }
@@ -263,6 +263,15 @@ VALUE Database_query_single_value(int argc, VALUE *argv, VALUE self) {
263
263
  return Database_perform_query(argc, argv, self, safe_query_single_value);
264
264
  }
265
265
 
266
+ /* call-seq:
267
+ * db.columns(sql) -> columns
268
+ *
269
+ * Returns the column names for the given query, without running it.
270
+ */
271
+ VALUE Database_columns(VALUE self, VALUE sql) {
272
+ return Database_perform_query(1, &sql, self, safe_query_columns);
273
+ }
274
+
266
275
  /* call-seq:
267
276
  * db.last_insert_rowid -> int
268
277
  *
@@ -272,7 +281,7 @@ VALUE Database_last_insert_rowid(VALUE self) {
272
281
  Database_t *db;
273
282
  GetOpenDatabase(self, db);
274
283
 
275
- return INT2NUM(sqlite3_last_insert_rowid(db->sqlite3_db));
284
+ return INT2FIX(sqlite3_last_insert_rowid(db->sqlite3_db));
276
285
  }
277
286
 
278
287
  /* call-seq:
@@ -284,7 +293,7 @@ VALUE Database_changes(VALUE self) {
284
293
  Database_t *db;
285
294
  GetOpenDatabase(self, db);
286
295
 
287
- return INT2NUM(sqlite3_changes(db->sqlite3_db));
296
+ return INT2FIX(sqlite3_changes(db->sqlite3_db));
288
297
  }
289
298
 
290
299
  /* call-seq:
@@ -362,6 +371,7 @@ void Init_ExtraliteDatabase() {
362
371
  rb_define_method(cDatabase, "query_single_row", Database_query_single_row, -1);
363
372
  rb_define_method(cDatabase, "query_single_column", Database_query_single_column, -1);
364
373
  rb_define_method(cDatabase, "query_single_value", Database_query_single_value, -1);
374
+ rb_define_method(cDatabase, "columns", Database_columns, 1);
365
375
 
366
376
  rb_define_method(cDatabase, "last_insert_rowid", Database_last_insert_rowid, 0);
367
377
  rb_define_method(cDatabase, "changes", Database_changes, 0);
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'mkmf'
4
+
5
+ $CFLAGS << " -Wno-undef"
6
+ $CFLAGS << " -Wno-discarded-qualifiers"
7
+
8
+ dir_config('extralite_ext')
9
+ create_makefile('extralite_ext')
@@ -1,9 +1,115 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # require 'rubygems'
4
+ # require 'mkmf'
5
+
6
+ # # $CFLAGS << "-Wdiscarded-qualifier"
7
+ # # $CFLAGS << " -Wno-comment"
8
+ # # $CFLAGS << " -Wno-unused-result"
9
+ # # $CFLAGS << " -Wno-dangling-else"
10
+ # # $CFLAGS << " -Wno-parentheses"
11
+
12
+ # dir_config 'extralite_ext'
13
+ # create_makefile 'extralite_ext'
14
+
15
+ ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
16
+
3
17
  require 'mkmf'
4
18
 
5
- $CFLAGS << " -Wno-undef"
6
- $CFLAGS << " -Wno-discarded-qualifiers"
19
+ # :stopdoc:
20
+
21
+ RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
22
+
23
+ ldflags = cppflags = nil
24
+ if RbConfig::CONFIG["host_os"] =~ /darwin/
25
+ begin
26
+ if with_config('sqlcipher')
27
+ brew_prefix = `brew --prefix sqlcipher`.chomp
28
+ ldflags = "#{brew_prefix}/lib"
29
+ cppflags = "#{brew_prefix}/include/sqlcipher"
30
+ pkg_conf = "#{brew_prefix}/lib/pkgconfig"
31
+ else
32
+ brew_prefix = `brew --prefix sqlite3`.chomp
33
+ ldflags = "#{brew_prefix}/lib"
34
+ cppflags = "#{brew_prefix}/include"
35
+ pkg_conf = "#{brew_prefix}/lib/pkgconfig"
36
+ end
37
+
38
+ # pkg_config should be less error prone than parsing compiler
39
+ # commandline options, but we need to set default ldflags and cpp flags
40
+ # in case the user doesn't have pkg-config installed
41
+ ENV['PKG_CONFIG_PATH'] ||= pkg_conf
42
+ rescue
43
+ end
44
+ end
45
+
46
+ if with_config('sqlcipher')
47
+ pkg_config("sqlcipher")
48
+ else
49
+ pkg_config("sqlite3")
50
+ end
51
+
52
+ # --with-sqlite3-{dir,include,lib}
53
+ if with_config('sqlcipher')
54
+ $CFLAGS << ' -DUSING_SQLCIPHER'
55
+ dir_config("sqlcipher", cppflags, ldflags)
56
+ else
57
+ dir_config("sqlite3", cppflags, ldflags)
58
+ end
59
+
60
+ if RbConfig::CONFIG["host_os"] =~ /mswin/
61
+ $CFLAGS << ' -W3'
62
+ end
63
+
64
+ if RUBY_VERSION < '2.7'
65
+ $CFLAGS << ' -DTAINTING_SUPPORT'
66
+ end
67
+
68
+ def asplode missing
69
+ if RUBY_PLATFORM =~ /mingw|mswin/
70
+ abort "#{missing} is missing. Install SQLite3 from " +
71
+ "http://www.sqlite.org/ first."
72
+ else
73
+ abort <<-error
74
+ #{missing} is missing. Try 'brew install sqlite3',
75
+ 'yum install sqlite-devel' or 'apt-get install libsqlite3-dev'
76
+ and check your shared library search path (the
77
+ location where your sqlite3 shared library is located).
78
+ error
79
+ end
80
+ end
81
+
82
+ asplode('sqlite3.h') unless find_header 'sqlite3.h'
83
+ find_library 'pthread', 'pthread_create' # 1.8 support. *shrug*
84
+
85
+ have_library 'dl' # for static builds
86
+
87
+ if with_config('sqlcipher')
88
+ asplode('sqlcipher') unless find_library 'sqlcipher', 'sqlite3_libversion_number'
89
+ else
90
+ asplode('sqlite3') unless find_library 'sqlite3', 'sqlite3_libversion_number'
91
+ end
92
+
93
+ # Functions defined in 1.9 but not 1.8
94
+ have_func('rb_proc_arity')
95
+
96
+ # Functions defined in 2.1 but not 2.0
97
+ have_func('rb_integer_pack')
98
+
99
+ # These functions may not be defined
100
+ have_func('sqlite3_initialize')
101
+ have_func('sqlite3_enable_load_extension')
102
+ have_func('sqlite3_load_extension')
103
+
104
+ unless have_func('sqlite3_open_v2')
105
+ abort "Please use a newer version of SQLite3"
106
+ end
107
+
108
+ have_func('sqlite3_prepare_v2')
109
+ have_type('sqlite3_int64', 'sqlite3.h')
110
+ have_type('sqlite3_uint64', 'sqlite3.h')
111
+
112
+ $defs << "-DEXTRALITE_NO_BUNDLE"
7
113
 
8
114
  dir_config('extralite_ext')
9
115
  create_makefile('extralite_ext')
@@ -3,7 +3,12 @@
3
3
 
4
4
  #include "ruby.h"
5
5
  #include "ruby/thread.h"
6
+
7
+ #ifdef EXTRALITE_NO_BUNDLE
6
8
  #include <sqlite3.h>
9
+ #else
10
+ #include "../sqlite3/sqlite3.h"
11
+ #endif
7
12
 
8
13
  // debug utility
9
14
  #define INSPECT(str, obj) { \
@@ -48,6 +53,7 @@ VALUE safe_query_hash(query_ctx *ctx);
48
53
  VALUE safe_query_single_column(query_ctx *ctx);
49
54
  VALUE safe_query_single_row(query_ctx *ctx);
50
55
  VALUE safe_query_single_value(query_ctx *ctx);
56
+ VALUE safe_query_columns(query_ctx *ctx);
51
57
 
52
58
  void prepare_single_stmt(sqlite3 *db, sqlite3_stmt **stmt, VALUE sql);
53
59
  void prepare_multi_stmt(sqlite3 *db, sqlite3_stmt **stmt, VALUE sql);
@@ -0,0 +1,3 @@
1
+ #ifndef EXTRALITE_NO_BUNDLE
2
+ #include "../sqlite3/sqlite3.c"
3
+ #endif
@@ -63,6 +63,9 @@ static inline VALUE PreparedStatement_perform_query(int argc, VALUE *argv, VALUE
63
63
  PreparedStatement_t *stmt;
64
64
  GetPreparedStatement(self, stmt);
65
65
 
66
+ if (!stmt->stmt)
67
+ rb_raise(cError, "Prepared statement is closed");
68
+
66
69
  sqlite3_reset(stmt->stmt);
67
70
  sqlite3_clear_bindings(stmt->stmt);
68
71
  bind_all_parameters(stmt->stmt, argc, argv);
@@ -218,6 +221,43 @@ VALUE PreparedStatement_sql(VALUE self) {
218
221
  return stmt->sql;
219
222
  }
220
223
 
224
+ /* call-seq:
225
+ * stmt.columns -> columns
226
+ *
227
+ * Returns the column names for the prepared statement without running it.
228
+ */
229
+ VALUE PreparedStatement_columns(VALUE self) {
230
+ return PreparedStatement_perform_query(0, NULL, self, safe_query_columns);
231
+ }
232
+
233
+ /* call-seq:
234
+ * stmt.close -> stmt
235
+ *
236
+ * Closes the prepared statement. Running a closed prepared statement will raise
237
+ * an error.
238
+ */
239
+ VALUE PreparedStatement_close(VALUE self) {
240
+ PreparedStatement_t *stmt;
241
+ GetPreparedStatement(self, stmt);
242
+ if (stmt->stmt) {
243
+ sqlite3_finalize(stmt->stmt);
244
+ stmt->stmt = NULL;
245
+ }
246
+ return self;
247
+ }
248
+
249
+ /* call-seq:
250
+ * stmt.closed? -> closed
251
+ *
252
+ * Returns true if the prepared statement is closed.
253
+ */
254
+ VALUE PreparedStatement_closed_p(VALUE self) {
255
+ PreparedStatement_t *stmt;
256
+ GetPreparedStatement(self, stmt);
257
+
258
+ return stmt->stmt ? Qfalse : Qtrue;
259
+ }
260
+
221
261
  void Init_ExtralitePreparedStatement() {
222
262
  VALUE mExtralite = rb_define_module("Extralite");
223
263
 
@@ -235,4 +275,9 @@ void Init_ExtralitePreparedStatement() {
235
275
  rb_define_method(cPreparedStatement, "query_single_row", PreparedStatement_query_single_row, -1);
236
276
  rb_define_method(cPreparedStatement, "query_single_column", PreparedStatement_query_single_column, -1);
237
277
  rb_define_method(cPreparedStatement, "query_single_value", PreparedStatement_query_single_value, -1);
278
+
279
+ rb_define_method(cPreparedStatement, "columns", PreparedStatement_columns, 0);
280
+
281
+ rb_define_method(cPreparedStatement, "close", PreparedStatement_close, 0);
282
+ rb_define_method(cPreparedStatement, "closed?", PreparedStatement_closed_p, 0);
238
283
  }
File without changes
File without changes
@@ -0,0 +1,8 @@
1
+ require_relative './gemspec'
2
+
3
+ Gem::Specification.new do |s|
4
+ common_spec(s)
5
+ s.name = 'extralite-bundle'
6
+ s.summary = 'Extra-lightweight SQLite3 wrapper for Ruby with bundled SQLite3'
7
+ s.extensions = ["ext/extralite/extconf-bundle.rb"]
8
+ end
data/extralite.gemspec CHANGED
@@ -1,30 +1,8 @@
1
- require_relative './lib/extralite/version'
1
+ require_relative './gemspec'
2
2
 
3
3
  Gem::Specification.new do |s|
4
+ common_spec(s)
4
5
  s.name = 'extralite'
5
- s.version = Extralite::VERSION
6
- s.licenses = ['MIT']
7
6
  s.summary = 'Extra-lightweight SQLite3 wrapper for Ruby'
8
- s.author = 'Sharon Rosner'
9
- s.email = 'sharon@noteflakes.com'
10
- s.files = `git ls-files`.split
11
- s.homepage = 'https://github.com/digital-fabric/extralite'
12
- s.metadata = {
13
- "source_code_uri" => "https://github.com/digital-fabric/extralite",
14
- "documentation_uri" => "https://www.rubydoc.info/gems/extralite",
15
- "homepage_uri" => "https://github.com/digital-fabric/extralite",
16
- "changelog_uri" => "https://github.com/digital-fabric/extralite/blob/master/CHANGELOG.md"
17
- }
18
- s.rdoc_options = ["--title", "extralite", "--main", "README.md"]
19
- s.extra_rdoc_files = ["README.md"]
20
- s.extensions = ["ext/extralite/extconf.rb"]
21
- s.require_paths = ["lib"]
22
- s.required_ruby_version = '>= 2.7'
23
-
24
- s.add_development_dependency 'rake-compiler', '1.1.6'
25
- s.add_development_dependency 'minitest', '5.15.0'
26
- s.add_development_dependency 'simplecov', '0.17.1'
27
- s.add_development_dependency 'yard', '0.9.27'
28
-
29
- s.add_development_dependency 'sequel', '5.51.0'
7
+ s.extensions = ["ext/extralite/extconf.rb"]
30
8
  end
data/gemspec.rb ADDED
@@ -0,0 +1,26 @@
1
+ require_relative './lib/extralite/version'
2
+
3
+ def common_spec(s)
4
+ s.version = Extralite::VERSION
5
+ s.licenses = ['MIT']
6
+ s.author = 'Sharon Rosner'
7
+ s.email = 'sharon@noteflakes.com'
8
+ s.files = `git ls-files`.split
9
+ s.homepage = 'https://github.com/digital-fabric/extralite'
10
+ s.metadata = {
11
+ "source_code_uri" => "https://github.com/digital-fabric/extralite",
12
+ "documentation_uri" => "https://www.rubydoc.info/gems/extralite",
13
+ "homepage_uri" => "https://github.com/digital-fabric/extralite",
14
+ "changelog_uri" => "https://github.com/digital-fabric/extralite/blob/master/CHANGELOG.md"
15
+ }
16
+ s.rdoc_options = ["--title", "extralite", "--main", "README.md"]
17
+ s.extra_rdoc_files = ["README.md"]
18
+ s.require_paths = ["lib"]
19
+ s.required_ruby_version = '>= 2.7'
20
+
21
+ s.add_development_dependency 'rake-compiler', '1.1.6'
22
+ s.add_development_dependency 'minitest', '5.15.0'
23
+ s.add_development_dependency 'simplecov', '0.17.1'
24
+ s.add_development_dependency 'yard', '0.9.27'
25
+ s.add_development_dependency 'sequel', '5.51.0'
26
+ end
@@ -1,3 +1,3 @@
1
1
  module Extralite
2
- VERSION = '1.13.1'
2
+ VERSION = '1.15'
3
3
  end
data/lib/extralite.rb CHANGED
@@ -17,5 +17,29 @@ module Extralite
17
17
 
18
18
  # An SQLite database
19
19
  class Database
20
+ alias_method :execute, :query
21
+
22
+ TABLES_SQL = <<~SQL
23
+ SELECT name FROM sqlite_schema
24
+ WHERE type ='table'
25
+ AND name NOT LIKE 'sqlite_%';
26
+ SQL
27
+
28
+ def tables
29
+ query_single_column(TABLES_SQL)
30
+ end
31
+
32
+ def pragma(value)
33
+ value.is_a?(Hash) ? pragma_set(value) : pragma_get(value)
34
+ end
35
+
36
+ def pragma_set(values)
37
+ sql = values.inject(+'') { |s, (k, v)| s += "pragma #{k}=#{v}; " }
38
+ query(sql)
39
+ end
40
+
41
+ def pragma_get(key)
42
+ query_single_value("pragma #{key}")
43
+ end
20
44
  end
21
- end
45
+ end
@@ -122,17 +122,17 @@ module Sequel
122
122
 
123
123
  connection_pragmas.each{|s| log_connection_yield(s, db){db.query(s)}}
124
124
 
125
- # class << db
126
- # attr_reader :prepared_statements
127
- # end
128
- # db.instance_variable_set(:@prepared_statements, {})
125
+ class << db
126
+ attr_reader :prepared_statements
127
+ end
128
+ db.instance_variable_set(:@prepared_statements, {})
129
129
 
130
130
  db
131
131
  end
132
132
 
133
133
  # Disconnect given connections from the database.
134
134
  def disconnect_connection(c)
135
- # c.prepared_statements.each_value{|v| v.first.close}
135
+ c.prepared_statements.each_value{|v| v.first.close }
136
136
  c.close
137
137
  end
138
138
 
@@ -149,13 +149,13 @@ module Sequel
149
149
  # Drop any prepared statements on the connection when executing DDL. This is because
150
150
  # prepared statements lock the table in such a way that you can't drop or alter the
151
151
  # table while a prepared statement that references it still exists.
152
- # def execute_ddl(sql, opts=OPTS)
153
- # synchronize(opts[:server]) do |conn|
154
- # conn.prepared_statements.values.each{|cps, s| cps.close}
155
- # conn.prepared_statements.clear
156
- # super
157
- # end
158
- # end
152
+ def execute_ddl(sql, opts=OPTS)
153
+ synchronize(opts[:server]) do |conn|
154
+ conn.prepared_statements.values.each{|cps, s| cps.close}
155
+ conn.prepared_statements.clear
156
+ super
157
+ end
158
+ end
159
159
 
160
160
  def execute_insert(sql, opts=OPTS)
161
161
  _execute(:insert, sql, opts)
@@ -193,7 +193,7 @@ module Sequel
193
193
  def _execute(type, sql, opts, &block)
194
194
  begin
195
195
  synchronize(opts[:server]) do |conn|
196
- # return execute_prepared_statement(conn, type, sql, opts, &block) if sql.is_a?(Symbol)
196
+ return execute_prepared_statement(conn, type, sql, opts, &block) if sql.is_a?(Symbol)
197
197
  log_args = opts[:arguments]
198
198
  args = {}
199
199
  opts.fetch(:arguments, OPTS).each{|k, v| args[k] = prepared_statement_argument(v) }
data/test/helper.rb CHANGED
@@ -4,4 +4,4 @@ require 'bundler/setup'
4
4
  require 'extralite'
5
5
  require 'minitest/autorun'
6
6
 
7
- puts "sqlite3 version: #{Extralite.sqlite3_version}"
7
+ puts "sqlite3 version: #{Extralite.sqlite3_version}"
@@ -68,6 +68,11 @@ end
68
68
  assert_nil r
69
69
  end
70
70
 
71
+ def test_columns
72
+ r = @db.columns('select x, z from t')
73
+ assert_equal [:x, :z], r
74
+ end
75
+
71
76
  def test_transaction_active?
72
77
  assert_equal false, @db.transaction_active?
73
78
  @db.query('begin')
@@ -177,6 +182,31 @@ end
177
182
  r = @db.query_single_value("select reverse('abcd')")
178
183
  assert_equal 'dcba', r
179
184
  end
185
+
186
+ def test_tables
187
+ assert_equal ['t'], @db.tables
188
+
189
+ @db.query('create table foo (bar text)')
190
+ assert_equal ['t', 'foo'], @db.tables
191
+
192
+ @db.query('drop table t')
193
+ assert_equal ['foo'], @db.tables
194
+
195
+ @db.query('drop table foo')
196
+ assert_equal [], @db.tables
197
+ end
198
+
199
+ def test_pragma
200
+ assert_equal 'memory', @db.pragma('journal_mode')
201
+ assert_equal 2, @db.pragma('synchronous')
202
+
203
+ assert_equal 1, @db.pragma(:schema_version)
204
+ assert_equal 0, @db.pragma(:recursive_triggers)
205
+
206
+ assert_equal [], @db.pragma(schema_version: 33, recursive_triggers: 1)
207
+ assert_equal 33, @db.pragma(:schema_version)
208
+ assert_equal 1, @db.pragma(:recursive_triggers)
209
+ end
180
210
  end
181
211
 
182
212
  class ScenarioTest < MiniTest::Test
@@ -3,12 +3,7 @@
3
3
  require_relative 'helper'
4
4
 
5
5
  class ExtraliteTest < MiniTest::Test
6
- SQLITE3_C_PATH = File.expand_path('../ext/extralite/sqlite3.c', __dir__)
7
- SQLITE_VERSION_DEFINE_REGEXP = /#define SQLITE_VERSION\s+"([\d\.]+)"/m.freeze
8
-
9
6
  def test_sqlite3_version
10
- version = IO.read(SQLITE3_C_PATH).match(SQLITE_VERSION_DEFINE_REGEXP)[1]
11
-
12
- assert_equal version, Extralite.sqlite3_version
7
+ assert_match /^3\.\d+\.\d+$/, Extralite.sqlite3_version
13
8
  end
14
9
  end
@@ -162,4 +162,23 @@ end
162
162
  r = @db.prepare('select null').query_single_value
163
163
  assert_nil r
164
164
  end
165
+
166
+ def test_prepared_statement_columns
167
+ r = @db.prepare("select 'abc' as a, 'def' as b").columns
168
+ assert_equal [:a, :b], r
169
+ end
170
+
171
+ def test_prepared_statement_close
172
+ p = @db.prepare("select 'abc'")
173
+
174
+ assert_equal false, p.closed?
175
+
176
+ p.close
177
+ assert_equal true, p.closed?
178
+
179
+ p.close
180
+ assert_equal true, p.closed?
181
+
182
+ assert_raises { p.query_single_value }
183
+ end
165
184
  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.13.1
4
+ version: '1.15'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sharon Rosner
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-27 00:00:00.000000000 Z
11
+ date: 2022-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake-compiler
@@ -80,7 +80,7 @@ dependencies:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
82
  version: 5.51.0
83
- description:
83
+ description:
84
84
  email: sharon@noteflakes.com
85
85
  executables: []
86
86
  extensions:
@@ -101,13 +101,17 @@ files:
101
101
  - bin/update_sqlite_source
102
102
  - ext/extralite/common.c
103
103
  - ext/extralite/database.c
104
+ - ext/extralite/extconf-bundle.rb
104
105
  - ext/extralite/extconf.rb
105
106
  - ext/extralite/extralite.h
106
107
  - ext/extralite/extralite_ext.c
108
+ - ext/extralite/extralite_sqlite3.c
107
109
  - ext/extralite/prepared_statement.c
108
- - ext/extralite/sqlite3.c
109
- - ext/extralite/sqlite3.h
110
+ - ext/sqlite3/sqlite3.c
111
+ - ext/sqlite3/sqlite3.h
112
+ - extralite-bundle.gemspec
110
113
  - extralite.gemspec
114
+ - gemspec.rb
111
115
  - lib/extralite.rb
112
116
  - lib/extralite/version.rb
113
117
  - lib/sequel/adapters/extralite.rb
@@ -130,7 +134,7 @@ metadata:
130
134
  documentation_uri: https://www.rubydoc.info/gems/extralite
131
135
  homepage_uri: https://github.com/digital-fabric/extralite
132
136
  changelog_uri: https://github.com/digital-fabric/extralite/blob/master/CHANGELOG.md
133
- post_install_message:
137
+ post_install_message:
134
138
  rdoc_options:
135
139
  - "--title"
136
140
  - extralite
@@ -149,8 +153,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
153
  - !ruby/object:Gem::Version
150
154
  version: '0'
151
155
  requirements: []
152
- rubygems_version: 3.3.3
153
- signing_key:
156
+ rubygems_version: 3.3.7
157
+ signing_key:
154
158
  specification_version: 4
155
159
  summary: Extra-lightweight SQLite3 wrapper for Ruby
156
160
  test_files: []