sequel_core 1.1 → 1.2
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 +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
|