sequel_core 1.1 → 1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +14 -0
- data/Rakefile +1 -1
- data/bin/sequel +140 -11
- data/lib/sequel_core/adapters/mysql.rb +16 -3
- data/lib/sequel_core/dataset/convenience.rb +6 -1
- data/lib/sequel_core/dataset/sequelizer.rb +7 -7
- data/lib/sequel_core/dataset/sql.rb +1 -1
- data/lib/sequel_core/schema/schema_sql.rb +5 -1
- data/spec/adapters/mysql_spec.rb +11 -0
- data/spec/dataset_spec.rb +30 -1
- data/spec/schema_spec.rb +7 -0
- data/spec/sequelizer_spec.rb +0 -40
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
=== 1.2 (2008-02-15)
|
2
|
+
|
3
|
+
* Added support for :varchar[100] like type declarations in #create_table.
|
4
|
+
|
5
|
+
* Fixed #rename_column in mysql adapter to support types like varchar(255) (#159).
|
6
|
+
|
7
|
+
* Added support for order and limit in DELETE statement in MySQL adapter (#160).
|
8
|
+
|
9
|
+
* Added checks to Dataset#multi_insert to prevent work if no values are given (#162).
|
10
|
+
|
11
|
+
* Override ruby2ruby implementation of Proc#to_sexp which leaks memory (#161).
|
12
|
+
|
13
|
+
* Added log option, help for sequel script (#157).
|
14
|
+
|
1
15
|
=== 1.1 (2008-02-15)
|
2
16
|
|
3
17
|
* Fixed Dataset#join_table to support joining of datasets (#156).
|
data/Rakefile
CHANGED
@@ -9,7 +9,7 @@ include FileUtils
|
|
9
9
|
# Configuration
|
10
10
|
##############################################################################
|
11
11
|
NAME = "sequel_core"
|
12
|
-
VERS = "1.
|
12
|
+
VERS = "1.2"
|
13
13
|
CLEAN.include ["**/.*.sw?", "pkg/*", ".config", "doc/*", "coverage/*"]
|
14
14
|
RDOC_OPTS = [
|
15
15
|
"--quiet",
|
data/bin/sequel
CHANGED
@@ -1,29 +1,76 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
|
+
require 'optparse'
|
5
|
+
require 'sequel' rescue nil
|
4
6
|
require 'sequel_core'
|
5
7
|
require 'sequel_model' rescue nil
|
8
|
+
require 'logger'
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
$uri = nil
|
11
|
+
$logfile = nil
|
12
|
+
$echo = nil
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
sequel
|
14
|
+
opts = OptionParser.new do |opts|
|
15
|
+
opts.banner = "Sequel: Lightweight ORM for Ruby"
|
16
|
+
opts.define_head "Usage: sequel <uri> [options]"
|
17
|
+
opts.separator ""
|
18
|
+
opts.separator "Examples:"
|
19
|
+
opts.separator " sequel sqlite:///blog.db"
|
20
|
+
opts.separator " sequel postgres://localhost/my_blog"
|
21
|
+
|
22
|
+
opts.separator ""
|
23
|
+
opts.separator "For more information see http://code.google.com/p/ruby-sequel"
|
24
|
+
opts.separator ""
|
25
|
+
opts.separator "Options:"
|
14
26
|
|
15
|
-
|
16
|
-
|
27
|
+
opts.on("-l", "--log logfile", "log SQL statements to log file") do |v|
|
28
|
+
$logfile = v
|
29
|
+
end
|
30
|
+
|
31
|
+
# opts.on("-e", "--echo", "echo SQL statements") do |v|
|
32
|
+
# $echo = v
|
33
|
+
# end
|
34
|
+
|
35
|
+
opts.on_tail("-?", "--help", "Show this message") do
|
36
|
+
puts opts
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on_tail("-v", "--version", "Show version") do
|
41
|
+
class << Gem; attr_accessor :loaded_specs; end
|
42
|
+
specs = Gem.loaded_specs['sequel']
|
43
|
+
puts "sequel #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
|
44
|
+
specs = Gem.loaded_specs['sequel_core']
|
45
|
+
puts "sequel_core #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
|
46
|
+
begin
|
47
|
+
specs = Gem.loaded_specs['sequel_model']
|
48
|
+
puts "sequel_model #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
|
49
|
+
rescue
|
50
|
+
end
|
51
|
+
exit
|
52
|
+
end
|
53
|
+
end
|
54
|
+
opts.parse!
|
17
55
|
|
18
56
|
db = ARGV.shift
|
19
57
|
|
20
|
-
if db.
|
21
|
-
puts
|
58
|
+
if db.blank?
|
59
|
+
puts opts
|
22
60
|
exit
|
23
61
|
end
|
24
62
|
|
63
|
+
db_opts = {}
|
64
|
+
if $logfile
|
65
|
+
db_opts[:logger] = Logger.new($logfile)
|
66
|
+
end
|
67
|
+
if $echo
|
68
|
+
db_opts[:echo] = true
|
69
|
+
end
|
70
|
+
|
25
71
|
begin
|
26
|
-
|
72
|
+
puts "db_opts = #{db_opts.inspect}"
|
73
|
+
DB = Sequel.connect db, db_opts
|
27
74
|
rescue => e
|
28
75
|
puts e.message
|
29
76
|
exit
|
@@ -40,3 +87,85 @@ end
|
|
40
87
|
require 'irb'
|
41
88
|
puts "Your database is stored in DB..."
|
42
89
|
IRB.start
|
90
|
+
|
91
|
+
__END__
|
92
|
+
|
93
|
+
#!/usr/bin/env ruby
|
94
|
+
|
95
|
+
require 'rubygems'
|
96
|
+
require 'optparse'
|
97
|
+
require 'bulkmail'
|
98
|
+
|
99
|
+
$helo = nil
|
100
|
+
$from = nil
|
101
|
+
$recipients = []
|
102
|
+
$content = nil
|
103
|
+
$delay = 60..300
|
104
|
+
|
105
|
+
opts = OptionParser.new do |opts|
|
106
|
+
opts.banner = "Usage: bulkmail <options>"
|
107
|
+
opts.define_head "Simple bulk-mailer."
|
108
|
+
opts.separator ""
|
109
|
+
opts.separator "Options:"
|
110
|
+
|
111
|
+
opts.on("-h", "--helo HOSTNAME", "HELO host name.") do |v|
|
112
|
+
$helo = v
|
113
|
+
end
|
114
|
+
|
115
|
+
opts.on("-r", "--recipients filename", "Recipients file name") do |v|
|
116
|
+
$recipients = IO.readlines(v).map {|l| l =~ /(.*)(\r\n|\n)$/ ? $1 : l}.compact
|
117
|
+
end
|
118
|
+
|
119
|
+
opts.on("-c", "--content filename", "Content file name") do |v|
|
120
|
+
$content = IO.read(v)
|
121
|
+
end
|
122
|
+
|
123
|
+
opts.on("-f", "--from from", "From address") do |v|
|
124
|
+
$from = v
|
125
|
+
end
|
126
|
+
|
127
|
+
opts.on('-n', "--nodelay", "No delay") do |v|
|
128
|
+
$delay = 0
|
129
|
+
end
|
130
|
+
|
131
|
+
# No argument, shows at tail. This will print an options summary.
|
132
|
+
# Try it and see!
|
133
|
+
opts.on_tail("-?", "--help", "Show this message") do
|
134
|
+
puts opts
|
135
|
+
exit
|
136
|
+
end
|
137
|
+
|
138
|
+
# Another typical switch to print the version.
|
139
|
+
opts.on_tail("-v", "--version", "Show version") do
|
140
|
+
class << Gem; attr_accessor :loaded_specs; end
|
141
|
+
specs = Gem.loaded_specs['bulkmail']
|
142
|
+
puts "bulkmail #{specs.version} (#{specs.date.strftime '%Y-%m-%d'})"
|
143
|
+
exit
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
begin
|
148
|
+
opts.parse! ARGV
|
149
|
+
rescue => e
|
150
|
+
puts e.message
|
151
|
+
puts e.backtrace.first
|
152
|
+
exit
|
153
|
+
end
|
154
|
+
|
155
|
+
unless $content
|
156
|
+
puts opts
|
157
|
+
exit
|
158
|
+
end
|
159
|
+
|
160
|
+
trap('INT') {exit}
|
161
|
+
|
162
|
+
puts "Please hold on..."
|
163
|
+
|
164
|
+
sender = BulkMail::Sender.new({
|
165
|
+
:list => $recipients,
|
166
|
+
:from => $from,
|
167
|
+
:message => $content,
|
168
|
+
:helo => $helo,
|
169
|
+
:delay => $delay
|
170
|
+
})
|
171
|
+
sender.start
|
@@ -141,9 +141,9 @@ module Sequel
|
|
141
141
|
def alter_table_sql(table, op)
|
142
142
|
case op[:op]
|
143
143
|
when :rename_column
|
144
|
-
"ALTER TABLE #{table} CHANGE COLUMN #{literal(op[:name])} #{literal(op[:new_name])} #{op[:type]}"
|
144
|
+
"ALTER TABLE #{table} CHANGE COLUMN #{literal(op[:name])} #{literal(op[:new_name])} #{type_literal(op[:type])}"
|
145
145
|
when :set_column_type
|
146
|
-
"ALTER TABLE #{table} CHANGE COLUMN #{literal(op[:name])} #{literal(op[:name])} #{op[:type]}"
|
146
|
+
"ALTER TABLE #{table} CHANGE COLUMN #{literal(op[:name])} #{literal(op[:name])} #{type_literal(op[:type])}"
|
147
147
|
when :drop_index
|
148
148
|
"DROP INDEX #{default_index_name(table, op[:columns])} ON #{table}"
|
149
149
|
else
|
@@ -316,13 +316,26 @@ module Sequel
|
|
316
316
|
# MySQL supports ORDER and LIMIT clauses in UPDATE statements.
|
317
317
|
def update_sql(values, opts = nil)
|
318
318
|
sql = super
|
319
|
-
|
320
319
|
opts = opts ? @opts.merge(opts) : @opts
|
321
320
|
|
322
321
|
if order = opts[:order]
|
323
322
|
sql << " ORDER BY #{column_list(order)}"
|
324
323
|
end
|
324
|
+
if limit = opts[:limit]
|
325
|
+
sql << " LIMIT #{limit}"
|
326
|
+
end
|
325
327
|
|
328
|
+
sql
|
329
|
+
end
|
330
|
+
|
331
|
+
# MySQL supports ORDER and LIMIT clauses in DELETE statements.
|
332
|
+
def delete_sql(opts = nil)
|
333
|
+
sql = super
|
334
|
+
opts = opts ? @opts.merge(opts) : @opts
|
335
|
+
|
336
|
+
if order = opts[:order]
|
337
|
+
sql << " ORDER BY #{column_list(order)}"
|
338
|
+
end
|
326
339
|
if limit = opts[:limit]
|
327
340
|
sql << " LIMIT #{limit}"
|
328
341
|
end
|
@@ -242,15 +242,20 @@ module Sequel
|
|
242
242
|
# # this will commit every 50 records
|
243
243
|
# dataset.multi_insert(lots_of_records, :slice => 50)
|
244
244
|
def multi_insert(*args)
|
245
|
-
if args
|
245
|
+
if args.empty?
|
246
|
+
return
|
247
|
+
elsif args[0].is_a?(Array) && args[1].is_a?(Array)
|
246
248
|
columns, values, opts = *args
|
247
249
|
else
|
248
250
|
# we assume that an array of hashes is given
|
249
251
|
hashes, opts = *args
|
252
|
+
return if hashes.empty?
|
250
253
|
columns = hashes.first.keys
|
251
254
|
# convert the hashes into arrays
|
252
255
|
values = hashes.map {|h| columns.map {|c| h[c]}}
|
253
256
|
end
|
257
|
+
# make sure there's work to do
|
258
|
+
return if columns.empty? || values.empty?
|
254
259
|
|
255
260
|
slice_size = opts && (opts[:commit_every] || opts[:slice])
|
256
261
|
|
@@ -371,12 +371,12 @@ rescue Exception
|
|
371
371
|
end
|
372
372
|
|
373
373
|
class Proc
|
374
|
-
# replacement for Proc#to_sexp
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
374
|
+
# replacement for Proc#to_sexp as defined in ruby2ruby.
|
375
|
+
# see also: http://rubyforge.org/tracker/index.php?func=detail&aid=18095&group_id=1513&atid=5921
|
376
|
+
# The ruby2ruby implementation leaks memory, so we fix it.
|
377
|
+
def to_sexp
|
378
|
+
block = self
|
379
|
+
c = Class.new {define_method(:m, &block)}
|
380
|
+
ParseTree.translate(c, :m)[2]
|
381
381
|
end
|
382
382
|
end
|
@@ -45,6 +45,10 @@ module Sequel
|
|
45
45
|
schema_utility_dataset.literal(v)
|
46
46
|
end
|
47
47
|
|
48
|
+
def type_literal(t)
|
49
|
+
t.is_a?(Symbol) ? t.to_s : literal(t)
|
50
|
+
end
|
51
|
+
|
48
52
|
def expression_list(*args, &block)
|
49
53
|
schema_utility_dataset.expression_list(*args, &block)
|
50
54
|
end
|
@@ -53,7 +57,7 @@ module Sequel
|
|
53
57
|
if column[:type] == :check
|
54
58
|
return constraint_definition_sql(column)
|
55
59
|
end
|
56
|
-
sql = "#{literal(column[:name].to_sym)} #{TYPES[column[:type]]}"
|
60
|
+
sql = "#{literal(column[:name].to_sym)} #{type_literal(TYPES[column[:type]])}"
|
57
61
|
column[:size] ||= 255 if column[:type] == :varchar
|
58
62
|
elements = column[:size] || column[:elements]
|
59
63
|
sql << "(#{literal(elements)})" if elements
|
data/spec/adapters/mysql_spec.rb
CHANGED
@@ -319,6 +319,17 @@ context "A MySQL database" do
|
|
319
319
|
@db[:test2].first[:zyx].should == 'qqqq'
|
320
320
|
end
|
321
321
|
|
322
|
+
specify "should support rename_column operations with types like varchar(255)" do
|
323
|
+
@db[:test2].delete
|
324
|
+
@db.add_column :test2, :tre, :text
|
325
|
+
@db[:test2] << {:name => 'mmm', :value => 111, :tre => 'qqqq'}
|
326
|
+
|
327
|
+
@db[:test2].columns.should == [:name, :value, :zyx, :tre]
|
328
|
+
@db.rename_column :test2, :tre, :ert, :type => :varchar[255]
|
329
|
+
@db[:test2].columns.should == [:name, :value, :zyx, :ert]
|
330
|
+
@db[:test2].first[:ert].should == 'qqqq'
|
331
|
+
end
|
332
|
+
|
322
333
|
specify "should support set_column_type operations" do
|
323
334
|
@db.add_column :test2, :xyz, :float
|
324
335
|
@db[:test2].delete
|
data/spec/dataset_spec.rb
CHANGED
@@ -1050,7 +1050,7 @@ end
|
|
1050
1050
|
context "Dataset#empty?" do
|
1051
1051
|
specify "should return true if records exist in the dataset" do
|
1052
1052
|
@db = Sequel::Database.new
|
1053
|
-
@db.meta_def(:execute) {|sql|
|
1053
|
+
@db.meta_def(:execute) {|sql| @sqls ||=[]; @sqls << sql}
|
1054
1054
|
@db.meta_def(:sqls) {@sqls ||= []}
|
1055
1055
|
|
1056
1056
|
$cccc = Class.new(Sequel::Dataset) do
|
@@ -2171,6 +2171,35 @@ context "Dataset#multi_insert" do
|
|
2171
2171
|
'COMMIT'
|
2172
2172
|
]
|
2173
2173
|
end
|
2174
|
+
|
2175
|
+
specify "should not do anything if no columns or values are given" do
|
2176
|
+
@ds.multi_insert
|
2177
|
+
@db.sqls.should be_nil
|
2178
|
+
|
2179
|
+
@ds.multi_insert([])
|
2180
|
+
@db.sqls.should be_nil
|
2181
|
+
|
2182
|
+
@ds.multi_insert([], [])
|
2183
|
+
@db.sqls.should be_nil
|
2184
|
+
|
2185
|
+
@ds.multi_insert([{}, {}])
|
2186
|
+
@db.sqls.should be_nil
|
2187
|
+
|
2188
|
+
@ds.multi_insert([:a, :b], [])
|
2189
|
+
@db.sqls.should be_nil
|
2190
|
+
|
2191
|
+
@ds.multi_insert([:x, :y], [[1, 2], [3, 4], [5, 6]], :slice => 2)
|
2192
|
+
@db.sqls.should == [
|
2193
|
+
'BEGIN',
|
2194
|
+
"INSERT INTO items (x, y) VALUES (1, 2)",
|
2195
|
+
"INSERT INTO items (x, y) VALUES (3, 4)",
|
2196
|
+
'COMMIT',
|
2197
|
+
'BEGIN',
|
2198
|
+
"INSERT INTO items (x, y) VALUES (5, 6)",
|
2199
|
+
'COMMIT'
|
2200
|
+
]
|
2201
|
+
end
|
2202
|
+
|
2174
2203
|
end
|
2175
2204
|
|
2176
2205
|
context "Dataset#query" do
|
data/spec/schema_spec.rb
CHANGED
@@ -94,6 +94,13 @@ context "DB#create_table" do
|
|
94
94
|
end
|
95
95
|
@db.sqls.should == ["CREATE TABLE cats (name varchar(51))"]
|
96
96
|
end
|
97
|
+
|
98
|
+
specify "should accept varchar size as sql function" do
|
99
|
+
@db.create_table(:cats) do
|
100
|
+
column :name, :varchar[102]
|
101
|
+
end
|
102
|
+
@db.sqls.should == ["CREATE TABLE cats (name varchar(102))"]
|
103
|
+
end
|
97
104
|
|
98
105
|
specify "should accept foreign keys" do
|
99
106
|
@db.create_table(:cats) do
|
data/spec/sequelizer_spec.rb
CHANGED
@@ -59,46 +59,6 @@ context "Sequelizer without Ruby2Ruby" do
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
context "Proc without #to_sexp method (Ruby2Ruby missing)" do
|
63
|
-
setup do
|
64
|
-
class Proc
|
65
|
-
alias_method :orig_to_sexp, :to_sexp
|
66
|
-
remove_method :to_sexp
|
67
|
-
end
|
68
|
-
|
69
|
-
module Kernel
|
70
|
-
alias_method :orig_sq_require, :require
|
71
|
-
def require(name); raise LoadError if name == 'ruby2ruby'; end
|
72
|
-
end
|
73
|
-
old_verbose = $VERBOSE
|
74
|
-
$VERBOSE = nil
|
75
|
-
load(File.join(File.dirname(__FILE__), '../lib/sequel_core/dataset/sequelizer.rb'))
|
76
|
-
$VERBOSE = old_verbose
|
77
|
-
@db = Sequel::Database.new
|
78
|
-
@ds = @db[:items]
|
79
|
-
end
|
80
|
-
|
81
|
-
teardown do
|
82
|
-
module Kernel
|
83
|
-
alias_method :require, :orig_sq_require
|
84
|
-
end
|
85
|
-
old_verbose = $VERBOSE
|
86
|
-
$VERBOSE = nil
|
87
|
-
load(File.join(File.dirname(__FILE__), '../lib/sequel_core/dataset/sequelizer.rb'))
|
88
|
-
$VERBOSE = old_verbose
|
89
|
-
|
90
|
-
class Proc
|
91
|
-
alias_method :to_sexp, :orig_to_sexp
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
specify "should define a replacement Proc#to_sexp implementation" do
|
96
|
-
pr = proc {1 + 1}
|
97
|
-
proc {pr.to_sexp}.should_not raise_error
|
98
|
-
pr.to_sexp.should == [:bmethod, nil, [:call, [:lit, 1], :+, [:array, [:lit, 1]]]]
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
62
|
context "Proc#to_sql" do
|
103
63
|
DB = Sequel::Database.new
|
104
64
|
DS = DB[:items]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: "1.
|
4
|
+
version: "1.2"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sharon Rosner
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-02-
|
12
|
+
date: 2008-02-16 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|