<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,5 +1,12 @@
 *SVN*
 
+* 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:
+
+    Developer.find_all nil, 'id ASC', 5      # return the first five developers 
+    Developer.find_all nil, 'id ASC', [3, 8] # return three developers, starting from #8 and forward
+    
+  This doesn't yet work with the DB2 or MS SQL adapters. Patches to make that happen are encouraged. 
+
 * Added alias_method :to_param, :id to Base, such that Active Record objects to be used as URL parameters in Action Pack automatically #812 [Nicholas Seckar/Sam Stephenson]
 
 * Improved the performance of the OCI8 adapter for Oracle #723 [pilx/gjenkins]</diff>
      <filename>activerecord/CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -346,16 +346,18 @@ module ActiveRecord #:nodoc:
       # table in the database. The +conditions+ can be used to narrow the selection of objects (WHERE-part),
       # such as by &quot;color = 'red'&quot;, and arrangement of the selection can be done through +orderings+ (ORDER BY-part),
       # such as by &quot;last_name, first_name DESC&quot;. A maximum of returned objects and their offset can be specified in 
-      # +limit+ (LIMIT...OFFSET-part). Examples:
+      # +limit+ with either just a single integer as the limit or as an array with the first element as the limit, 
+      # the second as the offset. Examples:
       #   Project.find_all &quot;category = 'accounts'&quot;, &quot;last_accessed DESC&quot;, 15
-      #   Project.find_all [&quot;category = ?&quot;, category_name], &quot;created ASC&quot;, [&quot;? OFFSET ?&quot;, 15, 20]
+      #   Project.find_all [&quot;category = ?&quot;, category_name], &quot;created ASC&quot;, [15, 20]
       def find_all(conditions = nil, orderings = nil, limit = nil, joins = nil)
         sql  = &quot;SELECT * FROM #{table_name} &quot; 
         sql &lt;&lt; &quot;#{joins} &quot; if joins
         add_conditions!(sql, conditions)
         sql &lt;&lt; &quot;ORDER BY #{orderings} &quot; unless orderings.nil?
 
-        connection.add_limit!(sql, sanitize_sql(limit)) unless limit.nil?
+        limit = sanitize_sql(limit) if limit.is_a? Array and limit.first.is_a? String
+        connection.add_limit!(sql, limit) if limit
 
         find_by_sql(sql)
       end</diff>
      <filename>activerecord/lib/active_record/base.rb</filename>
    </modified>
    <modified>
      <diff>@@ -353,10 +353,22 @@ module ActiveRecord
       def structure_dump() end
 
       def add_limit!(sql, limit)
+        if limit.is_a? Array
+          limit, offset = *limit
+          add_limit_with_offset!(sql, limit.to_i, offset.to_i)
+        else
+          add_limit_without_offset!(sql, limit)
+        end
+      end
+        
+      def add_limit_with_offset!(sql, limit, offset)
+        sql &lt;&lt; &quot; LIMIT #{limit} OFFSET #{offset}&quot;
+      end
+      
+      def add_limit_without_offset!(sql, limit)
         sql &lt;&lt; &quot; LIMIT #{limit}&quot;
       end
 
-
       def initialize_schema_information
         begin
           execute &quot;CREATE TABLE schema_info (version #{native_database_types[:integer][:name]}#{native_database_types[:integer][:limit]})&quot;</diff>
      <filename>activerecord/lib/active_record/connection_adapters/abstract_adapter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -89,7 +89,11 @@ begin
           s.gsub(/'/, &quot;''&quot;) # ' (for ruby-mode)
         end
 
-        def add_limit!(sql, limit)
+        def add_limit_with_offset!(sql, limit, offset)
+          raise ArgumentError, 'add_limit_with_offset! not implemented'
+        end
+
+        def add_limit_without_offset!(sql, limit)
           sql &lt;&lt; &quot; FETCH FIRST #{limit} ROWS ONLY&quot;
         end
 </diff>
      <filename>activerecord/lib/active_record/connection_adapters/db2_adapter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -172,7 +172,11 @@ module ActiveRecord
           structure += select_one(&quot;SHOW CREATE TABLE #{table.to_a.first.last}&quot;)[&quot;Create Table&quot;] + &quot;;\n\n&quot;
         end
       end
- 
+      
+      def add_limit_with_offset!(sql, limit, offset)
+        sql &lt;&lt; &quot; LIMIT #{offset}, #{limit}&quot;
+      end
+       
       def recreate_database(name)
         drop_database(name)
         create_database(name)</diff>
      <filename>activerecord/lib/active_record/connection_adapters/mysql_adapter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -182,10 +182,6 @@ begin
         alias :update :execute
         alias :delete :execute
 
-        def add_limit!(sql, limit)
-          sql &lt;&lt; &quot;LIMIT=&quot; &lt;&lt; limit.to_s
-        end
-
         def begin_db_transaction()
           @connection.autocommit = false
         end</diff>
      <filename>activerecord/lib/active_record/connection_adapters/oci_adapter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -253,19 +253,12 @@ EOL
         &quot;[#{name}]&quot;
       end
 
-      def add_limit!(sql, limit)
-        if sql =~ /LIMIT/i
-          limit = sql.slice!(/LIMIT.*/).gsub(/LIMIT.(.*)$/, '\1')
-        end
-        if !limit.nil?
-          limit_amount = limit.to_s.include?(&quot;OFFSET&quot;) ? get_offset_amount(limit) : Array.new([limit])
-          order_by = sql.include?(&quot;ORDER BY&quot;) ? get_order_by(sql.sub(/.*ORDER\sBY./, &quot;&quot;)) : nil
-          if limit_amount.size == 2
-            sql.gsub!(/SELECT/i, &quot;SELECT * FROM ( SELECT TOP #{limit_amount[0]} * FROM ( SELECT TOP #{limit_amount[1]}&quot;)&lt;&lt;&quot; ) AS tmp1 ORDER BY #{order_by[1]} ) AS tmp2 ORDER BY #{order_by[0]}&quot;
-          else
-            sql.gsub!(/SELECT/i, &quot;SELECT TOP #{limit_amount[0]}&quot;)
-          end
-        end
+      def add_limit_with_offset!(sql, limit, offset)
+        raise ArgumentError, 'add_limit_with_offset! not implemented'
+      end
+
+      def add_limit_without_offset!(sql, limit)
+        raise ArgumentError, 'add_limit_without_offset! not implemented'
       end
 
       def recreate_database(name)</diff>
      <filename>activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,7 +4,7 @@ require 'fixtures/topic'
 require 'fixtures/entrant'
 
 class FinderTest &lt; Test::Unit::TestCase
-  fixtures :companies, :topics, :entrants
+  fixtures :companies, :topics, :entrants, :developers
   
   def test_find
     assert_equal(@topics[&quot;first&quot;][&quot;title&quot;], Topic.find(1).title)
@@ -244,6 +244,33 @@ class FinderTest &lt; Test::Unit::TestCase
     assert_raises(ActiveRecord::StatementInvalid) { Topic.find_by_sql &quot;select 1 from badtable&quot; }
   end
 
+  def test_find_all_with_limit
+    first_five_developers = Developer.find_all nil, 'id ASC', 5
+    assert_equal 5, first_five_developers.length
+    assert_equal 'David', first_five_developers.first.name
+    assert_equal 'fixture_5', first_five_developers.last.name
+    
+    no_developers = Developer.find_all nil, 'id ASC', 0
+    assert_equal 0, no_developers.length
+    
+    assert_equal first_five_developers, Developer.find_all(nil, 'id ASC', [5])
+    assert_equal no_developers, Developer.find_all(nil, 'id ASC', [0])
+  end
+  
+  def test_find_all_with_limit_and_offset
+    first_three_developers = Developer.find_all nil, 'id ASC', [3, 0]
+    second_three_developers = Developer.find_all nil, 'id ASC', [3, 3]
+    last_two_developers = Developer.find_all nil, 'id ASC', [3, 8]
+    
+    assert_equal 3, first_three_developers.length
+    assert_equal 3, second_three_developers.length
+    assert_equal 2, last_two_developers.length
+    
+    assert_equal 'David', first_three_developers.first.name
+    assert_equal 'fixture_4', second_three_developers.first.name
+    assert_equal 'fixture_9', last_two_developers.first.name
+  end
+
   protected
     def bind(statement, *vars)
       if vars.first.is_a?(Hash)</diff>
      <filename>activerecord/test/finder_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>9fe45f31ebeb772fdd1bc850c12cd465463e2ef7</id>
    </parent>
  </parents>
  <author>
    <name>David Heinemeier Hansson</name>
    <login>dhh</login>
    <email>david@loudthinking.com</email>
  </author>
  <url>http://github.com/rails/rails/commit/ee8d110068e958b400987b5f224e14e292fd0558</url>
  <id>ee8d110068e958b400987b5f224e14e292fd0558</id>
  <committed-date>2005-03-20T13:56:50-08:00</committed-date>
  <authored-date>2005-03-20T13:56:50-08:00</authored-date>
  <message>Added adapter independent limit clause as a two-element array with the first being the limit, the second being the offset #795 [Sam Stephenson]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@944 5ecf4fe2-1ee6-0310-87b1-e25e094e27de</message>
  <tree>a94385c7b5cddb6704d2e6d53aa8097bd5363198</tree>
  <committer>
    <name>David Heinemeier Hansson</name>
    <login>dhh</login>
    <email>david@loudthinking.com</email>
  </committer>
</commit>
