swift 0.4.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.
- data/LICENSE +20 -0
- data/README.rdoc +236 -0
- data/Rakefile +40 -0
- data/VERSION +1 -0
- data/examples/async.rb +60 -0
- data/examples/db.rb +40 -0
- data/examples/scheme.rb +46 -0
- data/ext/extconf.rb +39 -0
- data/ext/swift.cc +756 -0
- data/lib/swift.rb +48 -0
- data/lib/swift/adapter.rb +120 -0
- data/lib/swift/attribute.rb +25 -0
- data/lib/swift/db.rb +39 -0
- data/lib/swift/header.rb +45 -0
- data/lib/swift/identity_map.rb +41 -0
- data/lib/swift/pool.rb +74 -0
- data/lib/swift/scheme.rb +70 -0
- data/lib/swift/type.rb +12 -0
- data/swift.gemspec +75 -0
- data/test/helper.rb +31 -0
- data/test/house-explode.jpg +0 -0
- data/test/test_adapter.rb +127 -0
- data/test/test_encoding.rb +40 -0
- data/test/test_identity_map.rb +17 -0
- data/test/test_io.rb +27 -0
- data/test/test_timestamps.rb +27 -0
- metadata +109 -0
data/lib/swift/type.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
module Swift
|
2
|
+
module Type
|
3
|
+
class BigDecimal < Attribute; end
|
4
|
+
class Boolean < Attribute; end
|
5
|
+
class Float < Attribute; end
|
6
|
+
class Integer < Attribute; end
|
7
|
+
class IO < Attribute; end
|
8
|
+
class String < Attribute; end
|
9
|
+
class Time < Attribute; end
|
10
|
+
end # Type
|
11
|
+
end # Swift
|
12
|
+
|
data/swift.gemspec
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{swift}
|
8
|
+
s.version = "0.4.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Shane Hanna", "Bharanee 'Barney' Rathna"]
|
12
|
+
s.date = %q{2010-08-07}
|
13
|
+
s.description = %q{A rational rudimentary database abstraction.}
|
14
|
+
s.email = ["shane.hanna@gmail.com", "deepfryed@gmail.com"]
|
15
|
+
s.extensions = ["ext/extconf.rb"]
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"LICENSE",
|
18
|
+
"README.rdoc"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"ext/extconf.rb",
|
26
|
+
"ext/swift.cc",
|
27
|
+
"lib/swift.rb",
|
28
|
+
"lib/swift/adapter.rb",
|
29
|
+
"lib/swift/attribute.rb",
|
30
|
+
"lib/swift/db.rb",
|
31
|
+
"lib/swift/header.rb",
|
32
|
+
"lib/swift/identity_map.rb",
|
33
|
+
"lib/swift/pool.rb",
|
34
|
+
"lib/swift/scheme.rb",
|
35
|
+
"lib/swift/type.rb",
|
36
|
+
"swift.gemspec",
|
37
|
+
"test/helper.rb",
|
38
|
+
"test/house-explode.jpg",
|
39
|
+
"test/test_adapter.rb",
|
40
|
+
"test/test_encoding.rb",
|
41
|
+
"test/test_identity_map.rb",
|
42
|
+
"test/test_io.rb",
|
43
|
+
"test/test_timestamps.rb"
|
44
|
+
]
|
45
|
+
s.homepage = %q{http://github.com/shanna/swift}
|
46
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
47
|
+
s.require_paths = ["lib"]
|
48
|
+
s.rubygems_version = %q{1.3.6}
|
49
|
+
s.summary = %q{A rational rudimentary database abstraction.}
|
50
|
+
s.test_files = [
|
51
|
+
"test/test_adapter.rb",
|
52
|
+
"test/test_io.rb",
|
53
|
+
"test/test_encoding.rb",
|
54
|
+
"test/test_timestamps.rb",
|
55
|
+
"test/helper.rb",
|
56
|
+
"test/test_identity_map.rb",
|
57
|
+
"examples/async.rb",
|
58
|
+
"examples/scheme.rb",
|
59
|
+
"examples/db.rb"
|
60
|
+
]
|
61
|
+
|
62
|
+
if s.respond_to? :specification_version then
|
63
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
64
|
+
s.specification_version = 3
|
65
|
+
|
66
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
67
|
+
s.add_development_dependency(%q<minitest>, [">= 1.7.0"])
|
68
|
+
else
|
69
|
+
s.add_dependency(%q<minitest>, [">= 1.7.0"])
|
70
|
+
end
|
71
|
+
else
|
72
|
+
s.add_dependency(%q<minitest>, [">= 1.7.0"])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'minitest/unit'
|
2
|
+
require 'minitest/spec'
|
3
|
+
|
4
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
|
+
require 'swift'
|
7
|
+
|
8
|
+
class MiniTest::Unit::TestCase
|
9
|
+
end
|
10
|
+
|
11
|
+
class MiniTest::Spec
|
12
|
+
def self.supported_by *adapters, &block
|
13
|
+
adapters.each do |adapter|
|
14
|
+
# test if adapter can be loaded.
|
15
|
+
begin
|
16
|
+
Swift.setup :default, adapter, db: 'swift_test'
|
17
|
+
rescue => error
|
18
|
+
warn "Unable to setup 'swift_test' db for #{adapter}, #{error.message}. Skipping..."
|
19
|
+
next
|
20
|
+
end
|
21
|
+
describe("Adapter #{adapter.name}") do
|
22
|
+
before do
|
23
|
+
Swift.setup :default, adapter, db: 'swift_test'
|
24
|
+
end
|
25
|
+
block.call(adapter)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
MiniTest::Unit.autorun
|
Binary file
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
describe 'Adapter' do
|
5
|
+
supported_by Swift::DB::Postgres, Swift::DB::Mysql do
|
6
|
+
describe 'db' do
|
7
|
+
it 'yields db to block' do
|
8
|
+
Swift.db do |db|
|
9
|
+
assert_kind_of Swift::Adapter, db
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe 'execute' do
|
15
|
+
it 'executes without bind values' do
|
16
|
+
assert Swift.db.execute %q{drop table if exists users}
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'executes with bind values' do
|
20
|
+
Swift.db.execute %q{drop table if exists users}
|
21
|
+
Swift.db.execute %q{create table users(id serial, name text, created_at timestamp)}
|
22
|
+
assert Swift.db.execute 'insert into users (name, created_at) values (?, now())', 'Benny Arthurton'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'prepared statements' do
|
27
|
+
before do
|
28
|
+
@db = Swift.db do |db|
|
29
|
+
db.execute %q{drop table if exists users}
|
30
|
+
db.execute %q{create table users(id serial, name text, created_at timestamp)}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'executes without bind values' do
|
35
|
+
assert @db.prepare(%q{insert into users (name, created_at) values ('Apple Arthurton', now())}).execute
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'executes with bind values' do
|
39
|
+
assert @db.prepare(%q{insert into users (name, created_at) values (?, now())}).execute('Apple Arthurton')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'executes multiple times' do
|
43
|
+
sth = @db.prepare(%q{insert into users (name, created_at) values (?, now())})
|
44
|
+
assert sth.execute('Apple Arthurton')
|
45
|
+
assert sth.execute('Benny Arthurton')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'executed prepared statements' do
|
50
|
+
before do
|
51
|
+
@db = Swift.db do |db|
|
52
|
+
db.execute %q{drop table if exists users}
|
53
|
+
db.execute %q{create table users(id serial, name text, created_at timestamp)}
|
54
|
+
sth = db.prepare(%q{insert into users (name, created_at) values (?, now())})
|
55
|
+
sth.execute('Apple Arthurton')
|
56
|
+
sth.execute('Benny Arthurton')
|
57
|
+
end
|
58
|
+
@sth = @db.prepare('select * from users').execute
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'enumerates' do
|
62
|
+
assert_kind_of Enumerable, @sth
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'enumerates block' do
|
66
|
+
begin
|
67
|
+
@sth.execute{|row| row}
|
68
|
+
rescue => error
|
69
|
+
flunk error.message
|
70
|
+
else
|
71
|
+
pass
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'returns hash tuples for enumerable methods' do
|
76
|
+
assert_kind_of Hash, @sth.first
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'returns array rows for fetchrow' do
|
80
|
+
assert_kind_of Array, @sth.fetchrow
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'returns a result set on Adapter#execute{}' do
|
84
|
+
@db.execute('select * from users') {|r| assert_kind_of Hash, r }
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns a result set on Adapter#results' do
|
88
|
+
@db.execute('select * from users')
|
89
|
+
assert_kind_of Swift::ResultSet, @db.results
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'transactions' do
|
94
|
+
it 'yields db to block' do
|
95
|
+
Swift.db.transaction do |db|
|
96
|
+
assert_kind_of Swift::Adapter, db
|
97
|
+
end
|
98
|
+
|
99
|
+
Swift.db.transaction :sweet do |db|
|
100
|
+
assert_kind_of Swift::Adapter, db
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
#--
|
106
|
+
# TODO: Not sure how I feel about the block in write; feels like it's just there to get around the fields in the
|
107
|
+
# argument list. How about write('users', %w{name, email, balance}, data)?
|
108
|
+
describe 'bulk writes!' do
|
109
|
+
before do
|
110
|
+
@db = Swift.db do |db|
|
111
|
+
db.execute %q{drop table if exists users}
|
112
|
+
db.execute %q{create table users(id serial, name text, email text)}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'writes from an IO object' do
|
117
|
+
data = StringIO.new "Sally Arthurton\tsally@local\nJonas Arthurton\tjonas@local\n"
|
118
|
+
assert_equal 2, Swift.db.write('users', %w{name email}, data)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'writes from a string' do
|
122
|
+
data = "Sally Arthurton\tsally@local\nJonas Arthurton\tjonas@local\n"
|
123
|
+
assert_equal 2, Swift.db.write('users', %w{name email}, data)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
describe 'Adapter' do
|
4
|
+
supported_by Swift::DB::Postgres, Swift::DB::Mysql do
|
5
|
+
describe 'character encoding' do
|
6
|
+
before do
|
7
|
+
Swift.db do |db|
|
8
|
+
db.execute %q{drop table if exists users}
|
9
|
+
db.execute %q{create table users(id serial, name text, primary key(id))}
|
10
|
+
|
11
|
+
# Mysql on debian at least doesn't default to utf8.
|
12
|
+
if db.kind_of? Swift::DB::Mysql
|
13
|
+
db.execute %q{alter table users default character set utf8}
|
14
|
+
db.execute %q{alter table users change name name text charset utf8}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should store and retrieve utf8 characters' do
|
20
|
+
Swift.db do |db|
|
21
|
+
name = "King of \u2665s"
|
22
|
+
db.prepare("insert into users (name) values(?)").execute(name)
|
23
|
+
value = db.prepare("select * from users limit 1").execute.first[:name]
|
24
|
+
assert_equal Encoding::UTF_8, value.encoding
|
25
|
+
assert_equal name, value
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should store and retrieve non ascii' do
|
30
|
+
Swift.db do |db|
|
31
|
+
name = "\xA1\xB8".force_encoding("euc-jp")
|
32
|
+
db.prepare("insert into users (name) values(?)").execute(name)
|
33
|
+
value = db.prepare("select * from users limit 1").execute.first[:name]
|
34
|
+
assert_equal Encoding::UTF_8, value.encoding
|
35
|
+
assert_equal name.encode("utf-8"), value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require 'swift/identity_map'
|
3
|
+
|
4
|
+
describe 'IdentityMap' do
|
5
|
+
before do
|
6
|
+
@im = Swift::IdentityMap.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it %q{returns nil on GC'd object} do
|
10
|
+
2.times do
|
11
|
+
@im.set('foo', 'foo')
|
12
|
+
assert_equal 'foo', @im.get('foo')
|
13
|
+
end
|
14
|
+
GC.start
|
15
|
+
assert_nil @im.get('foo')
|
16
|
+
end
|
17
|
+
end
|
data/test/test_io.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
describe 'Adapter' do
|
4
|
+
supported_by Swift::DB::Postgres, Swift::DB::Mysql do
|
5
|
+
describe 'Storing binary objects' do
|
6
|
+
before do
|
7
|
+
Swift.db do |db|
|
8
|
+
type = db.is_a?(Swift::DB::Postgres) ? 'bytea' : 'blob'
|
9
|
+
db.execute %q{drop table if exists users}
|
10
|
+
db.execute %Q{create table users(id serial, name text, image #{type}, primary key(id))}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'stores and retrieves an image' do
|
15
|
+
Swift.db do |db|
|
16
|
+
io = File.open(File.dirname(__FILE__) + '/house-explode.jpg')
|
17
|
+
db.prepare("insert into users (name, image) values(?, ?)").execute('test', io)
|
18
|
+
value = db.prepare("select image from users limit 1").execute.first[:image]
|
19
|
+
|
20
|
+
io.rewind
|
21
|
+
assert_equal Encoding::ASCII_8BIT, value.encoding
|
22
|
+
assert_equal io.read.force_encoding("ASCII-8BIT"), value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
describe 'Adapter' do
|
5
|
+
supported_by Swift::DB::Postgres, Swift::DB::Mysql do
|
6
|
+
describe 'time parsing and time zones' do
|
7
|
+
it 'should set timezone' do
|
8
|
+
assert Swift.db.timezone(8, 0) # +08:00
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should parse timestamps and do conversion accordingly' do
|
12
|
+
assert Swift.db.timezone(8, 30) # +08:30
|
13
|
+
|
14
|
+
time = DateTime.parse('2010-01-01 15:00:00+08:30')
|
15
|
+
match = Regexp.new time.to_time.strftime("%F %H:%M")
|
16
|
+
sql = if Swift.db.kind_of?(Swift::DB::Postgres)
|
17
|
+
"select '#{time.strftime('%F %H:%M:%S')}'::timestamp as now"
|
18
|
+
else
|
19
|
+
"select timestamp('#{time.strftime('%F %H:%M:%S')}') as now"
|
20
|
+
end
|
21
|
+
Swift.db.execute(sql) do |r|
|
22
|
+
assert_match match, r[:now].to_s, "parses time and does zone conversion"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
metadata
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: swift
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 4
|
8
|
+
- 1
|
9
|
+
version: 0.4.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Shane Hanna
|
13
|
+
- Bharanee 'Barney' Rathna
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-08-07 00:00:00 +10:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: minitest
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 7
|
31
|
+
- 0
|
32
|
+
version: 1.7.0
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
description: A rational rudimentary database abstraction.
|
36
|
+
email:
|
37
|
+
- shane.hanna@gmail.com
|
38
|
+
- deepfryed@gmail.com
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions:
|
42
|
+
- ext/extconf.rb
|
43
|
+
extra_rdoc_files:
|
44
|
+
- LICENSE
|
45
|
+
- README.rdoc
|
46
|
+
files:
|
47
|
+
- LICENSE
|
48
|
+
- README.rdoc
|
49
|
+
- Rakefile
|
50
|
+
- VERSION
|
51
|
+
- ext/extconf.rb
|
52
|
+
- ext/swift.cc
|
53
|
+
- lib/swift.rb
|
54
|
+
- lib/swift/adapter.rb
|
55
|
+
- lib/swift/attribute.rb
|
56
|
+
- lib/swift/db.rb
|
57
|
+
- lib/swift/header.rb
|
58
|
+
- lib/swift/identity_map.rb
|
59
|
+
- lib/swift/pool.rb
|
60
|
+
- lib/swift/scheme.rb
|
61
|
+
- lib/swift/type.rb
|
62
|
+
- swift.gemspec
|
63
|
+
- test/helper.rb
|
64
|
+
- test/house-explode.jpg
|
65
|
+
- test/test_adapter.rb
|
66
|
+
- test/test_encoding.rb
|
67
|
+
- test/test_identity_map.rb
|
68
|
+
- test/test_io.rb
|
69
|
+
- test/test_timestamps.rb
|
70
|
+
has_rdoc: true
|
71
|
+
homepage: http://github.com/shanna/swift
|
72
|
+
licenses: []
|
73
|
+
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options:
|
76
|
+
- --charset=UTF-8
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
version: "0"
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
version: "0"
|
93
|
+
requirements: []
|
94
|
+
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 1.3.6
|
97
|
+
signing_key:
|
98
|
+
specification_version: 3
|
99
|
+
summary: A rational rudimentary database abstraction.
|
100
|
+
test_files:
|
101
|
+
- test/test_adapter.rb
|
102
|
+
- test/test_io.rb
|
103
|
+
- test/test_encoding.rb
|
104
|
+
- test/test_timestamps.rb
|
105
|
+
- test/helper.rb
|
106
|
+
- test/test_identity_map.rb
|
107
|
+
- examples/async.rb
|
108
|
+
- examples/scheme.rb
|
109
|
+
- examples/db.rb
|