extralite 2.7.1 → 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/extralite.rb CHANGED
@@ -1,8 +1,163 @@
1
1
  require_relative './extralite_ext'
2
- require_relative './extralite/sqlite3_constants'
3
2
 
4
3
  # Extralite is a Ruby gem for working with SQLite databases
5
4
  module Extralite
5
+ SQLITE_STATUS_MEMORY_USED = 0
6
+ SQLITE_STATUS_PAGECACHE_USED = 1
7
+ SQLITE_STATUS_PAGECACHE_OVERFLOW = 2
8
+ SQLITE_STATUS_SCRATCH_USED = 3
9
+ SQLITE_STATUS_SCRATCH_OVERFLOW = 4
10
+ SQLITE_STATUS_MALLOC_SIZE = 5
11
+ SQLITE_STATUS_PARSER_STACK = 6
12
+ SQLITE_STATUS_PAGECACHE_SIZE = 7
13
+ SQLITE_STATUS_SCRATCH_SIZE = 8
14
+ SQLITE_STATUS_MALLOC_COUNT = 9
15
+
16
+ SQLITE_DBSTATUS_LOOKASIDE_USED = 0
17
+ SQLITE_DBSTATUS_CACHE_USED = 1
18
+ SQLITE_DBSTATUS_SCHEMA_USED = 2
19
+ SQLITE_DBSTATUS_STMT_USED = 3
20
+ SQLITE_DBSTATUS_LOOKASIDE_HIT = 4
21
+ SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE = 5
22
+ SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL = 6
23
+ SQLITE_DBSTATUS_CACHE_HIT = 7
24
+ SQLITE_DBSTATUS_CACHE_MISS = 8
25
+ SQLITE_DBSTATUS_CACHE_WRITE = 9
26
+ SQLITE_DBSTATUS_DEFERRED_FKS = 10
27
+ SQLITE_DBSTATUS_CACHE_USED_SHARED = 11
28
+ SQLITE_DBSTATUS_CACHE_SPILL = 12
29
+
30
+ SQLITE_STMTSTATUS_FULLSCAN_STEP = 1
31
+ SQLITE_STMTSTATUS_SORT = 2
32
+ SQLITE_STMTSTATUS_AUTOINDEX = 3
33
+ SQLITE_STMTSTATUS_VM_STEP = 4
34
+ SQLITE_STMTSTATUS_REPREPARE = 5
35
+ SQLITE_STMTSTATUS_RUN = 6
36
+ SQLITE_STMTSTATUS_FILTER_MISS = 7
37
+ SQLITE_STMTSTATUS_FILTER_HIT = 8
38
+ SQLITE_STMTSTATUS_MEMUSED = 99
39
+
40
+ SQLITE_LIMIT_LENGTH = 0
41
+ SQLITE_LIMIT_SQL_LENGTH = 1
42
+ SQLITE_LIMIT_COLUMN = 2
43
+ SQLITE_LIMIT_EXPR_DEPTH = 3
44
+ SQLITE_LIMIT_COMPOUND_SELECT = 4
45
+ SQLITE_LIMIT_VDBE_OP = 5
46
+ SQLITE_LIMIT_FUNCTION_ARG = 6
47
+ SQLITE_LIMIT_ATTACHED = 7
48
+ SQLITE_LIMIT_LIKE_PATTERN_LENGTH = 8
49
+ SQLITE_LIMIT_VARIABLE_NUMBER = 9
50
+ SQLITE_LIMIT_TRIGGER_DEPTH = 10
51
+ SQLITE_LIMIT_WORKER_THREADS = 11
52
+
53
+ SQLITE_OK = 0
54
+ SQLITE_ERROR = 1
55
+ SQLITE_INTERNAL = 2
56
+ SQLITE_PERM = 3
57
+ SQLITE_ABORT = 4
58
+ SQLITE_BUSY = 5
59
+ SQLITE_LOCKED = 6
60
+ SQLITE_NOMEM = 7
61
+ SQLITE_READONLY = 8
62
+ SQLITE_INTERRUPT = 9
63
+ SQLITE_IOERR = 10
64
+ SQLITE_CORRUPT = 11
65
+ SQLITE_NOTFOUND = 12
66
+ SQLITE_FULL = 13
67
+ SQLITE_CANTOPEN = 14
68
+ SQLITE_PROTOCOL = 15
69
+ SQLITE_EMPTY = 16
70
+ SQLITE_SCHEMA = 17
71
+ SQLITE_TOOBIG = 18
72
+ SQLITE_CONSTRAINT = 19
73
+ SQLITE_MISMATCH = 20
74
+ SQLITE_MISUSE = 21
75
+ SQLITE_NOLFS = 22
76
+ SQLITE_AUTH = 23
77
+ SQLITE_FORMAT = 24
78
+ SQLITE_RANGE = 25
79
+ SQLITE_NOTADB = 26
80
+ SQLITE_NOTICE = 27
81
+ SQLITE_WARNING = 28
82
+ SQLITE_ROW = 100
83
+ SQLITE_DONE = 101
84
+
85
+ SQLITE_ERROR_MISSING_COLLSEQ = (SQLITE_ERROR | (1<<8))
86
+ SQLITE_ERROR_RETRY = (SQLITE_ERROR | (2<<8))
87
+ SQLITE_ERROR_SNAPSHOT = (SQLITE_ERROR | (3<<8))
88
+ SQLITE_IOERR_READ = (SQLITE_IOERR | (1<<8))
89
+ SQLITE_IOERR_SHORT_READ = (SQLITE_IOERR | (2<<8))
90
+ SQLITE_IOERR_WRITE = (SQLITE_IOERR | (3<<8))
91
+ SQLITE_IOERR_FSYNC = (SQLITE_IOERR | (4<<8))
92
+ SQLITE_IOERR_DIR_FSYNC = (SQLITE_IOERR | (5<<8))
93
+ SQLITE_IOERR_TRUNCATE = (SQLITE_IOERR | (6<<8))
94
+ SQLITE_IOERR_FSTAT = (SQLITE_IOERR | (7<<8))
95
+ SQLITE_IOERR_UNLOCK = (SQLITE_IOERR | (8<<8))
96
+ SQLITE_IOERR_RDLOCK = (SQLITE_IOERR | (9<<8))
97
+ SQLITE_IOERR_DELETE = (SQLITE_IOERR | (10<<8))
98
+ SQLITE_IOERR_BLOCKED = (SQLITE_IOERR | (11<<8))
99
+ SQLITE_IOERR_NOMEM = (SQLITE_IOERR | (12<<8))
100
+ SQLITE_IOERR_ACCESS = (SQLITE_IOERR | (13<<8))
101
+ SQLITE_IOERR_CHECKRESERVEDLOCK = (SQLITE_IOERR | (14<<8))
102
+ SQLITE_IOERR_LOCK = (SQLITE_IOERR | (15<<8))
103
+ SQLITE_IOERR_CLOSE = (SQLITE_IOERR | (16<<8))
104
+ SQLITE_IOERR_DIR_CLOSE = (SQLITE_IOERR | (17<<8))
105
+ SQLITE_IOERR_SHMOPEN = (SQLITE_IOERR | (18<<8))
106
+ SQLITE_IOERR_SHMSIZE = (SQLITE_IOERR | (19<<8))
107
+ SQLITE_IOERR_SHMLOCK = (SQLITE_IOERR | (20<<8))
108
+ SQLITE_IOERR_SHMMAP = (SQLITE_IOERR | (21<<8))
109
+ SQLITE_IOERR_SEEK = (SQLITE_IOERR | (22<<8))
110
+ SQLITE_IOERR_DELETE_NOENT = (SQLITE_IOERR | (23<<8))
111
+ SQLITE_IOERR_MMAP = (SQLITE_IOERR | (24<<8))
112
+ SQLITE_IOERR_GETTEMPPATH = (SQLITE_IOERR | (25<<8))
113
+ SQLITE_IOERR_CONVPATH = (SQLITE_IOERR | (26<<8))
114
+ SQLITE_IOERR_VNODE = (SQLITE_IOERR | (27<<8))
115
+ SQLITE_IOERR_AUTH = (SQLITE_IOERR | (28<<8))
116
+ SQLITE_IOERR_BEGIN_ATOMIC = (SQLITE_IOERR | (29<<8))
117
+ SQLITE_IOERR_COMMIT_ATOMIC = (SQLITE_IOERR | (30<<8))
118
+ SQLITE_IOERR_ROLLBACK_ATOMIC = (SQLITE_IOERR | (31<<8))
119
+ SQLITE_IOERR_DATA = (SQLITE_IOERR | (32<<8))
120
+ SQLITE_IOERR_CORRUPTFS = (SQLITE_IOERR | (33<<8))
121
+ SQLITE_LOCKED_SHAREDCACHE = (SQLITE_LOCKED | (1<<8))
122
+ SQLITE_LOCKED_VTAB = (SQLITE_LOCKED | (2<<8))
123
+ SQLITE_BUSY_RECOVERY = (SQLITE_BUSY | (1<<8))
124
+ SQLITE_BUSY_SNAPSHOT = (SQLITE_BUSY | (2<<8))
125
+ SQLITE_BUSY_TIMEOUT = (SQLITE_BUSY | (3<<8))
126
+ SQLITE_CANTOPEN_NOTEMPDIR = (SQLITE_CANTOPEN | (1<<8))
127
+ SQLITE_CANTOPEN_ISDIR = (SQLITE_CANTOPEN | (2<<8))
128
+ SQLITE_CANTOPEN_FULLPATH = (SQLITE_CANTOPEN | (3<<8))
129
+ SQLITE_CANTOPEN_CONVPATH = (SQLITE_CANTOPEN | (4<<8))
130
+ SQLITE_CANTOPEN_DIRTYWAL = (SQLITE_CANTOPEN | (5<<8))
131
+ SQLITE_CANTOPEN_SYMLINK = (SQLITE_CANTOPEN | (6<<8))
132
+ SQLITE_CORRUPT_VTAB = (SQLITE_CORRUPT | (1<<8))
133
+ SQLITE_CORRUPT_SEQUENCE = (SQLITE_CORRUPT | (2<<8))
134
+ SQLITE_CORRUPT_INDEX = (SQLITE_CORRUPT | (3<<8))
135
+ SQLITE_READONLY_RECOVERY = (SQLITE_READONLY | (1<<8))
136
+ SQLITE_READONLY_CANTLOCK = (SQLITE_READONLY | (2<<8))
137
+ SQLITE_READONLY_ROLLBACK = (SQLITE_READONLY | (3<<8))
138
+ SQLITE_READONLY_DBMOVED = (SQLITE_READONLY | (4<<8))
139
+ SQLITE_READONLY_CANTINIT = (SQLITE_READONLY | (5<<8))
140
+ SQLITE_READONLY_DIRECTORY = (SQLITE_READONLY | (6<<8))
141
+ SQLITE_ABORT_ROLLBACK = (SQLITE_ABORT | (2<<8))
142
+ SQLITE_CONSTRAINT_CHECK = (SQLITE_CONSTRAINT | (1<<8))
143
+ SQLITE_CONSTRAINT_COMMITHOOK = (SQLITE_CONSTRAINT | (2<<8))
144
+ SQLITE_CONSTRAINT_FOREIGNKEY = (SQLITE_CONSTRAINT | (3<<8))
145
+ SQLITE_CONSTRAINT_FUNCTION = (SQLITE_CONSTRAINT | (4<<8))
146
+ SQLITE_CONSTRAINT_NOTNULL = (SQLITE_CONSTRAINT | (5<<8))
147
+ SQLITE_CONSTRAINT_PRIMARYKEY = (SQLITE_CONSTRAINT | (6<<8))
148
+ SQLITE_CONSTRAINT_TRIGGER = (SQLITE_CONSTRAINT | (7<<8))
149
+ SQLITE_CONSTRAINT_UNIQUE = (SQLITE_CONSTRAINT | (8<<8))
150
+ SQLITE_CONSTRAINT_VTAB = (SQLITE_CONSTRAINT | (9<<8))
151
+ SQLITE_CONSTRAINT_ROWID = (SQLITE_CONSTRAINT |(10<<8))
152
+ SQLITE_CONSTRAINT_PINNED = (SQLITE_CONSTRAINT |(11<<8))
153
+ SQLITE_CONSTRAINT_DATATYPE = (SQLITE_CONSTRAINT |(12<<8))
154
+ SQLITE_NOTICE_RECOVER_WAL = (SQLITE_NOTICE | (1<<8))
155
+ SQLITE_NOTICE_RECOVER_ROLLBACK = (SQLITE_NOTICE | (2<<8))
156
+ SQLITE_WARNING_AUTOINDEX = (SQLITE_WARNING | (1<<8))
157
+ SQLITE_AUTH_USER = (SQLITE_AUTH | (1<<8))
158
+ SQLITE_OK_LOAD_PERMANENTLY = (SQLITE_OK | (1<<8))
159
+ SQLITE_OK_SYMLINK = (SQLITE_OK | (2<<8))
160
+
6
161
 
7
162
  # The following error classes are already defined in the C extension. We put
8
163
  # them here for the sake of generating docs.
@@ -45,7 +200,7 @@ module Extralite
45
200
  # @param db [String] name of attached database
46
201
  # @return [Array] list of tables
47
202
  def tables(db = 'main')
48
- query_argv(format(TABLES_SQL, db: db))
203
+ query_splat(format(TABLES_SQL, db: db))
49
204
  end
50
205
 
51
206
  # Gets or sets one or more database pragmas. For a list of available pragmas
@@ -149,7 +304,7 @@ module Extralite
149
304
  end
150
305
 
151
306
  def pragma_get(key)
152
- query_single_argv("pragma #{key}")
307
+ query_single_splat("pragma #{key}")
153
308
  end
154
309
  end
155
310
 
@@ -33,7 +33,7 @@ def sqlite3_run(count)
33
33
  end
34
34
 
35
35
  def extralite_run(count)
36
- results = $extralite_db.query('select * from foo')
36
+ results = $extralite_db.query_array('select * from foo')
37
37
  raise unless results.size == count
38
38
  end
39
39
 
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+ gem 'sqlite3'
8
+ gem 'extralite', path: '..'
9
+ gem 'benchmark-ips'
10
+ end
11
+
12
+ require 'benchmark/ips'
13
+ require 'fileutils'
14
+
15
+ DB_PATH = "/tmp/extralite_sqlite3_perf-#{Time.now.to_i}-#{rand(10000)}.db"
16
+ puts "DB_PATH = #{DB_PATH.inspect}"
17
+
18
+ $sqlite3_db = SQLite3::Database.new(DB_PATH)
19
+ $extralite_db = Extralite::Database.new(DB_PATH, gvl_release_threshold: -1)
20
+
21
+ def prepare_database(count)
22
+ db = Extralite::Database.new(DB_PATH)
23
+ $extralite_db.query('create table if not exists foo ( a integer primary key, b text )')
24
+ $extralite_db.query('delete from foo')
25
+ $extralite_db.query('begin')
26
+ count.times { $extralite_db.query('insert into foo (b) values (?)', "hello#{rand(1000)}" )}
27
+ $extralite_db.query('commit')
28
+ end
29
+
30
+ def sqlite3_run(expected_count)
31
+ count = 0
32
+ $sqlite3_db.execute('select b from foo').each do |row|
33
+ b = row.first
34
+ count += 1
35
+ end
36
+ raise unless count == expected_count
37
+ end
38
+
39
+ def extralite_run(expected_count)
40
+ count = 0
41
+ $extralite_db.query_splat('select * from foo') do |b|
42
+ count += 1
43
+ end
44
+ raise unless count == expected_count
45
+ end
46
+
47
+ [10, 1000, 100000].each do |c|
48
+ puts; puts; puts "Record count: #{c}"
49
+
50
+ prepare_database(c)
51
+
52
+ bm = Benchmark.ips do |x|
53
+ x.config(:time => 5, :warmup => 2)
54
+
55
+ x.report("sqlite3") { sqlite3_run(c) }
56
+ x.report("extralite") { extralite_run(c) }
57
+
58
+ x.compare!
59
+ end
60
+ puts;
61
+ bm.entries.each { |e| puts "#{e.label}: #{(e.ips * c).round.to_i} rows/s" }
62
+ puts;
63
+ end
@@ -38,20 +38,20 @@ end
38
38
 
39
39
  TRANSFORM = ->(b) { { b: b } }
40
40
 
41
- def extralite_run_ary_map(count)
41
+ def extralite_run_array_map(count)
42
42
  results = []
43
- $extralite_db.query_ary('select * from foo') { |(b)| results << { b: b } }
43
+ $extralite_db.query_array('select * from foo') { |(b)| results << { b: b } }
44
44
  raise unless results.size == count
45
45
  end
46
46
 
47
- def extralite_run_argv_map(count)
47
+ def extralite_run_splat_map(count)
48
48
  results = []
49
- $extralite_db.query_argv('select * from foo') { |b| results << { b: b } }
49
+ $extralite_db.query_splat('select * from foo') { |b| results << { b: b } }
50
50
  raise unless results.size == count
51
51
  end
52
52
 
53
53
  def extralite_run_transform(count)
54
- results = $extralite_db.query_argv(TRANSFORM, 'select * from foo')
54
+ results = $extralite_db.query_splat(TRANSFORM, 'select * from foo')
55
55
  raise unless results.size == count
56
56
  end
57
57
 
@@ -62,8 +62,8 @@ end
62
62
  bm = Benchmark.ips do |x|
63
63
  x.config(:time => 5, :warmup => 2)
64
64
 
65
- x.report("ary_map") { extralite_run_ary_map(c) }
66
- x.report("argv_map") { extralite_run_argv_map(c) }
65
+ x.report("array_map") { extralite_run_array_map(c) }
66
+ x.report("splat_map") { extralite_run_splat_map(c) }
67
67
  x.report("transform") { extralite_run_transform(c) }
68
68
 
69
69
  x.compare!