activerecord 1.9.0 → 1.9.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

data/CHANGELOG CHANGED
@@ -1,3 +1,16 @@
1
+ *1.9.1* (27th March, 2005)
2
+
3
+ * Fixed that Active Record objects with float attribute could not be cloned #808
4
+
5
+ * Fixed that MissingSourceFile's wasn't properly detected in production mode #925 [Nicholas Seckar]
6
+
7
+ * Fixed that :counter_cache option would look for a line_items_count column for a LineItem object instead of lineitems_count
8
+
9
+ * Fixed that AR exists?() would explode on postgresql if the passed id did not match the PK type #900 [Scott Barron]
10
+
11
+ * Fixed the MS SQL adapter to work with the new limit/offset approach and with binary data (still suffering from 7KB limit, though) #901 [delynnb]
12
+
13
+
1
14
  *1.9.0* (22th March, 2005)
2
15
 
3
16
  * Added adapter independent limit clause as a two-element array with the first being the limit, the second being the offset #795 [Sam Stephenson]. Example:
@@ -376,12 +376,12 @@ module ActiveRecord
376
376
 
377
377
  if options[:counter_cache]
378
378
  module_eval(
379
- "after_create '#{association_class_name}.increment_counter(\"#{Inflector.pluralize(self.to_s.downcase). + "_count"}\", #{association_class_primary_key_name})" +
379
+ "after_create '#{association_class_name}.increment_counter(\"#{self.to_s.underscore.pluralize + "_count"}\", #{association_class_primary_key_name})" +
380
380
  " unless #{association_name}.nil?'"
381
381
  )
382
382
 
383
383
  module_eval(
384
- "before_destroy '#{association_class_name}.decrement_counter(\"#{Inflector.pluralize(self.to_s.downcase) + "_count"}\", #{association_class_primary_key_name})" +
384
+ "before_destroy '#{association_class_name}.decrement_counter(\"#{self.to_s.underscore.pluralize + "_count"}\", #{association_class_primary_key_name})" +
385
385
  " unless #{association_name}.nil?'"
386
386
  )
387
387
  end
@@ -91,6 +91,15 @@ module ActiveRecord #:nodoc:
91
91
  # on the other hand, will sanitize the <tt>user_name</tt> and +password+ before inserting them in the query, which will ensure that
92
92
  # an attacker can't escape the query and fake the login (or worse).
93
93
  #
94
+ # When using multiple parameters in the conditions, it can easily become hard to read exactly what the fourth or fifth
95
+ # question mark is supposed to represent. In those cases, you can resort to named bind variables instead. That's done by replacing
96
+ # the question marks with symbols and supplying a hash with values for the matching symbol keys:
97
+ #
98
+ # Company.find_first([
99
+ # "id = :id AND name = :name AND division = :division AND created_at > :accounting_date",
100
+ # { :id => 3, :name => "37signals", :division => "First", :accounting_date => '2005-01-01' }
101
+ # ])
102
+ #
94
103
  # == Overwriting default accessors
95
104
  #
96
105
  # All column values are automatically available through basic accessors on the Active Record object, but some times you
@@ -288,6 +297,7 @@ module ActiveRecord #:nodoc:
288
297
  # Person.find(1, :conditions => "associate_id = 5"
289
298
  # Person.find(1, 2, 6, :conditions => "status = 'active'"
290
299
  # Person.find([7, 17], :conditions => ["sanitize_me = ?", "bare'quote"]
300
+ # Person.find(25, :conditions => ["name = :name AND age = :age", { :name => "Mary", :age => 22 }]
291
301
  #
292
302
  # +RecordNotFound+ is raised if no record can be found.
293
303
  def find(*args)
@@ -330,7 +340,7 @@ module ActiveRecord #:nodoc:
330
340
  # Example:
331
341
  # Person.exists?(5)
332
342
  def exists?(id)
333
- !find_first("#{primary_key} = #{sanitize(id)}").nil?
343
+ !find_first("#{primary_key} = #{sanitize(id)}").nil? rescue false
334
344
  end
335
345
 
336
346
  # This method is deprecated in favor of find with the :conditions option.
@@ -1038,7 +1048,7 @@ module ActiveRecord #:nodoc:
1038
1048
  self.attribute_names.inject({}) do |attributes, name|
1039
1049
  begin
1040
1050
  attributes[name] = read_attribute(name).clone
1041
- rescue TypeError
1051
+ rescue TypeError, NoMethodError
1042
1052
  attributes[name] = read_attribute(name)
1043
1053
  end
1044
1054
  attributes
@@ -5,6 +5,27 @@ require 'active_record/connection_adapters/abstract_adapter'
5
5
  # Author: Joey Gibson <joey@joeygibson.com>
6
6
  # Date: 10/14/2004
7
7
  #
8
+ # Modifications: DeLynn Berry <delynnb@megastarfinancial.com>
9
+ # Date: 3/22/2005
10
+ #
11
+ # This adapter will ONLY work on Windows systems, since it relies on Win32OLE, which,
12
+ # to my knowledge, is only available on Window.
13
+ #
14
+ # It relies on the ADO support in the DBI module. If you are using the
15
+ # one-click installer of Ruby, then you already have DBI installed, but
16
+ # the ADO module is *NOT* installed. You will need to get the latest
17
+ # source distribution of Ruby-DBI from http://ruby-dbi.sourceforge.net/
18
+ # unzip it, and copy the file <tt>src/lib/dbd_ado/ADO.rb</tt> to
19
+ # <tt>X:/Ruby/lib/ruby/site_ruby/1.8/DBD/ADO/ADO.rb</tt> (you will need to create
20
+ # the ADO directory). Once you've installed that file, you are ready to go.
21
+ #
22
+ # Options:
23
+ #
24
+ # * <tt>:host</tt> -- Defaults to localhost
25
+ # * <tt>:username</tt> -- Defaults to sa
26
+ # * <tt>:password</tt> -- Defaults to nothing
27
+ # * <tt>:database</tt> -- The name of the database. No default, must be provided.
28
+ #
8
29
  # I have tested this code on a WindowsXP Pro SP1 system,
9
30
  # ruby 1.8.2 (2004-07-29) [i386-mswin32], SQL Server 2000.
10
31
  #
@@ -19,7 +40,7 @@ module ActiveRecord
19
40
  username = config[:username] ? config[:username].to_s : 'sa'
20
41
  password = config[:password].to_s
21
42
 
22
- if config.has_key? :database
43
+ if config.has_key?(:database)
23
44
  database = config[:database]
24
45
  else
25
46
  raise ArgumentError, "No database specified. Missing argument: database."
@@ -38,92 +59,110 @@ module ActiveRecord
38
59
 
39
60
  def initialize(name, default, sql_type = nil, is_identity = false, scale_value = 0)
40
61
  super(name, default, sql_type)
41
-
42
62
  @scale = scale_value
43
63
  @identity = is_identity
44
- end
45
-
46
- def binary_to_string(value)
47
- value
48
- end
49
-
50
- def string_to_binary(value)
51
- value
52
- end
64
+ end
53
65
 
54
66
  def simplified_type(field_type)
55
67
  case field_type
56
- when /int/i
57
- :integer
58
- when /float|double|decimal|numeric/i
59
- if @scale == 0
60
- :integer
61
- else
62
- :float
63
- nil
64
- end
65
- when /datetime/i
66
- :datetime
67
- when /timestamp/i
68
- :timestamp
69
- when /time/i
70
- :time
71
- when /date/i
72
- :date
73
- when /clob|text|ntext/i
74
- :text
75
- when /blob|binary|image/i
76
- :binary
77
- when /char|string/i
78
- :string
79
- when /boolean|bit/i
80
- :boolean
68
+ when /int|bigint|smallint|tinyint/i : :integer
69
+ when /float|double|decimal|money|numeric|real|smallmoney/i : @scale == 0 ? :integer : :float
70
+ when /datetime|smalldatetime/i : :datetime
71
+ when /timestamp/i : :timestamp
72
+ when /time/i : :time
73
+ when /text|ntext/i : :text
74
+ when /binary|image|varbinary/i : :binary
75
+ when /char|nchar|nvarchar|string|varchar/i : :string
76
+ when /bit/i : :boolean
77
+ end
78
+ end
79
+
80
+ def type_cast(value)
81
+ return nil if value.nil? || value =~ /^\s*null\s*$/i
82
+ case type
83
+ when :string then value
84
+ when :integer then value == true || value == false ? value == true ? '1' : '0' : value.to_i
85
+ when :float then value.to_f
86
+ when :datetime then cast_to_date_or_time(value)
87
+ when :timestamp then cast_to_time(value)
88
+ when :time then cast_to_time(value)
89
+ else value
90
+ end
91
+ end
92
+
93
+ def cast_to_date_or_time(value)
94
+ return value if value.is_a?(Date)
95
+ guess_date_or_time (value.is_a?(Time)) ? value : cast_to_time(value)
96
+ end
97
+
98
+ def cast_to_time(value)
99
+ return value if value.is_a?(Time)
100
+ time_array = ParseDate.parsedate value
101
+ time_array[0] ||= 2000; time_array[1] ||= 1; time_array[2] ||= 1;
102
+ Time.send Base.default_timezone, *time_array
103
+ end
104
+
105
+ def guess_date_or_time(value)
106
+ (value.hour == 0 and value.min == 0 and value.sec == 0) ?
107
+ Date.new(value.year, value.month, value.day) : value
108
+ end
109
+
110
+ # These methods will only allow the adapter to insert binary data with a length of 7K or less
111
+ # because of a SQL Server statement length policy.
112
+ def string_to_binary(value)
113
+ value.gsub(/(\r|\n|\0|\x1a)/) do
114
+ case $1
115
+ when "\r"
116
+ "%00"
117
+ when "\n"
118
+ "%01"
119
+ when "\0"
120
+ "%02"
121
+ when "\x1a"
122
+ "%03"
123
+ end
81
124
  end
82
125
  end
83
126
 
84
- def string_to_time(string)
85
- return string if string.is_a?(Time)
86
- time_array = ParseDate.parsedate(string, true)
87
- time_array.each_index do |i|
88
- case i
89
- when 0
90
- time_array[i] = time_array[i].nil? ? "2000" : time_array[i].to_s
91
- when 1
92
- time_array[i] = time_array[i].nil? ? "Jan" : time_array[i].to_s
93
- when 2
94
- time_array[i] = time_array[i].nil? ? "1" : time_array[i].to_s
95
- when 3
96
- time_array[i] = time_array[i].nil? ? "0" : time_array[i].to_s
97
- when 4
98
- time_array[i] = time_array[i].nil? ? "0" : time_array[i].to_s
99
- when 5
100
- time_array[i] = time_array[i].nil? ? "0" : time_array[i].to_s
127
+ def binary_to_string(value)
128
+ value.gsub(/(%00|%01|%02|%03)/) do
129
+ case $1
130
+ when "%00"
131
+ "\r"
132
+ when "%01"
133
+ "\n"
134
+ when "%02\0"
135
+ "\0"
136
+ when "%03"
137
+ "\x1a"
101
138
  end
102
139
  end
103
- # treat 0000-00-00 00:00:00 as nil
104
- Time.send(Base.default_timezone, *time_array) rescue nil
105
140
  end
106
141
 
107
142
  end
108
143
 
109
- # This adapter will ONLY work on Windows systems, since it relies on Win32OLE, which,
110
- # to my knowledge, is only available on Window.
111
- #
112
- # It relies on the ADO support in the DBI module. If you are using the
113
- # one-click installer of Ruby, then you already have DBI installed, but
114
- # the ADO module is *NOT* installed. You will need to get the latest
115
- # source distribution of Ruby-DBI from http://ruby-dbi.sourceforge.net/
116
- # unzip it, and copy the file <tt>src/lib/dbd_ado/ADO.rb</tt> to
117
- # <tt>X:/Ruby/lib/ruby/site_ruby/1.8/DBD/ADO/ADO.rb</tt> (you will need to create
118
- # the ADO directory). Once you've installed that file, you are ready to go.
119
- #
120
- # Options:
121
- #
122
- # * <tt>:host</tt> -- Defaults to localhost
123
- # * <tt>:username</tt> -- Defaults to sa
124
- # * <tt>:password</tt> -- Defaults to nothing
125
- # * <tt>:database</tt> -- The name of the database. No default, must be provided.
126
144
  class SQLServerAdapter < AbstractAdapter
145
+
146
+ def native_database_types
147
+ {
148
+ :primary_key => "int NOT NULL IDENTITY(1, 1) PRIMARY KEY",
149
+ :string => { :name => "varchar(255)" },
150
+ :text => { :name => "text(16)" },
151
+ :integer => { :name => "int(4)", :limit => 11 },
152
+ :float => { :name => "float(8)" },
153
+ :datetime => { :name => "datetime(8)" },
154
+ :timestamp => { :name => "datetime(8)" },
155
+ :time => { :name => "datetime(8)" },
156
+ :date => { :name => "datetime(8)" },
157
+ :binary => { :name => "image(16)" },
158
+ :boolean => { :name => "bit(1)" }
159
+ }
160
+ end
161
+
162
+ def adapter_name
163
+ 'SQLServer'
164
+ end
165
+
127
166
  def select_all(sql, name = nil)
128
167
  add_limit!(sql, nil)
129
168
  select(sql, name)
@@ -136,36 +175,22 @@ module ActiveRecord
136
175
  end
137
176
 
138
177
  def columns(table_name, name = nil)
139
- sql = <<EOL
140
- SELECT
141
- COLUMN_NAME as ColName,
142
- COLUMN_DEFAULT as DefaultValue,
143
- DATA_TYPE as ColType,
144
- COL_LENGTH('#{table_name}', COLUMN_NAME) as Length,
145
- COLUMNPROPERTY(OBJECT_ID('#{table_name}'), COLUMN_NAME, 'IsIdentity') as IsIdentity,
146
- NUMERIC_SCALE as Scale
147
- FROM INFORMATION_SCHEMA.columns
148
- WHERE TABLE_NAME = '#{table_name}'
149
- EOL
150
-
178
+ sql = "SELECT COLUMN_NAME as ColName, COLUMN_DEFAULT as DefaultValue, DATA_TYPE as ColType, COL_LENGTH('#{table_name}', COLUMN_NAME) as Length, COLUMNPROPERTY(OBJECT_ID('#{table_name}'), COLUMN_NAME, 'IsIdentity') as IsIdentity, NUMERIC_SCALE as Scale FROM INFORMATION_SCHEMA.columns WHERE TABLE_NAME = '#{table_name}'"
151
179
  result = nil
152
180
  # Uncomment if you want to have the Columns select statment logged.
153
- # Personnally, I think it adds unneccessary SQL statement bloat to the log.
181
+ # Personnally, I think it adds unneccessary bloat to the log.
154
182
  # If you do uncomment, make sure to comment the "result" line that follows
155
183
  log(sql, name, @connection) { |conn| result = conn.select_all(sql) }
156
184
  #result = @connection.select_all(sql)
157
185
  columns = []
158
186
  result.each { |field| columns << ColumnWithIdentity.new(field[:ColName], field[:DefaultValue].to_s.gsub!(/[()\']/,"") =~ /null/ ? nil : field[:DefaultValue], "#{field[:ColType]}(#{field[:Length]})", field[:IsIdentity] == 1 ? true : false, field[:Scale]) }
159
-
160
187
  columns
161
188
  end
162
189
 
163
190
  def insert(sql, name = nil, pk = nil, id_value = nil)
164
191
  begin
165
192
  table_name = get_table_name(sql)
166
-
167
193
  col = get_identity_column(table_name)
168
-
169
194
  ii_enabled = false
170
195
 
171
196
  if col != nil
@@ -181,14 +206,12 @@ EOL
181
206
 
182
207
  log(sql, name, @connection) do |conn|
183
208
  conn.execute(sql)
184
-
185
209
  select_one("SELECT @@IDENTITY AS Ident")["Ident"]
186
210
  end
187
211
  ensure
188
212
  if ii_enabled
189
213
  begin
190
214
  execute enable_identity_insert(table_name, false)
191
-
192
215
  rescue Exception => e
193
216
  # Couldn't turn off IDENTITY_INSERT
194
217
  end
@@ -196,11 +219,24 @@ EOL
196
219
  end
197
220
  end
198
221
 
222
+ def execute(sql, name = nil)
223
+ if sql =~ /^INSERT/i
224
+ insert(sql, name)
225
+ elsif sql =~ /^UPDATE|DELETE/i
226
+ log(sql, name, @connection) do |conn|
227
+ conn.execute(sql)
228
+ retVal = select_one("SELECT @@ROWCOUNT AS AffectedRows")["AffectedRows"]
229
+ end
230
+ else
231
+ log(sql, name, @connection) do |conn|
232
+ conn.execute(sql)
233
+ end
234
+ end
235
+ end
236
+
199
237
  def update(sql, name = nil)
200
238
  execute(sql, name)
201
- affected_rows(name)
202
239
  end
203
-
204
240
  alias_method :delete, :update
205
241
 
206
242
  def begin_db_transaction
@@ -236,8 +272,8 @@ EOL
236
272
  "'#{quote_string(value)}'"
237
273
  end
238
274
  when NilClass then "NULL"
239
- when TrueClass then (column && column.type == :boolean ? "'t'" : "1")
240
- when FalseClass then (column && column.type == :boolean ? "'f'" : "0")
275
+ when TrueClass then '1'
276
+ when FalseClass then '0'
241
277
  when Float, Fixnum, Bignum then value.to_s
242
278
  when Date then "'#{value.to_s}'"
243
279
  when Time, DateTime then "'#{value.strftime("%Y-%m-%d %H:%M:%S")}'"
@@ -254,11 +290,12 @@ EOL
254
290
  end
255
291
 
256
292
  def add_limit_with_offset!(sql, limit, offset)
257
- raise ArgumentError, 'add_limit_with_offset! not implemented'
293
+ order_by = sql.include?("ORDER BY") ? get_order_by(sql.sub(/.*ORDER\sBY./, "")) : nil
294
+ sql.gsub!(/SELECT/i, "SELECT * FROM ( SELECT TOP #{limit} * FROM ( SELECT TOP #{limit + offset}")<<" ) AS tmp1 ORDER BY #{order_by[1]} ) AS tmp2 ORDER BY #{order_by[0]}"
258
295
  end
259
296
 
260
297
  def add_limit_without_offset!(sql, limit)
261
- raise ArgumentError, 'add_limit_without_offset! not implemented'
298
+ limit.nil? ? sql : sql.gsub!(/SELECT/i, "SELECT TOP #{limit}")
262
299
  end
263
300
 
264
301
  def recreate_database(name)
@@ -274,36 +311,18 @@ EOL
274
311
  execute "CREATE DATABASE #{name}"
275
312
  end
276
313
 
277
- def execute(sql, name = nil)
278
- if sql =~ /^INSERT/i
279
- insert(sql, name)
280
- else
281
- log(sql, name, @connection) do |conn|
282
- conn.execute(sql)
283
- end
284
- end
285
- end
286
-
287
- def adapter_name()
288
- 'SqlServer'
289
- end
290
-
291
314
  private
292
315
  def select(sql, name = nil)
293
316
  rows = []
294
-
295
317
  log(sql, name, @connection) do |conn|
296
318
  conn.select_all(sql) do |row|
297
319
  record = {}
298
-
299
320
  row.column_names.each do |col|
300
321
  record[col] = row[col]
301
322
  end
302
-
303
323
  rows << record
304
324
  end
305
325
  end
306
-
307
326
  rows
308
327
  end
309
328
 
@@ -346,10 +365,6 @@ EOL
346
365
  return sql =~ /[\(\.\,]\s*#{col}/
347
366
  end
348
367
 
349
- def query_contains_text_column(sql, col)
350
-
351
- end
352
-
353
368
  def get_order_by(sql)
354
369
  return sql, sql.gsub(/\s*DESC\s*/, "").gsub(/\s*ASC\s*/, " DESC")
355
370
  end
@@ -358,15 +373,6 @@ EOL
358
373
  limit = limit.gsub!(/.OFFSET./i, ",").split(',')
359
374
  return limit[0].to_i, limit[0].to_i+limit[1].to_i
360
375
  end
361
-
362
- def affected_rows(name = nil)
363
- sql = "SELECT @@ROWCOUNT AS AffectedRows"
364
- log(sql, name, @connection) do |conn|
365
- conn.select_all(sql) do |row|
366
- return row[:AffectedRows].to_i
367
- end
368
- end
369
- end
370
376
  end
371
377
  end
372
378
  end
data/rakefile CHANGED
@@ -8,9 +8,14 @@ require 'rake/contrib/rubyforgepublisher'
8
8
 
9
9
  PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
10
10
  PKG_NAME = 'activerecord'
11
- PKG_VERSION = '1.9.0' + PKG_BUILD
11
+ PKG_VERSION = '1.9.1' + PKG_BUILD
12
12
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
13
13
 
14
+ RELEASE_NAME = "REL #{PKG_VERSION}"
15
+
16
+ RUBY_FORGE_PROJECT = "activerecord"
17
+ RUBY_FORGE_USER = "webster132"
18
+
14
19
  PKG_FILES = FileList[
15
20
  "lib/**/*", "test/**/*", "examples/**/*", "doc/**/*", "[A-Z]*", "install.rb", "rakefile"
16
21
  ].exclude(/\bCVS\b|~$/)
@@ -33,47 +38,14 @@ Rake::TestTask.new("test_mysql_ruby") { |t|
33
38
  t.verbose = true
34
39
  }
35
40
 
36
- Rake::TestTask.new("test_postgresql") { |t|
37
- t.libs << "test" << "test/connections/native_postgresql"
38
- t.pattern = 'test/*_test.rb'
39
- t.verbose = true
40
- }
41
-
42
- Rake::TestTask.new("test_sqlite") { |t|
43
- t.libs << "test" << "test/connections/native_sqlite"
44
- t.pattern = 'test/*_test.rb'
45
- t.verbose = true
46
- }
47
-
48
- Rake::TestTask.new("test_sqlite3") { |t|
49
- t.libs << "test" << "test/connections/native_sqlite3"
50
- t.pattern = 'test/*_test.rb'
51
- t.verbose = true
52
- }
53
-
54
- Rake::TestTask.new("test_sqlserver") { |t|
55
- t.libs << "test" << "test/connections/native_sqlserver"
56
- t.pattern = 'test/*_test.rb'
57
- t.verbose = true
58
- }
59
-
60
- Rake::TestTask.new("test_db2") { |t|
61
- t.libs << "test" << "test/connections/native_db2"
62
- t.pattern = 'test/*_test.rb'
63
- t.verbose = true
64
- }
65
-
66
- Rake::TestTask.new("test_oracle") { |t|
67
- t.libs << "test" << "test/connections/native_oracle"
68
- t.pattern = 'test/*_test.rb'
69
- t.verbose = true
70
- }
41
+ for adapter in %( postgresql sqlite sqlite3 sqlserver db2 oci )
42
+ Rake::TestTask.new("test_#{adapter}") { |t|
43
+ t.libs << "test" << "test/connections/native_#{adapter}"
44
+ t.pattern = 'test/*_test.rb'
45
+ t.verbose = true
46
+ }
47
+ end
71
48
 
72
- Rake::TestTask.new("test_oci") { |t|
73
- t.libs << "test" << "test/connections/native_oci"
74
- t.pattern = 'test/*_test.rb'
75
- t.verbose = true
76
- }
77
49
 
78
50
  # Generate the RDoc documentation
79
51
 
@@ -81,6 +53,7 @@ Rake::RDocTask.new { |rdoc|
81
53
  rdoc.rdoc_dir = 'doc'
82
54
  rdoc.title = "Active Record -- Object-relation mapping put on rails"
83
55
  rdoc.options << '--line-numbers --inline-source --accessor cattr_accessor=object'
56
+ rdoc.template = "#{ENV['template']}.rb" if ENV['template']
84
57
  rdoc.rdoc_files.include('README', 'RUNNING_UNIT_TESTS', 'CHANGELOG')
85
58
  rdoc.rdoc_files.include('lib/**/*.rb')
86
59
  rdoc.rdoc_files.exclude('lib/active_record/vendor/*')
@@ -88,20 +61,6 @@ Rake::RDocTask.new { |rdoc|
88
61
  }
89
62
 
90
63
 
91
- # Publish beta gem
92
- desc "Publish the beta gem"
93
- task :pgem => [:package] do
94
- Rake::SshFilePublisher.new("davidhh@comox.textdrive.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
95
- `ssh davidhh@comox.textdrive.com './gemupdate.sh'`
96
- end
97
-
98
- # Publish documentation
99
- desc "Publish the API documentation"
100
- task :pdoc => [:rdoc] do
101
- Rake::SshDirPublisher.new("davidhh@comox.textdrive.com", "public_html/ar", "doc").upload
102
- end
103
-
104
-
105
64
  # Create compressed packages
106
65
 
107
66
  dist_dirs = [ "lib", "test", "examples", "dev-utils" ]
@@ -117,7 +76,7 @@ spec = Gem::Specification.new do |s|
117
76
  s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
118
77
  end
119
78
 
120
- s.add_dependency('activesupport', '= 1.0.2' + PKG_BUILD)
79
+ s.add_dependency('activesupport', '= 1.0.3' + PKG_BUILD)
121
80
 
122
81
  s.files.delete "test/fixtures/fixture_database.sqlite"
123
82
  s.files.delete "test/fixtures/fixture_database_2.sqlite"
@@ -143,20 +102,130 @@ Rake::GemPackageTask.new(spec) do |p|
143
102
  end
144
103
 
145
104
 
146
- task :lines do
147
- lines = 0
148
- codelines = 0
149
- Dir.foreach("lib/active_record") { |file_name|
150
- next unless file_name =~ /.*rb/
151
-
152
- f = File.open("lib/active_record/" + file_name)
105
+ # Publishing ------------------------------------------------------
153
106
 
154
- while line = f.gets
155
- lines += 1
156
- next if line =~ /^\s*$/
157
- next if line =~ /^\s*#/
158
- codelines += 1
159
- end
160
- }
161
- puts "Lines #{lines}, LOC #{codelines}"
107
+ desc "Publish the beta gem"
108
+ task :pgem => [:package] do
109
+ Rake::SshFilePublisher.new("davidhh@comox.textdrive.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
110
+ `ssh davidhh@comox.textdrive.com './gemupdate.sh'`
111
+ end
112
+
113
+ desc "Publish the API documentation"
114
+ task :pdoc => [:rdoc] do
115
+ Rake::SshDirPublisher.new("davidhh@comox.textdrive.com", "public_html/ar", "doc").upload
162
116
  end
117
+
118
+ desc "Publish the release files to RubyForge."
119
+ task :release => [:package] do
120
+ files = ["gem", "tgz", "zip"].map { |ext| "pkg/#{PKG_FILE_NAME}.#{ext}" }
121
+
122
+ if RUBY_FORGE_PROJECT then
123
+ require 'net/http'
124
+ require 'open-uri'
125
+
126
+ project_uri = "http://rubyforge.org/projects/#{RUBY_FORGE_PROJECT}/"
127
+ project_data = open(project_uri) { |data| data.read }
128
+ group_id = project_data[/[?&]group_id=(\d+)/, 1]
129
+ raise "Couldn't get group id" unless group_id
130
+
131
+ # This echos password to shell which is a bit sucky
132
+ if ENV["RUBY_FORGE_PASSWORD"]
133
+ password = ENV["RUBY_FORGE_PASSWORD"]
134
+ else
135
+ print "#{RUBY_FORGE_USER}@rubyforge.org's password: "
136
+ password = STDIN.gets.chomp
137
+ end
138
+
139
+ login_response = Net::HTTP.start("rubyforge.org", 80) do |http|
140
+ data = [
141
+ "login=1",
142
+ "form_loginname=#{RUBY_FORGE_USER}",
143
+ "form_pw=#{password}"
144
+ ].join("&")
145
+ http.post("/account/login.php", data)
146
+ end
147
+
148
+ cookie = login_response["set-cookie"]
149
+ raise "Login failed" unless cookie
150
+ headers = { "Cookie" => cookie }
151
+
152
+ release_uri = "http://rubyforge.org/frs/admin/?group_id=#{group_id}"
153
+ release_data = open(release_uri, headers) { |data| data.read }
154
+ package_id = release_data[/[?&]package_id=(\d+)/, 1]
155
+ raise "Couldn't get package id" unless package_id
156
+
157
+ first_file = true
158
+ release_id = ""
159
+
160
+ files.each do |filename|
161
+ basename = File.basename(filename)
162
+ file_ext = File.extname(filename)
163
+ file_data = File.open(filename, "rb") { |file| file.read }
164
+
165
+ puts "Releasing #{basename}..."
166
+
167
+ release_response = Net::HTTP.start("rubyforge.org", 80) do |http|
168
+ release_date = Time.now.strftime("%Y-%m-%d %H:%M")
169
+ type_map = {
170
+ ".zip" => "3000",
171
+ ".tgz" => "3110",
172
+ ".gz" => "3110",
173
+ ".gem" => "1400"
174
+ }; type_map.default = "9999"
175
+ type = type_map[file_ext]
176
+ boundary = "rubyqMY6QN9bp6e4kS21H4y0zxcvoor"
177
+
178
+ query_hash = if first_file then
179
+ {
180
+ "group_id" => group_id,
181
+ "package_id" => package_id,
182
+ "release_name" => RELEASE_NAME,
183
+ "release_date" => release_date,
184
+ "type_id" => type,
185
+ "processor_id" => "8000", # Any
186
+ "release_notes" => "",
187
+ "release_changes" => "",
188
+ "preformatted" => "1",
189
+ "submit" => "1"
190
+ }
191
+ else
192
+ {
193
+ "group_id" => group_id,
194
+ "release_id" => release_id,
195
+ "package_id" => package_id,
196
+ "step2" => "1",
197
+ "type_id" => type,
198
+ "processor_id" => "8000", # Any
199
+ "submit" => "Add This File"
200
+ }
201
+ end
202
+
203
+ query = "?" + query_hash.map do |(name, value)|
204
+ [name, URI.encode(value)].join("=")
205
+ end.join("&")
206
+
207
+ data = [
208
+ "--" + boundary,
209
+ "Content-Disposition: form-data; name=\"userfile\"; filename=\"#{basename}\"",
210
+ "Content-Type: application/octet-stream",
211
+ "Content-Transfer-Encoding: binary",
212
+ "", file_data, ""
213
+ ].join("\x0D\x0A")
214
+
215
+ release_headers = headers.merge(
216
+ "Content-Type" => "multipart/form-data; boundary=#{boundary}"
217
+ )
218
+
219
+ target = first_file ? "/frs/admin/qrs.php" : "/frs/admin/editrelease.php"
220
+ http.post(target + query, data, release_headers)
221
+ end
222
+
223
+ if first_file then
224
+ release_id = release_response.body[/release_id=(\d+)/, 1]
225
+ raise("Couldn't get release id") unless release_id
226
+ end
227
+
228
+ first_file = false
229
+ end
230
+ end
231
+ end
@@ -11,7 +11,7 @@ class TestColumnAlias < Test::Unit::TestCase
11
11
  assert_equal(records[0].keys[0], "pk")
12
12
  end
13
13
  else
14
- records = topic.connection.select_all("SELECT id AS pk FROM topics LIMIT 1")
14
+ records = topic.connection.select_all("SELECT id AS pk FROM topics")
15
15
  assert_equal(records[0].keys[0], "pk")
16
16
  end
17
17
  end
@@ -4,6 +4,9 @@ require 'logger'
4
4
 
5
5
  ActiveRecord::Base.logger = Logger.new("debug.log")
6
6
 
7
+ db1 = 'activerecord_unittest'
8
+ db2 = 'activerecord_unittest2'
9
+
7
10
  ActiveRecord::Base.establish_connection(
8
11
  :adapter => "sqlserver",
9
12
  :host => "localhost",
@@ -2,10 +2,11 @@ require 'abstract_unit'
2
2
  require 'fixtures/company'
3
3
  require 'fixtures/topic'
4
4
  require 'fixtures/entrant'
5
+ require 'fixtures/developer'
5
6
 
6
7
  class FinderTest < Test::Unit::TestCase
7
8
  fixtures :companies, :topics, :entrants, :developers
8
-
9
+
9
10
  def test_find
10
11
  assert_equal(@topics["first"]["title"], Topic.find(1).title)
11
12
  end
@@ -43,10 +44,10 @@ class FinderTest < Test::Unit::TestCase
43
44
  def test_find_all_with_prepared_limit_and_offset
44
45
  if ActiveRecord::ConnectionAdapters.const_defined? :OracleAdapter
45
46
  if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OracleAdapter)
46
- assert_raises(ArgumentError) { Entrant.find_all nil, "id ASC", ["? OFFSET ?", 2, 1] }
47
+ assert_raises(ArgumentError) { Entrant.find_all nil, "id ASC", [2, 1] }
47
48
  end
48
49
  else
49
- entrants = Entrant.find_all nil, "id ASC", ["? OFFSET ?", 2, 1]
50
+ entrants = Entrant.find_all nil, "id ASC", [2, 1]
50
51
 
51
52
  assert_equal(2, entrants.size)
52
53
  assert_equal(@entrants["second"]["name"], entrants.first.name)
@@ -256,11 +257,11 @@ class FinderTest < Test::Unit::TestCase
256
257
  assert_equal first_five_developers, Developer.find_all(nil, 'id ASC', [5])
257
258
  assert_equal no_developers, Developer.find_all(nil, 'id ASC', [0])
258
259
  end
259
-
260
+
260
261
  def test_find_all_with_limit_and_offset
261
262
  first_three_developers = Developer.find_all nil, 'id ASC', [3, 0]
262
263
  second_three_developers = Developer.find_all nil, 'id ASC', [3, 3]
263
- last_two_developers = Developer.find_all nil, 'id ASC', [3, 8]
264
+ last_two_developers = Developer.find_all nil, 'id ASC', [2, 8]
264
265
 
265
266
  assert_equal 3, first_three_developers.length
266
267
  assert_equal 3, second_three_developers.length
@@ -14,5 +14,4 @@ DROP TABLE colnametests;
14
14
  DROP TABLE mixins;
15
15
  DROP TABLE people;
16
16
  DROP TABLE binaries;
17
- DROP TABLE computers;
18
-
17
+ DROP TABLE computers;
@@ -1,88 +1,79 @@
1
1
  CREATE TABLE accounts (
2
- id int NOT NULL IDENTITY(1, 1),
2
+ id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
3
3
  firm_id int default NULL,
4
- credit_limit int default NULL,
5
- PRIMARY KEY (id)
4
+ credit_limit int default NULL
6
5
  )
7
6
 
8
7
  CREATE TABLE companies (
9
- id int NOT NULL IDENTITY(1, 1),
8
+ id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
10
9
  type varchar(50) default NULL,
11
10
  ruby_type varchar(50) default NULL,
12
11
  firm_id int default NULL,
13
12
  name varchar(50) default NULL,
14
13
  client_of int default NULL,
15
- companies_count int default 0,
16
- rating int default 1,
17
- PRIMARY KEY (id)
14
+ rating int default 1
18
15
  )
19
16
 
20
17
  CREATE TABLE topics (
21
- id int NOT NULL IDENTITY(1, 1),
18
+ id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
22
19
  title varchar(255) default NULL,
23
20
  author_name varchar(255) default NULL,
24
21
  author_email_address varchar(255) default NULL,
25
22
  written_on datetime default NULL,
23
+ bonus_time datetime default NULL,
26
24
  last_read datetime default NULL,
27
25
  content text,
28
26
  approved tinyint default 1,
29
27
  replies_count int default 0,
30
28
  parent_id int default NULL,
31
- type varchar(50) default NULL,
32
- PRIMARY KEY (id)
29
+ type varchar(50) default NULL
33
30
  )
34
31
 
35
32
  CREATE TABLE developers (
36
- id int NOT NULL IDENTITY(1, 1),
33
+ id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
37
34
  name varchar(100) default NULL,
38
- PRIMARY KEY (id)
35
+ salary int default 70000
39
36
  );
40
37
 
41
38
  CREATE TABLE projects (
42
- id int NOT NULL IDENTITY(1, 1),
43
- name varchar(100) default NULL,
44
- salary int default 70000,
45
- PRIMARY KEY (id)
39
+ id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
40
+ name varchar(100) default NULL
46
41
  );
47
42
 
48
43
  CREATE TABLE developers_projects (
49
44
  developer_id int NOT NULL,
50
- project_id int NOT NULL
45
+ project_id int NOT NULL,
46
+ joined_on datetime default NULL
51
47
  );
52
48
 
53
49
  CREATE TABLE customers (
54
- id int NOT NULL IDENTITY(1, 1),
50
+ id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
55
51
  name varchar(100) default NULL,
56
52
  balance int default 0,
57
53
  address_street varchar(100) default NULL,
58
54
  address_city varchar(100) default NULL,
59
55
  address_country varchar(100) default NULL,
60
- gps_location varchar(100) default NULL,
61
- PRIMARY KEY (id)
56
+ gps_location varchar(100) default NULL
62
57
  );
63
58
 
64
59
  CREATE TABLE movies (
65
- movieid int NOT NULL IDENTITY(1, 1),
66
- name varchar(100) default NULL,
67
- PRIMARY KEY (movieid)
60
+ movieid int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
61
+ name varchar(100) default NULL
68
62
  );
69
63
 
70
64
  CREATE TABLE subscribers (
71
- nick varchar(100) NOT NULL,
72
- name varchar(100) default NULL,
73
- PRIMARY KEY (nick)
65
+ nick varchar(100) NOT NULL PRIMARY KEY,
66
+ name varchar(100) default NULL
74
67
  );
75
68
 
76
69
  CREATE TABLE booleantests (
77
- id int NOT NULL IDENTITY(1, 1),
78
- value integer default NULL,
79
- PRIMARY KEY (id)
70
+ id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
71
+ value bit default NULL
80
72
  );
81
73
 
82
74
  CREATE TABLE auto_id_tests (
83
- auto_id int NOT NULL IDENTITY(1, 1),
84
- value int default NULL,
85
- PRIMARY KEY (auto_id)
75
+ auto_id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
76
+ value int default NULL
86
77
  );
87
78
 
88
79
  CREATE TABLE entrants (
@@ -92,22 +83,20 @@ CREATE TABLE entrants (
92
83
  );
93
84
 
94
85
  CREATE TABLE colnametests (
95
- id int NOT NULL IDENTITY(1, 1),
96
- [references] int NOT NULL,
97
- PRIMARY KEY (id)
86
+ id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
87
+ [references] int NOT NULL
98
88
  );
99
89
 
100
90
  CREATE TABLE mixins (
101
- id int NOT NULL IDENTITY(1, 1),
102
- parent_id int default NULL,
103
- type varchar(40) default NULL,
91
+ id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
92
+ parent_id int default NULL,
104
93
  pos int default NULL,
105
- lft int default NULL,
106
- rgt int default NULL,
107
- root_id int default NULL,
108
94
  created_at datetime default NULL,
109
95
  updated_at datetime default NULL,
110
- PRIMARY KEY (id)
96
+ lft int default NULL,
97
+ rgt int default NULL,
98
+ root_id int default NULL,
99
+ type varchar(40) default NULL
111
100
  );
112
101
 
113
102
  CREATE TABLE people (
@@ -118,14 +107,12 @@ CREATE TABLE people (
118
107
  );
119
108
 
120
109
  CREATE TABLE binaries (
121
- id int NOT NULL IDENTITY(1, 1),
122
- data image NULL,
123
- PRIMARY KEY (id)
110
+ id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
111
+ data image NULL
124
112
  );
125
113
 
126
114
  CREATE TABLE computers (
127
- id int NOT NULL IDENTITY(1, 1),
128
- developer int NOT NULL,
129
- PRIMARY KEY (id)
115
+ id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
116
+ developer int NOT NULL
130
117
  );
131
118
 
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.8
3
3
  specification_version: 1
4
4
  name: activerecord
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.9.0
7
- date: 2005-03-22
6
+ version: 1.9.1
7
+ date: 2005-03-27
8
8
  summary: Implements the ActiveRecord pattern for ORM.
9
9
  require_paths:
10
10
  - lib
@@ -142,8 +142,6 @@ files:
142
142
  - test/fixtures/developers_projects.yml
143
143
  - test/fixtures/entrant.rb
144
144
  - test/fixtures/entrants.yml
145
- - test/fixtures/fixture_database.sqlite
146
- - test/fixtures/fixture_database_2.sqlite
147
145
  - test/fixtures/migrations
148
146
  - test/fixtures/mixin.rb
149
147
  - test/fixtures/mixins.yml
@@ -227,5 +225,5 @@ dependencies:
227
225
  -
228
226
  - "="
229
227
  - !ruby/object:Gem::Version
230
- version: 1.0.2
228
+ version: 1.0.3
231
229
  version: