sequel 0.1.9.9 → 0.1.9.10
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/CHANGELOG +18 -0
- data/Rakefile +1 -1
- data/lib/sequel.rb +2 -2
- data/lib/sequel/ado.rb +10 -4
- data/lib/sequel/connection_pool.rb +22 -0
- data/lib/sequel/core_ext.rb +43 -6
- data/lib/sequel/database.rb +2 -45
- data/lib/sequel/dataset/dataset_convenience.rb +10 -0
- data/lib/sequel/dataset/dataset_sql.rb +17 -3
- data/lib/sequel/mysql.rb +9 -11
- data/lib/sequel/schema/schema_sql.rb +8 -6
- data/lib/sequel/sqlite.rb +11 -4
- data/spec/adapters/mysql_spec.rb +3 -1
- data/spec/adapters/sqlite_spec.rb +48 -2
- data/spec/core_ext_spec.rb +19 -0
- data/spec/database_spec.rb +6 -1
- data/spec/dataset_spec.rb +16 -0
- data/spec/schema_spec.rb +5 -5
- metadata +2 -3
data/CHANGELOG
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
=== 0.19.10 (2007-08-22)
|
2
|
+
|
3
|
+
* Changed schema generation code to generate separate statements for CREATE TABLE and each CREATE INDEX (#34).
|
4
|
+
|
5
|
+
* Refactored Dataset::SQL#field_name for better support of different quoting schemes by specific adapters.
|
6
|
+
|
7
|
+
* Added #current_page_record_count for paginated datasets.
|
8
|
+
|
9
|
+
* Removed Database#literal and included Dataset::SQL instead.
|
10
|
+
|
11
|
+
* Sequel::Dataset:SQL#field_name can now take a hash (as well as #select and any method that uses #field_name) for aliasing column names. E.g. Dataset.new(nil).from(:test).select(:_qqa => 'Date').sql #=> 'SELECT _qqa AS 'Date' FROM test'.
|
12
|
+
|
13
|
+
* Moved SingleThreadedPool to lib/sequel/connection_pool.rb.
|
14
|
+
|
15
|
+
* Changed SQLite::Dataset to return affected rows for #delete and #update (#33).
|
16
|
+
|
17
|
+
* ADO adapter: Added use of Enumerable for Recordset#Fields, playing it safe and moving to the first row before getting results, and changing the auto_increment constant to work for MSSQL.
|
18
|
+
|
1
19
|
=== 0.1.9.9 (2007-08-18)
|
2
20
|
|
3
21
|
* New ADO adapter by cdcarter (#31).
|
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ require 'fileutils'
|
|
6
6
|
include FileUtils
|
7
7
|
|
8
8
|
NAME = "sequel"
|
9
|
-
VERS = "0.1.9.
|
9
|
+
VERS = "0.1.9.10"
|
10
10
|
CLEAN.include ['**/.*.sw?', 'pkg/*', '.config', 'doc/*', 'coverage/*']
|
11
11
|
RDOC_OPTS = ['--quiet', '--title', "Sequel: Concise ORM for Ruby",
|
12
12
|
"--opname", "index.html",
|
data/lib/sequel.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'metaid'
|
2
2
|
|
3
3
|
files = %w[
|
4
|
-
core_ext error
|
5
|
-
dataset migration model
|
4
|
+
core_ext error connection_pool pretty_table expressions
|
5
|
+
dataset migration model schema database
|
6
6
|
]
|
7
7
|
dir = File.join(File.dirname(__FILE__), 'sequel')
|
8
8
|
files.each {|f| require(File.join(dir, f))}
|
data/lib/sequel/ado.rb
CHANGED
@@ -9,6 +9,12 @@ module Sequel
|
|
9
9
|
class Database < Sequel::Database
|
10
10
|
set_adapter_scheme :ado
|
11
11
|
|
12
|
+
AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
|
13
|
+
|
14
|
+
def auto_increment_sql
|
15
|
+
AUTO_INCREMENT
|
16
|
+
end
|
17
|
+
|
12
18
|
def connect
|
13
19
|
dbname = @opts[:database]
|
14
20
|
handle = WIN32OLE.new('ADODB.Connection')
|
@@ -41,11 +47,11 @@ module Sequel
|
|
41
47
|
@db.synchronize do
|
42
48
|
s = @db.execute sql
|
43
49
|
|
44
|
-
|
45
|
-
@columns =
|
46
|
-
0.upto(num_cols-1) {|x| @columns[x] = s.Fields(x).Name.to_sym}
|
50
|
+
fields = s.Fields.extend(Enumerable)
|
51
|
+
@columns = fields.map {|x| x.Name.to_sym}
|
47
52
|
|
48
|
-
s.
|
53
|
+
s.moveFirst
|
54
|
+
s.getRows.transpose.each {|r| yield hash_row(r)}
|
49
55
|
end
|
50
56
|
self
|
51
57
|
end
|
@@ -105,5 +105,27 @@ module Sequel
|
|
105
105
|
@allocated.delete(thread)
|
106
106
|
end
|
107
107
|
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# A SingleThreadedPool acts as a replacement for a ConnectionPool for use
|
111
|
+
# in single-threaded applications. ConnectionPool imposes a substantial
|
112
|
+
# performance penalty, so SingleThreadedPool is used to gain some speed.
|
113
|
+
class SingleThreadedPool
|
114
|
+
attr_writer :connection_proc
|
115
|
+
|
116
|
+
# Initializes the instance with the supplied block as the connection_proc.
|
117
|
+
def initialize(&block)
|
118
|
+
@connection_proc = block
|
119
|
+
end
|
120
|
+
|
121
|
+
# Yields the connection to the supplied block. This method simulates the
|
122
|
+
# ConnectionPool#hold API.
|
123
|
+
def hold
|
124
|
+
@conn ||= @connection_proc.call
|
125
|
+
yield @conn
|
126
|
+
rescue Exception => e
|
127
|
+
# if the error is not a StandardError it is converted into RuntimeError.
|
128
|
+
raise e.is_a?(StandardError) ? e : e.message
|
108
129
|
end
|
130
|
+
end
|
109
131
|
end
|
data/lib/sequel/core_ext.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Enumerable extensions.
|
2
2
|
module Enumerable
|
3
|
+
# Invokes the specified method for each item, along with the supplied
|
4
|
+
# arguments.
|
3
5
|
def send_each(sym, *args)
|
4
6
|
each {|i| i.send(sym, *args)}
|
5
7
|
end
|
@@ -16,6 +18,9 @@ class Array
|
|
16
18
|
end
|
17
19
|
|
18
20
|
module Sequel
|
21
|
+
# ExpressionString is used to represent literal SQL expressions. An
|
22
|
+
# ExpressionString is copied verbatim into an SQL statement. Instances of
|
23
|
+
# ExpressionString can be created by calling String#expr.
|
19
24
|
class ExpressionString < ::String
|
20
25
|
end
|
21
26
|
end
|
@@ -33,50 +38,72 @@ class String
|
|
33
38
|
def split_sql
|
34
39
|
to_sql.split(';').map {|s| s.strip}
|
35
40
|
end
|
36
|
-
|
37
|
-
#
|
41
|
+
|
42
|
+
# Converts a string into an ExpressionString, in order to override string
|
43
|
+
# literalization, e.g.:
|
44
|
+
#
|
45
|
+
# DB[:items].filter(:abc => 'def').sql #=>
|
46
|
+
# "SELECT * FROM items WHERE (abc = 'def')"
|
47
|
+
#
|
48
|
+
# DB[:items].filter(:abc => 'def'.expr).sql #=>
|
49
|
+
# "SELECT * FROM items WHERE (abc = def)"
|
50
|
+
#
|
38
51
|
def expr
|
39
52
|
Sequel::ExpressionString.new(self)
|
40
53
|
end
|
41
54
|
|
42
|
-
#
|
55
|
+
# Converts a string into a Time object.
|
43
56
|
def to_time
|
44
57
|
Time.parse(self)
|
45
58
|
end
|
46
59
|
|
60
|
+
# Converts a string into a field name.
|
47
61
|
def to_field_name
|
48
62
|
self
|
49
63
|
end
|
50
64
|
end
|
51
65
|
|
66
|
+
# Methods to format field names and associated constructs. This module is
|
67
|
+
# included in String and Symbol.
|
52
68
|
module FieldCompositionMethods
|
69
|
+
# Constructs a DESC clause for use in an ORDER BY clause.
|
53
70
|
def DESC
|
54
71
|
"#{to_field_name} DESC"
|
55
72
|
end
|
56
73
|
|
74
|
+
# Constructs an AS clause for field aliasing.
|
57
75
|
def AS(target)
|
58
76
|
"#{to_field_name} AS #{target}"
|
59
77
|
end
|
60
78
|
|
79
|
+
# Constructs a qualified wildcard (*) clause.
|
61
80
|
def ALL
|
62
81
|
"#{to_s}.*"
|
63
82
|
end
|
64
83
|
|
65
|
-
FIELD_TITLE_RE1 = /^(.*)\sAS\s(.+)
|
84
|
+
FIELD_TITLE_RE1 = /^(.*)\sAS\s(.+)$/i.freeze
|
66
85
|
FIELD_TITLE_RE2 = /^([^\.]+)\.([^\.]+)$/.freeze
|
67
86
|
|
87
|
+
# Returns the field name. If the field name is aliased, the alias is
|
88
|
+
# returned.
|
68
89
|
def field_title
|
69
|
-
s = to_field_name
|
70
|
-
case s
|
90
|
+
case s = to_field_name
|
71
91
|
when FIELD_TITLE_RE1, FIELD_TITLE_RE2: $2
|
72
92
|
else
|
73
93
|
s
|
74
94
|
end
|
75
95
|
end
|
76
96
|
|
97
|
+
# Formats a min(x) expression.
|
77
98
|
def MIN; "min(#{to_field_name})"; end
|
99
|
+
|
100
|
+
# Formats a max(x) expression.
|
78
101
|
def MAX; "max(#{to_field_name})"; end
|
102
|
+
|
103
|
+
# Formats a sum(x) expression.
|
79
104
|
def SUM; "sum(#{to_field_name})"; end
|
105
|
+
|
106
|
+
# Formats an avg(x) expression.
|
80
107
|
def AVG; "avg(#{to_field_name})"; end
|
81
108
|
end
|
82
109
|
|
@@ -92,6 +119,16 @@ class Symbol
|
|
92
119
|
FIELD_REF_RE1 = /^([a-z_]+)__([a-z_]+)___([a-z_]+)/.freeze
|
93
120
|
FIELD_REF_RE2 = /^([a-z_]+)___([a-z_]+)$/.freeze
|
94
121
|
FIELD_REF_RE3 = /^([a-z_]+)__([a-z_]+)$/.freeze
|
122
|
+
|
123
|
+
# Converts a symbol into a field name. This method supports underscore
|
124
|
+
# notation in order to express qualified (two underscores) and aliased
|
125
|
+
# (three underscores) fields:
|
126
|
+
#
|
127
|
+
# :abc.to_field_name #=> "abc"
|
128
|
+
# :abc___a.to_field_name #=> "abc AS a"
|
129
|
+
# :items__abc.to_field_name #=> "items.abc"
|
130
|
+
# :items__abc___a.to_field_name #=> "items.abc AS a"
|
131
|
+
#
|
95
132
|
def to_field_name
|
96
133
|
s = to_s
|
97
134
|
case s
|
data/lib/sequel/database.rb
CHANGED
@@ -1,25 +1,6 @@
|
|
1
1
|
require 'uri'
|
2
2
|
|
3
3
|
module Sequel
|
4
|
-
# A SingleThreadedPool acts as a replacement for a ConnectionPool for use
|
5
|
-
# in single-threaded applications. ConnectionPool imposes a substantial
|
6
|
-
# performance penalty, so SingleThreadedPool is used to gain some speed.
|
7
|
-
class SingleThreadedPool
|
8
|
-
attr_writer :connection_proc
|
9
|
-
|
10
|
-
def initialize(&block)
|
11
|
-
@connection_proc = block
|
12
|
-
end
|
13
|
-
|
14
|
-
def hold
|
15
|
-
@conn ||= @connection_proc.call
|
16
|
-
yield @conn
|
17
|
-
rescue Exception => e
|
18
|
-
# if the error is not a StandardError it is converted into RuntimeError.
|
19
|
-
raise e.is_a?(StandardError) ? e : e.message
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
4
|
# A Database object represents a virtual connection to a database.
|
24
5
|
# The Database class is meant to be subclassed by database adapters in order
|
25
6
|
# to provide the functionality needed for executing queries.
|
@@ -110,33 +91,9 @@ module Sequel
|
|
110
91
|
true
|
111
92
|
end
|
112
93
|
|
94
|
+
include Dataset::SQL
|
113
95
|
include Schema::SQL
|
114
96
|
|
115
|
-
NULL = "NULL".freeze
|
116
|
-
TIMESTAMP_FORMAT = "TIMESTAMP '%Y-%m-%d %H:%M:%S'".freeze
|
117
|
-
DATE_FORMAT = "DATE '%Y-%m-%d'".freeze
|
118
|
-
TRUE = "'t'".freeze
|
119
|
-
FALSE = "'f'".freeze
|
120
|
-
|
121
|
-
# default literal implementation for use in schema definitions
|
122
|
-
def literal(v)
|
123
|
-
case v
|
124
|
-
when ExpressionString: v
|
125
|
-
when String: "'#{v.gsub(/'/, "''")}'"
|
126
|
-
when Integer, Float: v.to_s
|
127
|
-
when NilClass: NULL
|
128
|
-
when TrueClass: TRUE
|
129
|
-
when FalseClass: FALSE
|
130
|
-
when Symbol: v.to_field_name
|
131
|
-
when Array: v.empty? ? NULL : v.map {|i| literal(i)}.join(COMMA_SEPARATOR)
|
132
|
-
when Time: v.strftime(TIMESTAMP_FORMAT)
|
133
|
-
when Date: v.strftime(DATE_FORMAT)
|
134
|
-
when Dataset: "(#{v.sql})"
|
135
|
-
else
|
136
|
-
raise SequelError, "can't express #{v.inspect} as a SQL literal"
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
97
|
# default serial primary key definition. this should be overriden for each adapter.
|
141
98
|
def serial_primary_key_options
|
142
99
|
{:primary_key => true, :type => :integer, :auto_increment => true}
|
@@ -152,7 +109,7 @@ module Sequel
|
|
152
109
|
# end
|
153
110
|
def create_table(name, &block)
|
154
111
|
g = Schema::Generator.new(self, name, &block)
|
155
|
-
|
112
|
+
create_table_sql_list(*g.create_info).each {|sta| execute(sta)}
|
156
113
|
end
|
157
114
|
|
158
115
|
# Drops a table.
|
@@ -129,6 +129,16 @@ module Sequel
|
|
129
129
|
a..b
|
130
130
|
end
|
131
131
|
|
132
|
+
# Returns the number of records in the current page
|
133
|
+
def current_page_record_count
|
134
|
+
return 0 if @current_page > @page_count
|
135
|
+
|
136
|
+
a = 1 + (@current_page - 1) * @page_size
|
137
|
+
b = a + @page_size - 1
|
138
|
+
b = @pagination_record_count if b > @pagination_record_count
|
139
|
+
b - a + 1
|
140
|
+
end
|
141
|
+
|
132
142
|
# Returns the minimum value for the given field.
|
133
143
|
def min(field)
|
134
144
|
single_value(:select => [field.MIN.AS(:v)])
|
@@ -7,9 +7,23 @@ module Sequel
|
|
7
7
|
# symbols can include double underscores to denote a dot separator, e.g.
|
8
8
|
# :posts__id will be converted into posts.id.
|
9
9
|
def field_name(field)
|
10
|
-
|
10
|
+
case field
|
11
|
+
when Symbol, String:
|
12
|
+
quoted_field_name(field.to_field_name)
|
13
|
+
when Hash:
|
14
|
+
field.map {|f,a| "#{field_name(f)} AS #{field_name(a)}"}.join(COMMA_SEPARATOR)
|
15
|
+
else
|
16
|
+
field
|
17
|
+
end
|
11
18
|
end
|
12
19
|
|
20
|
+
# Adds quoting to field references. This method is just a stub and can
|
21
|
+
# be overriden in adapters in order to provide correct field quoting
|
22
|
+
# behavior.
|
23
|
+
def quoted_field_name(name)
|
24
|
+
name
|
25
|
+
end
|
26
|
+
|
13
27
|
ALIASED_REGEXP = /^(.*)\s(.*)$/.freeze
|
14
28
|
QUALIFIED_REGEXP = /^(.*)\.(.*)$/.freeze
|
15
29
|
|
@@ -203,7 +217,7 @@ module Sequel
|
|
203
217
|
# Returns a copy of the dataset with the order reversed. If no order is
|
204
218
|
# given, the existing order is inverted.
|
205
219
|
def reverse_order(*order)
|
206
|
-
order(invert_order(order.empty? ? @opts[:order] : order))
|
220
|
+
order(*invert_order(order.empty? ? @opts[:order] : order))
|
207
221
|
end
|
208
222
|
|
209
223
|
DESC_ORDER_REGEXP = /(.*)\sDESC/.freeze
|
@@ -420,7 +434,7 @@ module Sequel
|
|
420
434
|
sql = opts[:distinct] ? \
|
421
435
|
"SELECT DISTINCT #{select_fields} FROM #{select_source}" : \
|
422
436
|
"SELECT #{select_fields} FROM #{select_source}"
|
423
|
-
|
437
|
+
|
424
438
|
if join = opts[:join]
|
425
439
|
sql << join
|
426
440
|
end
|
data/lib/sequel/mysql.rb
CHANGED
@@ -137,27 +137,25 @@ module Sequel
|
|
137
137
|
end
|
138
138
|
|
139
139
|
class Dataset < Sequel::Dataset
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
def quote_field(field)
|
145
|
-
field =~ FIELD_NOT_QUOTABLE_RE ? field : "`#{field}`"
|
140
|
+
UNQUOTABLE_FIELD_RE = /^(`(.+)`)|\*$/.freeze
|
141
|
+
def quote_field(f)
|
142
|
+
f =~ UNQUOTABLE_FIELD_RE ? f : "`#{f}`"
|
146
143
|
end
|
147
144
|
|
148
|
-
|
149
|
-
|
150
|
-
|
145
|
+
FIELD_EXPR_RE = /^([^\(]+\()?([^\.]+\.)?([^\s\)]+)(\))?(\sAS\s(.+))?$/i.freeze
|
146
|
+
FIELD_ORDER_RE = /^(.*) (DESC|ASC)$/i.freeze
|
147
|
+
def quoted_field_name(name)
|
148
|
+
case name
|
151
149
|
when FIELD_EXPR_RE:
|
152
150
|
$6 ? \
|
153
151
|
"#{$1}#{$2}#{quote_field($3)}#{$4} AS #{quote_field($6)}" : \
|
154
152
|
"#{$1}#{$2}#{quote_field($3)}#{$4}"
|
155
153
|
when FIELD_ORDER_RE: "#{quote_field($1)} #{$2}"
|
156
154
|
else
|
157
|
-
quote_field(
|
155
|
+
quote_field(name)
|
158
156
|
end
|
159
157
|
end
|
160
|
-
|
158
|
+
|
161
159
|
def literal(v)
|
162
160
|
case v
|
163
161
|
when true: '1'
|
@@ -66,16 +66,18 @@ module Sequel
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
def
|
70
|
-
indexes.map {|i| index_definition_sql(table_name, i)}
|
69
|
+
def index_list_sql_list(table_name, indexes)
|
70
|
+
indexes.map {|i| index_definition_sql(table_name, i)}
|
71
71
|
end
|
72
72
|
|
73
|
-
def
|
74
|
-
sql = "CREATE TABLE #{name} (#{column_list_sql(columns)});"
|
75
|
-
|
73
|
+
def create_table_sql_list(name, columns, indexes = nil)
|
74
|
+
sql = ["CREATE TABLE #{name} (#{column_list_sql(columns)});"]
|
75
|
+
if indexes && !indexes.empty?
|
76
|
+
sql.concat(index_list_sql_list(name, indexes))
|
77
|
+
end
|
76
78
|
sql
|
77
79
|
end
|
78
|
-
|
80
|
+
|
79
81
|
def drop_table_sql(name)
|
80
82
|
"DROP TABLE #{name};"
|
81
83
|
end
|
data/lib/sequel/sqlite.rb
CHANGED
@@ -34,7 +34,7 @@ module Sequel
|
|
34
34
|
|
35
35
|
def execute(sql)
|
36
36
|
@logger.info(sql) if @logger
|
37
|
-
@pool.hold {|conn| conn.execute_batch(sql)}
|
37
|
+
@pool.hold {|conn| conn.execute_batch(sql); conn.changes}
|
38
38
|
end
|
39
39
|
|
40
40
|
def execute_insert(sql)
|
@@ -122,12 +122,19 @@ module Sequel
|
|
122
122
|
|
123
123
|
def update(values, opts = nil)
|
124
124
|
@db.execute update_sql(values, opts)
|
125
|
-
self
|
126
125
|
end
|
127
126
|
|
128
127
|
def delete(opts = nil)
|
129
|
-
|
130
|
-
|
128
|
+
# check if no filter is specified
|
129
|
+
unless (opts && opts[:where]) || @opts[:where]
|
130
|
+
@db.transaction do
|
131
|
+
unfiltered_count = count
|
132
|
+
@db.execute delete_sql(opts)
|
133
|
+
unfiltered_count
|
134
|
+
end
|
135
|
+
else
|
136
|
+
@db.execute delete_sql(opts)
|
137
|
+
end
|
131
138
|
end
|
132
139
|
|
133
140
|
EXPLAIN = 'EXPLAIN %s'.freeze
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -7,6 +7,8 @@ end
|
|
7
7
|
MYSQL_DB.create_table :items do
|
8
8
|
text :name
|
9
9
|
integer :value
|
10
|
+
|
11
|
+
index :value
|
10
12
|
end
|
11
13
|
|
12
14
|
context "A MySQL dataset" do
|
@@ -94,7 +96,7 @@ context "A MySQL dataset" do
|
|
94
96
|
'SELECT max(items.`name`) AS `max_name` FROM items'
|
95
97
|
|
96
98
|
@d.insert_sql(:value => 333).should == \
|
97
|
-
'INSERT INTO items (`value`) VALUES (333)'
|
99
|
+
'INSERT INTO items (`value`) VALUES (333);'
|
98
100
|
end
|
99
101
|
|
100
102
|
specify "should support ORDER clause in UPDATE statements" do
|
@@ -115,7 +115,7 @@ context "An SQLite dataset" do
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
context "An
|
118
|
+
context "An SQLite dataset" do
|
119
119
|
setup do
|
120
120
|
@d = SQLITE_DB[:items]
|
121
121
|
@d.delete # remove all records
|
@@ -139,4 +139,50 @@ context "An SQLITE dataset" do
|
|
139
139
|
specify "should correctly return min" do
|
140
140
|
@d.min(:value).should == 1.23.to_s
|
141
141
|
end
|
142
|
-
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context "SQLite::Dataset#delete" do
|
145
|
+
setup do
|
146
|
+
@d = SQLITE_DB[:items]
|
147
|
+
@d.delete # remove all records
|
148
|
+
@d << {:name => 'abc', :value => 1.23}
|
149
|
+
@d << {:name => 'def', :value => 4.56}
|
150
|
+
@d << {:name => 'ghi', :value => 7.89}
|
151
|
+
end
|
152
|
+
|
153
|
+
specify "should return the number of records affected when filtered" do
|
154
|
+
@d.count.should == 3
|
155
|
+
@d.filter {value < 3}.delete.should == 1
|
156
|
+
@d.count.should == 2
|
157
|
+
|
158
|
+
@d.filter {value < 3}.delete.should == 0
|
159
|
+
@d.count.should == 2
|
160
|
+
end
|
161
|
+
|
162
|
+
specify "should return the number of records affected when unfiltered" do
|
163
|
+
@d.count.should == 3
|
164
|
+
@d.delete.should == 3
|
165
|
+
@d.count.should == 0
|
166
|
+
|
167
|
+
@d.delete.should == 0
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context "SQLite::Dataset#update" do
|
172
|
+
setup do
|
173
|
+
@d = SQLITE_DB[:items]
|
174
|
+
@d.delete # remove all records
|
175
|
+
@d << {:name => 'abc', :value => 1.23}
|
176
|
+
@d << {:name => 'def', :value => 4.56}
|
177
|
+
@d << {:name => 'ghi', :value => 7.89}
|
178
|
+
end
|
179
|
+
|
180
|
+
specify "should return the number of records affected" do
|
181
|
+
@d.filter(:name => 'abc').update(:value => 2).should == 1
|
182
|
+
|
183
|
+
@d.update(:value => 10).should == 3
|
184
|
+
|
185
|
+
@d.filter(:name => 'xxx').update(:value => 23).should == 0
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
data/spec/core_ext_spec.rb
CHANGED
@@ -115,6 +115,25 @@ context "Symbol#to_field_name" do
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
context "FieldCompositionMethods#field_title" do
|
119
|
+
specify "should return the field name for non aliased fields" do
|
120
|
+
:xyz.field_title.should == 'xyz'
|
121
|
+
:abc__xyz.field_title.should == 'xyz'
|
122
|
+
|
123
|
+
'abc'.field_title.should == 'abc'
|
124
|
+
'abc.def'.field_title.should == 'def'
|
125
|
+
end
|
126
|
+
|
127
|
+
specify "should return the field alias for aliased fields" do
|
128
|
+
:xyz___x.field_title.should == 'x'
|
129
|
+
:abc__xyz___y.field_title.should == 'y'
|
130
|
+
|
131
|
+
'abc AS x'.field_title.should == 'x'
|
132
|
+
'abc as y'.field_title.should == 'y'
|
133
|
+
'abc.def AS d'.field_title.should == 'd'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
118
137
|
context "Symbol" do
|
119
138
|
specify "should support MIN for specifying min function" do
|
120
139
|
:abc__def.MIN.should == 'min(abc.def)'
|
data/spec/database_spec.rb
CHANGED
data/spec/dataset_spec.rb
CHANGED
@@ -551,6 +551,11 @@ context "Dataset#select" do
|
|
551
551
|
specify "should use the wildcard if no arguments are given" do
|
552
552
|
@d.select.sql.should == 'SELECT * FROM test'
|
553
553
|
end
|
554
|
+
|
555
|
+
specify "should accept a hash for AS values" do
|
556
|
+
@d.select(:name => 'n', :__ggh => 'age').sql.should =~
|
557
|
+
/SELECT ((name AS n, __ggh AS age)|(__ggh AS age, name AS n)) FROM test/
|
558
|
+
end
|
554
559
|
|
555
560
|
specify "should overrun the previous select option" do
|
556
561
|
@d.select(:a, :b, :c).select.sql.should == 'SELECT * FROM test'
|
@@ -1199,6 +1204,10 @@ context "Dataset#set_model" do
|
|
1199
1204
|
all[3].class.should == @m1
|
1200
1205
|
#...
|
1201
1206
|
end
|
1207
|
+
|
1208
|
+
specify "should raise an error if more than two arguments are supplied" do
|
1209
|
+
proc {@dataset.set_model(1, 2, 3)}.should raise_error(SequelError)
|
1210
|
+
end
|
1202
1211
|
end
|
1203
1212
|
|
1204
1213
|
context "Dataset#model_classes" do
|
@@ -1420,6 +1429,13 @@ context "A paginated dataset" do
|
|
1420
1429
|
@d.paginate(4, 50).current_page_record_range.should == (151..153)
|
1421
1430
|
@d.paginate(5, 50).current_page_record_range.should == (0..0)
|
1422
1431
|
end
|
1432
|
+
|
1433
|
+
specify "should return the record count for the current page" do
|
1434
|
+
@paginated.current_page_record_count.should == 20
|
1435
|
+
@d.paginate(3, 50).current_page_record_count.should == 50
|
1436
|
+
@d.paginate(4, 50).current_page_record_count.should == 3
|
1437
|
+
@d.paginate(5, 50).current_page_record_count.should == 0
|
1438
|
+
end
|
1423
1439
|
end
|
1424
1440
|
|
1425
1441
|
context "Dataset#columns" do
|
data/spec/schema_spec.rb
CHANGED
@@ -136,7 +136,7 @@ context "DB#create_table" do
|
|
136
136
|
integer :id
|
137
137
|
index :id
|
138
138
|
end
|
139
|
-
@db.sqls.should == ["CREATE TABLE cats (id integer);CREATE INDEX cats_id_index ON cats (id);"]
|
139
|
+
@db.sqls.should == ["CREATE TABLE cats (id integer);", "CREATE INDEX cats_id_index ON cats (id);"]
|
140
140
|
end
|
141
141
|
|
142
142
|
specify "should accept multiple index definitions" do
|
@@ -145,7 +145,7 @@ context "DB#create_table" do
|
|
145
145
|
index :id
|
146
146
|
index :name
|
147
147
|
end
|
148
|
-
@db.sqls.should == ["CREATE TABLE cats (id integer);CREATE INDEX cats_id_index ON cats (id);CREATE INDEX cats_name_index ON cats (name);"]
|
148
|
+
@db.sqls.should == ["CREATE TABLE cats (id integer);", "CREATE INDEX cats_id_index ON cats (id);", "CREATE INDEX cats_name_index ON cats (name);"]
|
149
149
|
end
|
150
150
|
|
151
151
|
specify "should accept custom index names" do
|
@@ -153,7 +153,7 @@ context "DB#create_table" do
|
|
153
153
|
integer :id
|
154
154
|
index :id, :name => 'abc'
|
155
155
|
end
|
156
|
-
@db.sqls.should == ["CREATE TABLE cats (id integer);CREATE INDEX abc ON cats (id);"]
|
156
|
+
@db.sqls.should == ["CREATE TABLE cats (id integer);", "CREATE INDEX abc ON cats (id);"]
|
157
157
|
end
|
158
158
|
|
159
159
|
specify "should accept unique index definitions" do
|
@@ -161,7 +161,7 @@ context "DB#create_table" do
|
|
161
161
|
integer :id
|
162
162
|
index :id, :unique => true
|
163
163
|
end
|
164
|
-
@db.sqls.should == ["CREATE TABLE cats (id integer);CREATE UNIQUE INDEX cats_id_index ON cats (id);"]
|
164
|
+
@db.sqls.should == ["CREATE TABLE cats (id integer);", "CREATE UNIQUE INDEX cats_id_index ON cats (id);"]
|
165
165
|
end
|
166
166
|
|
167
167
|
specify "should accept compound index definitions" do
|
@@ -169,7 +169,7 @@ context "DB#create_table" do
|
|
169
169
|
integer :id
|
170
170
|
index [:id, :name], :unique => true
|
171
171
|
end
|
172
|
-
@db.sqls.should == ["CREATE TABLE cats (id integer);CREATE UNIQUE INDEX cats_id_name_index ON cats (id, name);"]
|
172
|
+
@db.sqls.should == ["CREATE TABLE cats (id integer);", "CREATE UNIQUE INDEX cats_id_name_index ON cats (id, name);"]
|
173
173
|
end
|
174
174
|
end
|
175
175
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: sequel
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.9.
|
7
|
-
date: 2007-08-
|
6
|
+
version: 0.1.9.10
|
7
|
+
date: 2007-08-23 00:00:00 +03:00
|
8
8
|
summary: Lightweight ORM library for Ruby
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -33,7 +33,6 @@ files:
|
|
33
33
|
- README
|
34
34
|
- Rakefile
|
35
35
|
- bin/sequel
|
36
|
-
- doc/rdoc
|
37
36
|
- spec/adapters
|
38
37
|
- spec/connection_pool_spec.rb
|
39
38
|
- spec/core_ext_spec.rb
|