sqlite3 0.0.3 → 0.0.4
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.
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/sqlite3.rb +0 -7
- data/lib/sqlite3/constants.rb +7 -7
- data/lib/sqlite3/database.rb +35 -35
- data/lib/sqlite3/driver/ffi/api.rb +1 -1
- data/lib/sqlite3/driver/ffi/driver.rb +1 -1
- data/lib/sqlite3/resultset.rb +6 -6
- data/test/test_active_record.rb +93 -0
- metadata +14 -5
- data/lib/sqlite3/translator.rb +0 -106
- data/lib/sqlite3/value.rb +0 -60
- data/lib/sqlite3/version.rb +0 -14
data/Rakefile
CHANGED
@@ -14,6 +14,7 @@ begin
|
|
14
14
|
gem.authors = ["Jakub Kuźma"]
|
15
15
|
gem.add_dependency "ffi", ">= 0.5.1"
|
16
16
|
gem.add_development_dependency "test-unit", ">= 2.0"
|
17
|
+
gem.add_development_dependency "activerecord", ">= 2.3.5"
|
17
18
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
18
19
|
gem.post_install_message = <<-EOM
|
19
20
|
==== WARNING ===================================================================
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|
data/lib/sqlite3.rb
CHANGED
@@ -1,16 +1,9 @@
|
|
1
|
-
# start (required by translator)
|
2
|
-
require "time"
|
3
|
-
require "date"
|
4
|
-
# end
|
5
|
-
|
6
1
|
require "ffi"
|
7
2
|
|
8
3
|
require "sqlite3/constants"
|
9
4
|
require "sqlite3/errors"
|
10
5
|
require "sqlite3/pragmas"
|
11
6
|
require "sqlite3/statement"
|
12
|
-
require "sqlite3/translator"
|
13
7
|
require "sqlite3/resultset"
|
14
|
-
require "sqlite3/value"
|
15
8
|
require "sqlite3/encoding"
|
16
9
|
require "sqlite3/database"
|
data/lib/sqlite3/constants.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
module SQLite3
|
2
2
|
module Constants
|
3
3
|
|
4
|
-
module TextRep
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
4
|
+
# module TextRep
|
5
|
+
# UTF8 = 1
|
6
|
+
# UTF16LE = 2
|
7
|
+
# UTF16BE = 3
|
8
|
+
# UTF16 = 4
|
9
|
+
# ANY = 5
|
10
|
+
# end
|
11
11
|
|
12
12
|
module ColumnType
|
13
13
|
INTEGER = 1
|
data/lib/sqlite3/database.rb
CHANGED
@@ -55,7 +55,7 @@ module SQLite3
|
|
55
55
|
|
56
56
|
# A boolean indicating whether or not type translation is enabled for this
|
57
57
|
# database.
|
58
|
-
attr_accessor :type_translation
|
58
|
+
# attr_accessor :type_translation
|
59
59
|
|
60
60
|
# Encoding used to comunicate with database.
|
61
61
|
attr_reader :encoding
|
@@ -77,9 +77,9 @@ module SQLite3
|
|
77
77
|
|
78
78
|
@closed = false
|
79
79
|
@results_as_hash = options.fetch(:results_as_hash, false)
|
80
|
-
@type_translation = options.fetch(:type_translation, false)
|
81
|
-
@translator = nil
|
82
|
-
@transaction_active = false
|
80
|
+
# @type_translation = options.fetch(:type_translation, false)
|
81
|
+
# @translator = nil
|
82
|
+
# @transaction_active = false
|
83
83
|
end
|
84
84
|
|
85
85
|
# Return +true+ if the string is a valid (ie, parsable) SQL statement, and
|
@@ -106,9 +106,9 @@ module SQLite3
|
|
106
106
|
# instances. Furthermore, the translators are instantiated lazily, so that
|
107
107
|
# if a database does not use type translation, it will not be burdened by
|
108
108
|
# the overhead of a useless type translator. (See the Translator class.)
|
109
|
-
def translator
|
110
|
-
|
111
|
-
end
|
109
|
+
# def translator
|
110
|
+
# @translator ||= Translator.new
|
111
|
+
# end
|
112
112
|
|
113
113
|
# Closes this database.
|
114
114
|
def close
|
@@ -197,16 +197,16 @@ module SQLite3
|
|
197
197
|
#
|
198
198
|
# This always returns +nil+, making it unsuitable for queries that return
|
199
199
|
# rows.
|
200
|
-
def execute_batch(sql, *bind_vars)
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
end
|
200
|
+
# def execute_batch(sql, *bind_vars)
|
201
|
+
# sql = sql.strip
|
202
|
+
# until sql.empty? do
|
203
|
+
# prepare(sql) do |stmt|
|
204
|
+
# stmt.execute(*bind_vars)
|
205
|
+
# sql = stmt.remainder.strip
|
206
|
+
# end
|
207
|
+
# end
|
208
|
+
# nil
|
209
|
+
# end
|
210
210
|
|
211
211
|
# This is a convenience method for creating a statement, binding
|
212
212
|
# paramters to it, and calling execute:
|
@@ -219,18 +219,18 @@ module SQLite3
|
|
219
219
|
# returned, or you could have problems with locks on the table. If called
|
220
220
|
# with a block, +close+ will be invoked implicitly when the block
|
221
221
|
# terminates.
|
222
|
-
def query(sql, *bind_vars)
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
end
|
222
|
+
# def query(sql, *bind_vars)
|
223
|
+
# result = prepare(sql).execute(*bind_vars)
|
224
|
+
# if block_given?
|
225
|
+
# begin
|
226
|
+
# yield result
|
227
|
+
# ensure
|
228
|
+
# result.close
|
229
|
+
# end
|
230
|
+
# else
|
231
|
+
# return result
|
232
|
+
# end
|
233
|
+
# end
|
234
234
|
|
235
235
|
# A convenience method for obtaining the first row of a result set, and
|
236
236
|
# discarding all others. It is otherwise identical to #execute.
|
@@ -266,14 +266,14 @@ module SQLite3
|
|
266
266
|
|
267
267
|
# Returns the total number of changes made to this database instance
|
268
268
|
# since it was opened.
|
269
|
-
def total_changes
|
270
|
-
|
271
|
-
end
|
269
|
+
# def total_changes
|
270
|
+
# @driver.total_changes(@handle)
|
271
|
+
# end
|
272
272
|
|
273
273
|
# Interrupts the currently executing operation, causing it to abort.
|
274
|
-
def interrupt
|
275
|
-
|
276
|
-
end
|
274
|
+
# def interrupt
|
275
|
+
# @driver.interrupt(@handle)
|
276
|
+
# end
|
277
277
|
|
278
278
|
# Indicates that if a request for a resource terminates because that
|
279
279
|
# resource is busy, SQLite should sleep and retry for up to the indicated
|
@@ -38,7 +38,7 @@ EOF
|
|
38
38
|
# attach_function :sqlite3_reset, [:pointer], :int
|
39
39
|
attach_function :sqlite3_step, [:pointer], :int
|
40
40
|
attach_function :sqlite3_last_insert_rowid, [:pointer], :int64
|
41
|
-
|
41
|
+
attach_function :sqlite3_changes, [:pointer], :int
|
42
42
|
# attach_function :sqlite3_total_changes, [:pointer], :int
|
43
43
|
# attach_function :sqlite3_interrupt, [:pointer], :void
|
44
44
|
# attach_function :sqlite3_complete, [:string], :int
|
@@ -146,7 +146,7 @@ module SQLite3
|
|
146
146
|
api_delegate :bind_parameter_index
|
147
147
|
api_delegate :bind_parameter_name
|
148
148
|
api_delegate :busy_timeout
|
149
|
-
|
149
|
+
api_delegate :changes
|
150
150
|
api_delegate :close
|
151
151
|
# api_delegate :column_bytes
|
152
152
|
# api_delegate :column_bytes16
|
data/lib/sqlite3/resultset.rb
CHANGED
@@ -114,11 +114,11 @@ module SQLite3
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
|
-
if @db.type_translation
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
end
|
117
|
+
# if @db.type_translation
|
118
|
+
# row = @stmt.types.zip(row).map do |type, value|
|
119
|
+
# @db.translator.translate(type, value)
|
120
|
+
# end
|
121
|
+
# end
|
122
122
|
|
123
123
|
if @db.results_as_hash
|
124
124
|
new_row = HashWithTypes[ *(@stmt.columns.zip(row).to_a.flatten) ]
|
@@ -133,7 +133,7 @@ module SQLite3
|
|
133
133
|
row.fields = @stmt.columns
|
134
134
|
end
|
135
135
|
|
136
|
-
row.types = @stmt.types
|
136
|
+
# row.types = @stmt.types
|
137
137
|
|
138
138
|
return row
|
139
139
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require "helper"
|
2
|
+
require "active_record"
|
3
|
+
|
4
|
+
class CreateUsers < ActiveRecord::Migration
|
5
|
+
def self.up
|
6
|
+
create_table :users do |t|
|
7
|
+
t.string :login
|
8
|
+
t.integer :login_count
|
9
|
+
t.binary :avatar
|
10
|
+
t.float :ranking
|
11
|
+
t.date :birthdate
|
12
|
+
t.boolean :active
|
13
|
+
t.datetime :expires_at
|
14
|
+
t.text :about_me
|
15
|
+
t.timestamps
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.down
|
20
|
+
drop_table :users
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class User < ActiveRecord::Base
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
class TestActiveRecord < Test::Unit::TestCase
|
29
|
+
def setup
|
30
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
31
|
+
ActiveRecord::Base.default_timezone = :utc
|
32
|
+
CreateUsers.migrate(:up)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_user_count
|
36
|
+
assert_equal 0, User.count
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_user_columns
|
40
|
+
column_names = User.column_names
|
41
|
+
assert column_names.include?("id")
|
42
|
+
assert column_names.include?("login")
|
43
|
+
assert column_names.include?("login_count")
|
44
|
+
assert column_names.include?("avatar")
|
45
|
+
assert column_names.include?("ranking")
|
46
|
+
assert column_names.include?("birthdate")
|
47
|
+
assert column_names.include?("active")
|
48
|
+
assert column_names.include?("expires_at")
|
49
|
+
assert column_names.include?("about_me")
|
50
|
+
assert column_names.include?("created_at")
|
51
|
+
assert column_names.include?("updated_at")
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_user_create
|
55
|
+
login = "bob"
|
56
|
+
avatar = open("test/fixtures/SQLite.gif", "rb").read
|
57
|
+
login_count = 0
|
58
|
+
ranking = 1.0
|
59
|
+
active = true
|
60
|
+
birthdate = Date.new(1969, 12, 1)
|
61
|
+
expires_at = DateTime.new(2100, 12, 1, 12, 54, 22)
|
62
|
+
about_me = "aboutme" * 500
|
63
|
+
|
64
|
+
User.create!(:login => login,
|
65
|
+
:login_count => login_count,
|
66
|
+
:avatar => avatar,
|
67
|
+
:ranking => ranking,
|
68
|
+
:active => active,
|
69
|
+
:birthdate => birthdate,
|
70
|
+
:expires_at => expires_at,
|
71
|
+
:about_me => about_me)
|
72
|
+
|
73
|
+
user = User.first
|
74
|
+
|
75
|
+
assert_equal login, user.login
|
76
|
+
assert_equal login_count, user.login_count
|
77
|
+
assert_equal avatar, user.avatar
|
78
|
+
assert_equal ranking, user.ranking
|
79
|
+
assert_equal active, user.active
|
80
|
+
assert_equal birthdate, user.birthdate
|
81
|
+
assert_equal expires_at, user.expires_at
|
82
|
+
assert_equal about_me, user.about_me
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_user_update
|
86
|
+
User.create!(:login => "bob")
|
87
|
+
user = User.first
|
88
|
+
assert_equal "bob", user.login
|
89
|
+
user.update_attributes(:login => "alice")
|
90
|
+
user = User.first
|
91
|
+
assert_equal "alice", user.login
|
92
|
+
end
|
93
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqlite3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Jakub Ku\xC5\xBAma"
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-12-09 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -32,6 +32,16 @@ dependencies:
|
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: "2.0"
|
34
34
|
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: activerecord
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.3.5
|
44
|
+
version:
|
35
45
|
description: SQLite3/Ruby FFI bindings
|
36
46
|
email: qoobaa@gmail.com
|
37
47
|
executables: []
|
@@ -58,11 +68,9 @@ files:
|
|
58
68
|
- lib/sqlite3/pragmas.rb
|
59
69
|
- lib/sqlite3/resultset.rb
|
60
70
|
- lib/sqlite3/statement.rb
|
61
|
-
- lib/sqlite3/translator.rb
|
62
|
-
- lib/sqlite3/value.rb
|
63
|
-
- lib/sqlite3/version.rb
|
64
71
|
- test/fixtures/SQLite.gif
|
65
72
|
- test/helper.rb
|
73
|
+
- test/test_active_record.rb
|
66
74
|
- test/test_database_initialization.rb
|
67
75
|
- test/test_database_queries_utf_16.rb
|
68
76
|
- test/test_database_queries_utf_8.rb
|
@@ -107,5 +115,6 @@ summary: SQLite3/Ruby FFI bindings
|
|
107
115
|
test_files:
|
108
116
|
- test/test_database_queries_utf_8.rb
|
109
117
|
- test/test_database_queries_utf_16.rb
|
118
|
+
- test/test_active_record.rb
|
110
119
|
- test/test_database_initialization.rb
|
111
120
|
- test/helper.rb
|
data/lib/sqlite3/translator.rb
DELETED
@@ -1,106 +0,0 @@
|
|
1
|
-
module SQLite3
|
2
|
-
|
3
|
-
# The Translator class encapsulates the logic and callbacks necessary for
|
4
|
-
# converting string data to a value of some specified type. Every Database
|
5
|
-
# instance may have a Translator instance, in order to assist in type
|
6
|
-
# translation (Database#type_translation).
|
7
|
-
#
|
8
|
-
# Further, applications may define their own custom type translation logic
|
9
|
-
# by registering translator blocks with the corresponding database's
|
10
|
-
# translator instance (Database#translator).
|
11
|
-
class Translator
|
12
|
-
|
13
|
-
# Create a new Translator instance. It will be preinitialized with default
|
14
|
-
# translators for most SQL data types.
|
15
|
-
def initialize
|
16
|
-
@translators = Hash.new(proc { |type, value| value })
|
17
|
-
@type_name_cache = {}
|
18
|
-
register_default_translators
|
19
|
-
end
|
20
|
-
|
21
|
-
# Add a new translator block, which will be invoked to process type
|
22
|
-
# translations to the given type. The type should be an SQL datatype, and
|
23
|
-
# may include parentheses (i.e., "VARCHAR(30)"). However, any parenthetical
|
24
|
-
# information is stripped off and discarded, so type translation decisions
|
25
|
-
# are made solely on the "base" type name.
|
26
|
-
#
|
27
|
-
# The translator block itself should accept two parameters, "type" and
|
28
|
-
# "value". In this case, the "type" is the full type name (including
|
29
|
-
# parentheses), so the block itself may include logic for changing how a
|
30
|
-
# type is translated based on the additional data. The "value" parameter
|
31
|
-
# is the (string) data to convert.
|
32
|
-
#
|
33
|
-
# The block should return the translated value.
|
34
|
-
def add_translator(type, &block) # :yields: type, value
|
35
|
-
@translators[ type_name(type) ] = block
|
36
|
-
end
|
37
|
-
|
38
|
-
# Translate the given string value to a value of the given type. In the
|
39
|
-
# absense of an installed translator block for the given type, the value
|
40
|
-
# itself is always returned. Further, +nil+ values are never translated,
|
41
|
-
# and are always passed straight through regardless of the type parameter.
|
42
|
-
def translate(type, value)
|
43
|
-
unless value.nil?
|
44
|
-
@translators[ type_name(type) ].call(type, value)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
# A convenience method for working with type names. This returns the "base"
|
49
|
-
# type name, without any parenthetical data.
|
50
|
-
def type_name(type)
|
51
|
-
@type_name_cache[type] ||= begin
|
52
|
-
type = "" if type.nil?
|
53
|
-
type = $1 if type =~ /^(.*?)\(/
|
54
|
-
type.upcase
|
55
|
-
end
|
56
|
-
end
|
57
|
-
private :type_name
|
58
|
-
|
59
|
-
# Register the default translators for the current Translator instance.
|
60
|
-
# This includes translators for most major SQL data types.
|
61
|
-
def register_default_translators
|
62
|
-
[ "time",
|
63
|
-
"timestamp" ].each { |type| add_translator(type) { |t, v| Time.parse(v) } }
|
64
|
-
|
65
|
-
add_translator("date") { |t,v| Date.parse(v) }
|
66
|
-
add_translator("datetime") { |t,v| DateTime.parse(v) }
|
67
|
-
|
68
|
-
[ "decimal",
|
69
|
-
"float",
|
70
|
-
"numeric",
|
71
|
-
"double",
|
72
|
-
"real",
|
73
|
-
"dec",
|
74
|
-
"fixed" ].each { |type| add_translator(type) { |t,v| v.to_f } }
|
75
|
-
|
76
|
-
[ "integer",
|
77
|
-
"smallint",
|
78
|
-
"mediumint",
|
79
|
-
"int",
|
80
|
-
"bigint" ].each { |type| add_translator(type) { |t,v| v.to_i } }
|
81
|
-
|
82
|
-
[ "bit",
|
83
|
-
"bool",
|
84
|
-
"boolean" ].each do |type|
|
85
|
-
add_translator(type) do |t,v|
|
86
|
-
!(v.strip.gsub(/00+/,"0") == "0" ||
|
87
|
-
v.downcase == "false" ||
|
88
|
-
v.downcase == "f" ||
|
89
|
-
v.downcase == "no" ||
|
90
|
-
v.downcase == "n")
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
add_translator("tinyint") do |type, value|
|
95
|
-
if type =~ /\(\s*1\s*\)/
|
96
|
-
value.to_i == 1
|
97
|
-
else
|
98
|
-
value.to_i
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
private :register_default_translators
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
|
-
end
|
data/lib/sqlite3/value.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
module SQLite3
|
2
|
-
|
3
|
-
class Value
|
4
|
-
attr_reader :handle
|
5
|
-
|
6
|
-
def initialize(db, handle)
|
7
|
-
@driver = db.driver
|
8
|
-
@handle = handle
|
9
|
-
end
|
10
|
-
|
11
|
-
def null?
|
12
|
-
type == :null
|
13
|
-
end
|
14
|
-
|
15
|
-
def to_blob
|
16
|
-
@driver.value_blob(@handle)
|
17
|
-
end
|
18
|
-
|
19
|
-
def length(utf16 = false)
|
20
|
-
if utf16
|
21
|
-
@driver.value_bytes16(@handle)
|
22
|
-
else
|
23
|
-
@driver.value_bytes(@handle)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def to_f
|
28
|
-
@driver.value_double(@handle)
|
29
|
-
end
|
30
|
-
|
31
|
-
def to_i
|
32
|
-
@driver.value_int(@handle)
|
33
|
-
end
|
34
|
-
|
35
|
-
def to_int64
|
36
|
-
@driver.value_int64(@handle)
|
37
|
-
end
|
38
|
-
|
39
|
-
def to_s(utf16 = false)
|
40
|
-
@driver.value_text(@handle, utf16)
|
41
|
-
end
|
42
|
-
|
43
|
-
def type
|
44
|
-
case @driver.value_type(@handle)
|
45
|
-
when Constants::ColumnType::INTEGER
|
46
|
-
:int
|
47
|
-
when Constants::ColumnType::FLOAT
|
48
|
-
:float
|
49
|
-
when Constants::ColumnType::TEXT
|
50
|
-
:text
|
51
|
-
when Constants::ColumnType::BLOB
|
52
|
-
:blob
|
53
|
-
when Constants::ColumnType::NULL
|
54
|
-
:null
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|