sequel 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +13 -0
- data/COPYING +18 -0
- data/README +151 -0
- data/Rakefile +96 -0
- data/lib/sequel.rb +13 -0
- data/lib/sequel/connection_pool.rb +65 -0
- data/lib/sequel/core_ext.rb +9 -0
- data/lib/sequel/database.rb +119 -0
- data/lib/sequel/dataset.rb +357 -0
- data/lib/sequel/model.rb +237 -0
- data/lib/sequel/postgres.rb +396 -0
- data/lib/sequel/schema.rb +163 -0
- data/lib/sequel/sqlite.rb +112 -0
- data/spec/database_spec.rb +18 -0
- data/spec/dataset_spec.rb +124 -0
- data/spec/postgres_spec.rb +6 -0
- metadata +85 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'sqlite3'
|
2
|
+
require 'metaid'
|
3
|
+
|
4
|
+
module Sequel
|
5
|
+
module SQLite
|
6
|
+
class Database < Sequel::Database
|
7
|
+
set_adapter_scheme :sqlite
|
8
|
+
attr_reader :pool
|
9
|
+
|
10
|
+
def initialize(opts = {})
|
11
|
+
super
|
12
|
+
@pool = ConnectionPool.new(@opts[:max_connections] || 4) do
|
13
|
+
db = SQLite3::Database.new(@opts[:database])
|
14
|
+
db.type_translation = true
|
15
|
+
db
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def dataset(opts = nil)
|
20
|
+
SQLite::Dataset.new(self, opts)
|
21
|
+
end
|
22
|
+
|
23
|
+
def tables
|
24
|
+
# return a list of tables
|
25
|
+
end
|
26
|
+
|
27
|
+
def execute(sql)
|
28
|
+
@pool.hold {|conn| conn.execute(sql)}
|
29
|
+
end
|
30
|
+
|
31
|
+
def execute_insert(sql)
|
32
|
+
@pool.hold {|conn| conn.execute(sql); conn.last_insert_row_id}
|
33
|
+
end
|
34
|
+
|
35
|
+
def single_value(sql)
|
36
|
+
@pool.hold {|conn| conn.get_first_value(sql)}
|
37
|
+
end
|
38
|
+
|
39
|
+
def result_set(sql, record_class, &block)
|
40
|
+
@pool.hold do |conn|
|
41
|
+
conn.query(sql) do |result|
|
42
|
+
columns = result.columns
|
43
|
+
column_count = columns.size
|
44
|
+
result.each do |values|
|
45
|
+
row = {}
|
46
|
+
column_count.times {|i| row[columns[i].to_sym] = values[i]}
|
47
|
+
block.call(record_class ? record_class.new(row) : row)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def synchronize(&block)
|
54
|
+
@pool.hold(&block)
|
55
|
+
end
|
56
|
+
|
57
|
+
def transaction(&block)
|
58
|
+
@pool.hold {|conn| conn.transaction(&block)}
|
59
|
+
end
|
60
|
+
|
61
|
+
def table_exists?(name)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Dataset < Sequel::Dataset
|
66
|
+
def each(opts = nil, &block)
|
67
|
+
@db.result_set(select_sql(opts), @record_class, &block)
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
LIMIT_1 = {:limit => 1}.freeze
|
72
|
+
|
73
|
+
def first(opts = nil)
|
74
|
+
opts = opts ? opts.merge(LIMIT_1) : LIMIT_1
|
75
|
+
@db.result_set(select_sql(opts), @record_class) {|r| return r}
|
76
|
+
end
|
77
|
+
|
78
|
+
def last(opts = nil)
|
79
|
+
raise RuntimeError, 'No order specified' unless
|
80
|
+
@opts[:order] || (opts && opts[:order])
|
81
|
+
|
82
|
+
opts = {:order => reverse_order(@opts[:order])}.
|
83
|
+
merge(opts ? opts.merge(LIMIT_1) : LIMIT_1)
|
84
|
+
@db.result_set(select_sql(opts), @record_class) {|r| return r}
|
85
|
+
end
|
86
|
+
|
87
|
+
def count(opts = nil)
|
88
|
+
@db.single_value(count_sql(opts)).to_i
|
89
|
+
end
|
90
|
+
|
91
|
+
def insert(values = nil, opts = nil)
|
92
|
+
@db.synchronize do
|
93
|
+
@db.execute_insert insert_sql(values, opts)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def update(values, opts = nil)
|
98
|
+
@db.synchronize do
|
99
|
+
@db.execute update_sql(values, opts)
|
100
|
+
end
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
def delete(opts = nil)
|
105
|
+
@db.synchronize do
|
106
|
+
@db.execute delete_sql(opts)
|
107
|
+
end
|
108
|
+
self
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../lib/sequel')
|
2
|
+
|
3
|
+
|
4
|
+
class Sequel::Database
|
5
|
+
attr_accessor :opts
|
6
|
+
end
|
7
|
+
|
8
|
+
context "A new Database" do
|
9
|
+
specify "should accept options and store them in @opts" do
|
10
|
+
opts = :my_options
|
11
|
+
Sequel::Database.new(opts).opts.should_be opts
|
12
|
+
end
|
13
|
+
|
14
|
+
specify "should set opts to empty hash if not specified" do
|
15
|
+
Sequel::Database.new.opts.should == {}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../lib/sequel')
|
2
|
+
|
3
|
+
class sequel::Dataset
|
4
|
+
attr_accessor :db, :opts
|
5
|
+
end
|
6
|
+
|
7
|
+
context "The Dataset Class" do
|
8
|
+
specify "should include the Enumerable mix-in" do
|
9
|
+
Sequel::Dataset.included_modules.should_include Enumerable
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "A new Dataset instance" do
|
14
|
+
specify "should store db and opts in @db and @opts" do
|
15
|
+
db = "my db"
|
16
|
+
opts = [1, 2, 3, 4]
|
17
|
+
|
18
|
+
d = Sequel::Dataset.new(db, opts)
|
19
|
+
d.db.should_be db
|
20
|
+
d.opts.should_be opts
|
21
|
+
end
|
22
|
+
|
23
|
+
specify "should set opts to empty hash if ommited" do
|
24
|
+
Sequel::Dataset.new(:db).opts.should == {}
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "Dataset#dup_merge" do
|
29
|
+
specify "should create a new instance of the same class with merged opts" do
|
30
|
+
subclass = Class.new(Sequel::Dataset)
|
31
|
+
db = "my db"
|
32
|
+
orig = subclass.new(db, {1 => 2, 3 => 4})
|
33
|
+
dup = orig.dup_merge({3 => 5})
|
34
|
+
|
35
|
+
dup.class.should_be subclass
|
36
|
+
dup.opts.should == {1 => 2, 3 => 5}
|
37
|
+
dup.db.should_be db
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "Dataset#field_name" do
|
42
|
+
setup {@d = Sequel::Dataset.new(:db)}
|
43
|
+
|
44
|
+
specify "should return the argument as is if not a symbol" do
|
45
|
+
@d.field_name(nil).should == nil
|
46
|
+
@d.field_name(1).should == 1
|
47
|
+
@d.field_name('field').should == 'field'
|
48
|
+
end
|
49
|
+
|
50
|
+
specify "should parse fields with underscore without change" do
|
51
|
+
@d.field_name(:node_id).should == 'node_id'
|
52
|
+
end
|
53
|
+
|
54
|
+
specify "should parse double-underscore as dot-notation" do
|
55
|
+
@d.field_name(:posts__id).should == 'posts.id'
|
56
|
+
end
|
57
|
+
|
58
|
+
specify "should parse triple-underscore as AS notation" do
|
59
|
+
@d.field_name(:posts__id___pid).should == 'posts.id AS pid'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "Dataset#field_list" do
|
64
|
+
setup {@d = Sequel::Dataset.new(:db)}
|
65
|
+
|
66
|
+
specify "should return the sql wildcard if an empty array is specified" do
|
67
|
+
@d.field_list([]).should == '*'
|
68
|
+
end
|
69
|
+
|
70
|
+
specify "should return comma-separated field list if an array is passed" do
|
71
|
+
@d.field_list([:a, :b]).should == 'a, b'
|
72
|
+
end
|
73
|
+
|
74
|
+
specify "should return the argument as is if not an array" do
|
75
|
+
@d.field_list(nil).should_be_nil
|
76
|
+
@d.field_list(23).should_be 23
|
77
|
+
@d.field_list("wowie zowie").should == "wowie zowie"
|
78
|
+
end
|
79
|
+
|
80
|
+
specify "should parse field names using #field_name" do
|
81
|
+
@d.field_list([:posts__author_id, :authors__name]).should ==
|
82
|
+
'posts.author_id, authors.name'
|
83
|
+
|
84
|
+
@d.field_list([:posts__id___pid, :authors__name___aname]).should ==
|
85
|
+
'posts.id AS pid, authors.name AS aname'
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "Dataset#source_list" do
|
90
|
+
setup {@d = Sequel::Dataset.new(:db)}
|
91
|
+
|
92
|
+
specify "should return the argument if not an array or hash" do
|
93
|
+
@d.source_list(nil).should_be_nil
|
94
|
+
@d.source_list(1).should == 1
|
95
|
+
@d.source_list('hello').should == 'hello'
|
96
|
+
@d.source_list(:symbol).should == :symbol
|
97
|
+
end
|
98
|
+
|
99
|
+
specify "should return comma-separated value if an array is specified" do
|
100
|
+
@d.source_list([1, 2, 3]).should == '1, 2, 3'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "Dataset DSL: " do
|
105
|
+
specify "#form should create a duplicate dataset with the source argument merged" do
|
106
|
+
subclass = Class.new(Sequel::Dataset)
|
107
|
+
d1 = subclass.new(:db, {:select => '*'})
|
108
|
+
|
109
|
+
d2 = d1.from(:posts)
|
110
|
+
d2.class.should_be subclass
|
111
|
+
d2.opts[:select].should == '*'
|
112
|
+
d2.opts[:from].should == :posts
|
113
|
+
end
|
114
|
+
|
115
|
+
specify "#select should create a duplicate dataset with the select argument merged" do
|
116
|
+
subclass = Class.new(Sequel::Dataset)
|
117
|
+
d1 = subclass.new(:db, {:from => :posts})
|
118
|
+
|
119
|
+
d2 = d1.select(:id, :name)
|
120
|
+
d2.class.should_be subclass
|
121
|
+
d2.opts[:from].should == :posts
|
122
|
+
d2.opts[:select].should == [:id, :name]
|
123
|
+
end
|
124
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: sequel
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2007-03-05 00:00:00 +02:00
|
8
|
+
summary: ORM framework for Ruby.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: ciconia@gmail.com
|
12
|
+
homepage: http://code.google.com/p/ruby-sequel/
|
13
|
+
rubyforge_project:
|
14
|
+
description: ORM framework for Ruby.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.2
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Sharon Rosner
|
31
|
+
files:
|
32
|
+
- COPYING
|
33
|
+
- README
|
34
|
+
- Rakefile
|
35
|
+
- doc/rdoc
|
36
|
+
- spec/database_spec.rb
|
37
|
+
- spec/dataset_spec.rb
|
38
|
+
- spec/postgres_spec.rb
|
39
|
+
- lib/sequel
|
40
|
+
- lib/sequel.rb
|
41
|
+
- lib/sequel/dataset.rb
|
42
|
+
- lib/sequel/model.rb
|
43
|
+
- lib/sequel/postgres.rb
|
44
|
+
- lib/sequel/schema.rb
|
45
|
+
- lib/sequel/sqlite.rb
|
46
|
+
- lib/sequel/connection_pool.rb
|
47
|
+
- lib/sequel/database.rb
|
48
|
+
- lib/sequel/core_ext.rb
|
49
|
+
- CHANGELOG
|
50
|
+
test_files: []
|
51
|
+
|
52
|
+
rdoc_options:
|
53
|
+
- --quiet
|
54
|
+
- --title
|
55
|
+
- Sequel Documentation
|
56
|
+
- --opname
|
57
|
+
- index.html
|
58
|
+
- --line-numbers
|
59
|
+
- --main
|
60
|
+
- README
|
61
|
+
- --inline-source
|
62
|
+
- --exclude
|
63
|
+
- ^(examples|extras)\/
|
64
|
+
- --exclude
|
65
|
+
- lib/sequel.rb
|
66
|
+
extra_rdoc_files:
|
67
|
+
- README
|
68
|
+
- CHANGELOG
|
69
|
+
- COPYING
|
70
|
+
executables: []
|
71
|
+
|
72
|
+
extensions: []
|
73
|
+
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
dependencies:
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: metaid
|
79
|
+
version_requirement:
|
80
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">"
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 0.0.0
|
85
|
+
version:
|