redis_orm 0.6 → 0.6.1
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 +4 -0
- data/Gemfile +8 -0
- data/Manifest +3 -1
- data/README.md +15 -3
- data/Rakefile +1 -6
- data/benchmarks/sortable_benchmark.rb +45 -0
- data/lib/redis_orm/redis_orm.rb +130 -24
- data/redis_orm.gemspec +9 -9
- data/test/exceptions_test.rb +5 -0
- data/test/options_test.rb +16 -15
- data/test/{order_test.rb → sortable_test.rb} +65 -4
- metadata +26 -26
    
        data/CHANGELOG
    CHANGED
    
    | @@ -1,3 +1,7 @@ | |
| 1 | 
            +
            v0.6.1 [05-12-2011]
         | 
| 2 | 
            +
            * rewritten sortable functionality for attributes which values are strings
         | 
| 3 | 
            +
            * added Gemfile to the project, improved tests
         | 
| 4 | 
            +
             | 
| 1 5 | 
             
            v0.6 [12-09-2011]
         | 
| 2 6 | 
             
            * added equality operator for object, #to_s method for inspecting objects, #find! which could throw RecordNotFound error
         | 
| 3 7 | 
             
            * added self.descendants class method which returns all inherited from RedisOrm::Base classes
         | 
    
        data/Gemfile
    ADDED
    
    
    
        data/Manifest
    CHANGED
    
    | @@ -1,8 +1,10 @@ | |
| 1 1 | 
             
            CHANGELOG
         | 
| 2 | 
            +
            Gemfile
         | 
| 2 3 | 
             
            LICENSE
         | 
| 3 4 | 
             
            Manifest
         | 
| 4 5 | 
             
            README.md
         | 
| 5 6 | 
             
            Rakefile
         | 
| 7 | 
            +
            benchmarks/sortable_benchmark.rb
         | 
| 6 8 | 
             
            lib/redis_orm.rb
         | 
| 7 9 | 
             
            lib/redis_orm/active_model_behavior.rb
         | 
| 8 10 | 
             
            lib/redis_orm/associations/belongs_to.rb
         | 
| @@ -24,9 +26,9 @@ test/exceptions_test.rb | |
| 24 26 | 
             
            test/has_one_has_many_test.rb
         | 
| 25 27 | 
             
            test/indices_test.rb
         | 
| 26 28 | 
             
            test/options_test.rb
         | 
| 27 | 
            -
            test/order_test.rb
         | 
| 28 29 | 
             
            test/polymorphic_test.rb
         | 
| 29 30 | 
             
            test/redis.conf
         | 
| 31 | 
            +
            test/sortable_test.rb
         | 
| 30 32 | 
             
            test/test_helper.rb
         | 
| 31 33 | 
             
            test/uuid_as_id_test.rb
         | 
| 32 34 | 
             
            test/validations_test.rb
         | 
    
        data/README.md
    CHANGED
    
    | @@ -29,15 +29,25 @@ end | |
| 29 29 |  | 
| 30 30 | 
             
            ## Installing redis_orm
         | 
| 31 31 |  | 
| 32 | 
            +
            stable release:
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            ```sh
         | 
| 32 35 | 
             
            gem install redis_orm
         | 
| 36 | 
            +
            ```
         | 
| 33 37 |  | 
| 34 | 
            -
            or 
         | 
| 38 | 
            +
            or edge version:
         | 
| 35 39 |  | 
| 40 | 
            +
            ```sh
         | 
| 36 41 | 
             
            git clone git://github.com/german/redis_orm.git
         | 
| 37 | 
            -
             | 
| 38 42 | 
             
            cd redis_orm
         | 
| 39 | 
            -
             | 
| 40 43 | 
             
            bundle install
         | 
| 44 | 
            +
            ```
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            To run the tests you should have redis installed already. Please check [Redis download/installation page](http://redis.io/download).
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            ```sh
         | 
| 49 | 
            +
            rake test
         | 
| 50 | 
            +
            ```
         | 
| 41 51 |  | 
| 42 52 | 
             
            ## Setting up a connection to the redis server
         | 
| 43 53 |  | 
| @@ -84,6 +94,8 @@ Following options are available in property declaration: | |
| 84 94 |  | 
| 85 95 | 
             
                if *true* is specified then you could sort records by this property later
         | 
| 86 96 |  | 
| 97 | 
            +
            *Note* that when you're using :sortable option redis_orm maintains one additional list per attribute. Also note that the #create method could be 3 times slower in some cases (this will be improved in future releases), while the #find performance is basically the same (see the "benchmarks/sortable_benchmark.rb").
         | 
| 98 | 
            +
             | 
| 87 99 | 
             
            ## Searching records by the value
         | 
| 88 100 |  | 
| 89 101 | 
             
            Usually it's done via declaring an index and using *:conditions* hash or dynamic finders. For example:
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -4,7 +4,7 @@ require 'rake' | |
| 4 4 | 
             
            #=begin
         | 
| 5 5 | 
             
            require 'echoe'
         | 
| 6 6 |  | 
| 7 | 
            -
            Echoe.new('redis_orm', '0.6') do |p|
         | 
| 7 | 
            +
            Echoe.new('redis_orm', '0.6.1') do |p|
         | 
| 8 8 | 
             
              p.description    = "ORM for Redis (advanced key-value storage) with ActiveRecord API"
         | 
| 9 9 | 
             
              p.url            = "https://github.com/german/redis_orm"
         | 
| 10 10 | 
             
              p.author         = "Dmitrii Samoilov"
         | 
| @@ -26,13 +26,8 @@ Rake::TestTask.new(:test) do |t| | |
| 26 26 | 
             
            end
         | 
| 27 27 | 
             
            =end
         | 
| 28 28 |  | 
| 29 | 
            -
            #require 'rspec/core/rake_task'
         | 
| 30 29 | 
             
            task :test do |t|
         | 
| 31 30 | 
             
              Dir['test/**/*_test.rb'].each do |file|
         | 
| 32 31 | 
             
                puts `ruby -I./lib #{file}`
         | 
| 33 32 | 
             
              end
         | 
| 34 33 | 
             
            end
         | 
| 35 | 
            -
            #task :default => :test
         | 
| 36 | 
            -
            #RSpec::Core::RakeTask.new(:spec) do |t|
         | 
| 37 | 
            -
            #  t.pattern = 'test/**/*_test.rb'
         | 
| 38 | 
            -
            #end
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            require File.expand_path(File.dirname(__FILE__) + '/../lib/redis_orm')
         | 
| 2 | 
            +
            require 'benchmark'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class User < RedisOrm::Base
         | 
| 5 | 
            +
              property :name, String
         | 
| 6 | 
            +
              property :age, Integer
         | 
| 7 | 
            +
              property :wage, Float
         | 
| 8 | 
            +
              
         | 
| 9 | 
            +
              index :name
         | 
| 10 | 
            +
              index :age
         | 
| 11 | 
            +
            end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            class SortableUser < RedisOrm::Base
         | 
| 14 | 
            +
              property :name, String, :sortable => true
         | 
| 15 | 
            +
              property :age, Integer, :sortable => true
         | 
| 16 | 
            +
              property :wage, Float, :sortable => true
         | 
| 17 | 
            +
              
         | 
| 18 | 
            +
              index :name
         | 
| 19 | 
            +
              index :age
         | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            path_to_conf = File.dirname(File.expand_path(__FILE__)) + "/../test/redis.conf"
         | 
| 23 | 
            +
            $redis_pid = spawn 'redis-server ' + path_to_conf, :out => "/dev/null"
         | 
| 24 | 
            +
            sleep(0.3) # must be some delay otherwise "Connection refused - Unable to connect to Redis"
         | 
| 25 | 
            +
            path_to_socket = File.dirname(File.expand_path(__FILE__)) + "/../redis.sock"
         | 
| 26 | 
            +
            begin
         | 
| 27 | 
            +
              $redis = Redis.new(:host => 'localhost', :path => path_to_socket)
         | 
| 28 | 
            +
            rescue => e
         | 
| 29 | 
            +
              puts 'Unable to create connection to the redis server: ' + e.message.inspect
         | 
| 30 | 
            +
              Process.kill 9, $redis_pid.to_i if $redis_pid
         | 
| 31 | 
            +
            end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            n = 100
         | 
| 34 | 
            +
            Benchmark.bmbm do |x|
         | 
| 35 | 
            +
              x.report("creating regular user:") { for i in 1..n; u = User.create(:name => "user#{i}", :age => i, :wage => 100*i); end}
         | 
| 36 | 
            +
              x.report("creating user w/ sortable attrs:") { for i in 1..n; u = SortableUser.create(:name => "user#{i}", :age => i, :wage => 100*i); end }
         | 
| 37 | 
            +
            end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            Benchmark.bmbm do |x|
         | 
| 40 | 
            +
              x.report("finding regular users:") { User.find(:all, :limit => 5, :offset => 10) }
         | 
| 41 | 
            +
              x.report("finding users w/ sortable attrs:") { SortableUser.find(:all, :limit => 5, :offset => 10, :order => [:name, :asc]) }
         | 
| 42 | 
            +
            end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            $redis.flushall if $redis
         | 
| 45 | 
            +
            Process.kill 9, $redis_pid.to_i if $redis_pid
         | 
    
        data/lib/redis_orm/redis_orm.rb
    CHANGED
    
    | @@ -193,6 +193,8 @@ module RedisOrm | |
| 193 193 | 
             
                      [options[:offset].to_i, options[:limit].to_i]
         | 
| 194 194 | 
             
                    elsif options[:limit]
         | 
| 195 195 | 
             
                      [0, options[:limit].to_i]
         | 
| 196 | 
            +
                    else
         | 
| 197 | 
            +
                      [0, -1]
         | 
| 196 198 | 
             
                    end
         | 
| 197 199 |  | 
| 198 200 | 
             
                    order_max_limit = Time.now.to_f
         | 
| @@ -214,30 +216,66 @@ module RedisOrm | |
| 214 216 | 
             
                      end
         | 
| 215 217 | 
             
                    end
         | 
| 216 218 |  | 
| 219 | 
            +
                    order_by_property_is_string = false
         | 
| 220 | 
            +
                    
         | 
| 217 221 | 
             
                    # if not array => created_at native order (in which ids were pushed to "#{model_name}:ids" set by default)
         | 
| 218 222 | 
             
                    direction = if !options[:order].blank?
         | 
| 219 | 
            -
                       | 
| 223 | 
            +
                      property = {}
         | 
| 224 | 
            +
                      dir = if options[:order].is_a?(Array)
         | 
| 225 | 
            +
                        property = @@properties[model_name].detect{|prop| prop[:name].to_s == options[:order].first.to_s}
         | 
| 220 226 | 
             
                        # for String values max limit for search key could be 1.0, but for Numeric values there's actually no limit
         | 
| 221 227 | 
             
                        order_max_limit = 100_000_000_000
         | 
| 222 228 | 
             
                        ids_key = "#{prepared_index}:#{options[:order].first}_ids"
         | 
| 223 229 | 
             
                        options[:order].size == 2 ? options[:order].last : 'asc'
         | 
| 224 230 | 
             
                      else
         | 
| 231 | 
            +
                        property = @@properties[model_name].detect{|prop| prop[:name].to_s == options[:order].to_s}
         | 
| 225 232 | 
             
                        ids_key = prepared_index
         | 
| 226 233 | 
             
                        options[:order]
         | 
| 227 234 | 
             
                      end
         | 
| 235 | 
            +
                      if property && property[:class].eql?("String") && property[:options][:sortable]
         | 
| 236 | 
            +
                        order_by_property_is_string = true
         | 
| 237 | 
            +
                      end
         | 
| 238 | 
            +
                      dir
         | 
| 228 239 | 
             
                    else
         | 
| 229 240 | 
             
                      ids_key = prepared_index
         | 
| 230 241 | 
             
                      'asc'
         | 
| 231 242 | 
             
                    end
         | 
| 232 243 |  | 
| 233 | 
            -
                    if  | 
| 234 | 
            -
                      id = $redis.get prepared_index
         | 
| 235 | 
            -
                      model_name.to_s.camelize.constantize.find(id)
         | 
| 236 | 
            -
                    else
         | 
| 244 | 
            +
                    if order_by_property_is_string
         | 
| 237 245 | 
             
                      if direction.to_s == 'desc'
         | 
| 238 | 
            -
                        $redis. | 
| 246 | 
            +
                        ids_length = $redis.llen(ids_key)
         | 
| 247 | 
            +
                        limit = if options[:offset] && options[:limit]
         | 
| 248 | 
            +
                          [(ids_length - options[:offset].to_i - options[:limit].to_i), (ids_length - options[:offset].to_i - 1)]
         | 
| 249 | 
            +
                        elsif options[:limit]
         | 
| 250 | 
            +
                          [ids_length - options[:limit].to_i, ids_length]
         | 
| 251 | 
            +
                        elsif options[:offset]
         | 
| 252 | 
            +
                          [0, (ids_length - options[:offset].to_i - 1)]
         | 
| 253 | 
            +
                        else
         | 
| 254 | 
            +
                          [0, -1]
         | 
| 255 | 
            +
                        end
         | 
| 256 | 
            +
                        $redis.lrange(ids_key, *limit).reverse.compact.collect{|id| find(id.split(':').last)}
         | 
| 257 | 
            +
                      else
         | 
| 258 | 
            +
                        limit = if options[:offset] && options[:limit]
         | 
| 259 | 
            +
                          [options[:offset].to_i, (options[:offset].to_i + options[:limit].to_i)]
         | 
| 260 | 
            +
                        elsif options[:limit]
         | 
| 261 | 
            +
                          [0, options[:limit].to_i - 1]
         | 
| 262 | 
            +
                        elsif options[:offset]
         | 
| 263 | 
            +
                          [options[:offset].to_i, -1]
         | 
| 264 | 
            +
                        else
         | 
| 265 | 
            +
                          [0, -1]
         | 
| 266 | 
            +
                        end
         | 
| 267 | 
            +
                        $redis.lrange(ids_key, *limit).compact.collect{|id| find(id.split(':').last)}
         | 
| 268 | 
            +
                      end
         | 
| 269 | 
            +
                    else
         | 
| 270 | 
            +
                      if index && index[:options][:unique]
         | 
| 271 | 
            +
                        id = $redis.get prepared_index
         | 
| 272 | 
            +
                        model_name.to_s.camelize.constantize.find(id)
         | 
| 239 273 | 
             
                      else
         | 
| 240 | 
            -
                         | 
| 274 | 
            +
                        if direction.to_s == 'desc'
         | 
| 275 | 
            +
                          $redis.zrevrangebyscore(ids_key, order_max_limit, 0, :limit => limit).compact.collect{|id| find(id)}
         | 
| 276 | 
            +
                        else
         | 
| 277 | 
            +
                          $redis.zrangebyscore(ids_key, 0, order_max_limit, :limit => limit).compact.collect{|id| find(id)}
         | 
| 278 | 
            +
                        end
         | 
| 241 279 | 
             
                      end
         | 
| 242 280 | 
             
                    end
         | 
| 243 281 | 
             
                  end
         | 
| @@ -464,12 +502,20 @@ module RedisOrm | |
| 464 502 |  | 
| 465 503 | 
             
                      prev_prop_value = instance_variable_get(:"@#{prop[:name]}_changes").first
         | 
| 466 504 | 
             
                      prop_value = instance_variable_get(:"@#{prop[:name]}")
         | 
| 467 | 
            -
             | 
| 505 | 
            +
                      # TODO DRY in destroy also
         | 
| 468 506 | 
             
                      if prop[:options][:sortable]
         | 
| 469 | 
            -
                         | 
| 470 | 
            -
             | 
| 471 | 
            -
             | 
| 472 | 
            -
                           | 
| 507 | 
            +
                        if prop[:class].eql?("String")
         | 
| 508 | 
            +
                          $redis.lrem "#{model_name}:#{prop[:name]}_ids", 1, "#{prev_prop_value}:#{@id}"
         | 
| 509 | 
            +
                          # remove id from every indexed property
         | 
| 510 | 
            +
                          @@indices[model_name].each do |index|
         | 
| 511 | 
            +
                            $redis.lrem "#{construct_prepared_index(index)}:#{prop[:name]}_ids", 1, "#{prop_value}:#{@id}"
         | 
| 512 | 
            +
                          end
         | 
| 513 | 
            +
                        else
         | 
| 514 | 
            +
                          $redis.zrem "#{model_name}:#{prop[:name]}_ids", @id
         | 
| 515 | 
            +
                          # remove id from every indexed property
         | 
| 516 | 
            +
                          @@indices[model_name].each do |index|
         | 
| 517 | 
            +
                            $redis.zrem "#{construct_prepared_index(index)}:#{prop[:name]}_ids", @id
         | 
| 518 | 
            +
                          end
         | 
| 473 519 | 
             
                        end
         | 
| 474 520 | 
             
                      end
         | 
| 475 521 |  | 
| @@ -571,18 +617,28 @@ module RedisOrm | |
| 571 617 |  | 
| 572 618 | 
             
                    # if some property need to be sortable add id of the record to the appropriate sorted set
         | 
| 573 619 | 
             
                    if prop[:options][:sortable]
         | 
| 574 | 
            -
                      property_value = instance_variable_get(:"@#{prop[:name]}")
         | 
| 575 | 
            -
                       | 
| 576 | 
            -
                         | 
| 577 | 
            -
                         | 
| 578 | 
            -
                         | 
| 579 | 
            -
                         | 
| 580 | 
            -
                         | 
| 581 | 
            -
             | 
| 582 | 
            -
             | 
| 583 | 
            -
             | 
| 584 | 
            -
                       | 
| 585 | 
            -
                         | 
| 620 | 
            +
                      property_value = instance_variable_get(:"@#{prop[:name]}").to_s
         | 
| 621 | 
            +
                      if prop[:class].eql?("String")
         | 
| 622 | 
            +
                        sortable_key = "#{model_name}:#{prop[:name]}_ids"
         | 
| 623 | 
            +
                        el_or_position_to_insert = find_position_to_insert(sortable_key, property_value)
         | 
| 624 | 
            +
                        el_or_position_to_insert == 0 ? $redis.lpush(sortable_key, "#{property_value}:#{@id}") : $redis.linsert(sortable_key, "AFTER", el_or_position_to_insert, "#{property_value}:#{@id}")
         | 
| 625 | 
            +
                        # add to every indexed property
         | 
| 626 | 
            +
                        @@indices[model_name].each do |index|
         | 
| 627 | 
            +
                          sortable_key = "#{construct_prepared_index(index)}:#{prop[:name]}_ids"
         | 
| 628 | 
            +
                          el_or_position_to_insert == 0 ? $redis.lpush(sortable_key, "#{property_value}:#{@id}") : $redis.linsert(sortable_key, "AFTER", el_or_position_to_insert, "#{property_value}:#{@id}")
         | 
| 629 | 
            +
                        end
         | 
| 630 | 
            +
                      else
         | 
| 631 | 
            +
                        score = case prop[:class]
         | 
| 632 | 
            +
                          when "Integer"; property_value.to_f
         | 
| 633 | 
            +
                          when "Float"; property_value.to_f
         | 
| 634 | 
            +
                          when "RedisOrm::Boolean"; (property_value == true ? 1.0 : 0.0)
         | 
| 635 | 
            +
                          when "Time"; property_value.to_f
         | 
| 636 | 
            +
                        end
         | 
| 637 | 
            +
                        $redis.zadd "#{model_name}:#{prop[:name]}_ids", score, @id
         | 
| 638 | 
            +
                        # add to every indexed property
         | 
| 639 | 
            +
                        @@indices[model_name].each do |index|
         | 
| 640 | 
            +
                          $redis.zadd "#{construct_prepared_index(index)}:#{prop[:name]}_ids", score, @id
         | 
| 641 | 
            +
                        end
         | 
| 586 642 | 
             
                      end
         | 
| 587 643 | 
             
                    end
         | 
| 588 644 | 
             
                  end
         | 
| @@ -612,6 +668,47 @@ module RedisOrm | |
| 612 668 | 
             
                  true # if there were no errors just return true, so *if* conditions would work
         | 
| 613 669 | 
             
                end
         | 
| 614 670 |  | 
| 671 | 
            +
                def find_position_to_insert(sortable_key, value)
         | 
| 672 | 
            +
                  end_index = $redis.llen(sortable_key)
         | 
| 673 | 
            +
             | 
| 674 | 
            +
                  return 0 if end_index == 0
         | 
| 675 | 
            +
                  
         | 
| 676 | 
            +
                  start_index = 0
         | 
| 677 | 
            +
                  pivot_index = end_index / 2
         | 
| 678 | 
            +
             | 
| 679 | 
            +
                  start_el = $redis.lindex(sortable_key, start_index)
         | 
| 680 | 
            +
                  end_el   = $redis.lindex(sortable_key, end_index - 1)
         | 
| 681 | 
            +
                  pivot_el = $redis.lindex(sortable_key, pivot_index)
         | 
| 682 | 
            +
             | 
| 683 | 
            +
                  while start_index != end_index
         | 
| 684 | 
            +
                    # aa..ab..ac..bd <- ad
         | 
| 685 | 
            +
                    if start_el.split(':').first > value # Michael > Abe
         | 
| 686 | 
            +
                      return 0
         | 
| 687 | 
            +
                    elsif end_el.split(':').first < value # Abe < Todd 
         | 
| 688 | 
            +
                      return end_el
         | 
| 689 | 
            +
                    elsif start_el.split(':').first == value # Abe == Abe
         | 
| 690 | 
            +
                      return start_el
         | 
| 691 | 
            +
                    elsif pivot_el.split(':').first == value # Todd == Todd
         | 
| 692 | 
            +
                      return pivot_el
         | 
| 693 | 
            +
                    elsif end_el.split(':').first == value
         | 
| 694 | 
            +
                      return end_el
         | 
| 695 | 
            +
                    elsif (start_el.split(':').first < value) && (pivot_el.split(':').first > value)
         | 
| 696 | 
            +
                      start_index = start_index
         | 
| 697 | 
            +
                      prev_pivot_index = pivot_index
         | 
| 698 | 
            +
                      pivot_index = start_index + ((end_index - pivot_index) / 2)
         | 
| 699 | 
            +
                      end_index   = prev_pivot_index
         | 
| 700 | 
            +
                    elsif (pivot_el.split(':').first < value) && (end_el.split(':').first > value) # M < V && Y > V
         | 
| 701 | 
            +
                      start_index = pivot_index
         | 
| 702 | 
            +
                      pivot_index = pivot_index + ((end_index - pivot_index) / 2)
         | 
| 703 | 
            +
                      end_index   = end_index          
         | 
| 704 | 
            +
                    end
         | 
| 705 | 
            +
                    start_el = $redis.lindex(sortable_key, start_index)
         | 
| 706 | 
            +
                    end_el   = $redis.lindex(sortable_key, end_index - 1)
         | 
| 707 | 
            +
                    pivot_el = $redis.lindex(sortable_key, pivot_index)
         | 
| 708 | 
            +
                  end
         | 
| 709 | 
            +
                  start_el
         | 
| 710 | 
            +
                end
         | 
| 711 | 
            +
                
         | 
| 615 712 | 
             
                def update_attributes(attributes)
         | 
| 616 713 | 
             
                  if attributes.is_a?(Hash)
         | 
| 617 714 | 
             
                    attributes.each do |key, value|
         | 
| @@ -632,7 +729,16 @@ module RedisOrm | |
| 632 729 | 
             
                  end
         | 
| 633 730 |  | 
| 634 731 | 
             
                  @@properties[model_name].each do |prop|
         | 
| 732 | 
            +
                    property_value = instance_variable_get(:"@#{prop[:name]}").to_s
         | 
| 635 733 | 
             
                    $redis.hdel("#{model_name}:#{@id}", prop[:name].to_s)
         | 
| 734 | 
            +
                    
         | 
| 735 | 
            +
                    if prop[:options][:sortable]
         | 
| 736 | 
            +
                      if prop[:class].eql?("String")
         | 
| 737 | 
            +
                        $redis.lrem "#{model_name}:#{prop[:name]}_ids", 1, "#{property_value}:#{@id}"
         | 
| 738 | 
            +
                      else
         | 
| 739 | 
            +
                        $redis.zrem "#{model_name}:#{prop[:name]}_ids", @id
         | 
| 740 | 
            +
                      end
         | 
| 741 | 
            +
                    end
         | 
| 636 742 | 
             
                  end
         | 
| 637 743 |  | 
| 638 744 | 
             
                  $redis.zrem "#{model_name}:ids", @id
         | 
    
        data/redis_orm.gemspec
    CHANGED
    
    | @@ -2,22 +2,22 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            Gem::Specification.new do |s|
         | 
| 4 4 | 
             
              s.name = %q{redis_orm}
         | 
| 5 | 
            -
              s.version = "0.6"
         | 
| 5 | 
            +
              s.version = "0.6.1"
         | 
| 6 6 |  | 
| 7 7 | 
             
              s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
         | 
| 8 | 
            -
              s.authors = [ | 
| 9 | 
            -
              s.date = %q{2011- | 
| 8 | 
            +
              s.authors = [%q{Dmitrii Samoilov}]
         | 
| 9 | 
            +
              s.date = %q{2011-12-05}
         | 
| 10 10 | 
             
              s.description = %q{ORM for Redis (advanced key-value storage) with ActiveRecord API}
         | 
| 11 11 | 
             
              s.email = %q{germaninthetown@gmail.com}
         | 
| 12 | 
            -
              s.extra_rdoc_files = [ | 
| 13 | 
            -
              s.files = [ | 
| 12 | 
            +
              s.extra_rdoc_files = [%q{CHANGELOG}, %q{LICENSE}, %q{README.md}, %q{lib/redis_orm.rb}, %q{lib/redis_orm/active_model_behavior.rb}, %q{lib/redis_orm/associations/belongs_to.rb}, %q{lib/redis_orm/associations/has_many.rb}, %q{lib/redis_orm/associations/has_many_helper.rb}, %q{lib/redis_orm/associations/has_many_proxy.rb}, %q{lib/redis_orm/associations/has_one.rb}, %q{lib/redis_orm/redis_orm.rb}, %q{lib/redis_orm/utils.rb}]
         | 
| 13 | 
            +
              s.files = [%q{CHANGELOG}, %q{Gemfile}, %q{LICENSE}, %q{Manifest}, %q{README.md}, %q{Rakefile}, %q{benchmarks/sortable_benchmark.rb}, %q{lib/redis_orm.rb}, %q{lib/redis_orm/active_model_behavior.rb}, %q{lib/redis_orm/associations/belongs_to.rb}, %q{lib/redis_orm/associations/has_many.rb}, %q{lib/redis_orm/associations/has_many_helper.rb}, %q{lib/redis_orm/associations/has_many_proxy.rb}, %q{lib/redis_orm/associations/has_one.rb}, %q{lib/redis_orm/redis_orm.rb}, %q{lib/redis_orm/utils.rb}, %q{redis_orm.gemspec}, %q{test/association_indices_test.rb}, %q{test/associations_test.rb}, %q{test/atomicity_test.rb}, %q{test/basic_functionality_test.rb}, %q{test/callbacks_test.rb}, %q{test/changes_array_test.rb}, %q{test/dynamic_finders_test.rb}, %q{test/exceptions_test.rb}, %q{test/has_one_has_many_test.rb}, %q{test/indices_test.rb}, %q{test/options_test.rb}, %q{test/polymorphic_test.rb}, %q{test/redis.conf}, %q{test/sortable_test.rb}, %q{test/test_helper.rb}, %q{test/uuid_as_id_test.rb}, %q{test/validations_test.rb}]
         | 
| 14 14 | 
             
              s.homepage = %q{https://github.com/german/redis_orm}
         | 
| 15 | 
            -
              s.rdoc_options = [ | 
| 16 | 
            -
              s.require_paths = [ | 
| 15 | 
            +
              s.rdoc_options = [%q{--line-numbers}, %q{--inline-source}, %q{--title}, %q{Redis_orm}, %q{--main}, %q{README.md}]
         | 
| 16 | 
            +
              s.require_paths = [%q{lib}]
         | 
| 17 17 | 
             
              s.rubyforge_project = %q{redis_orm}
         | 
| 18 | 
            -
              s.rubygems_version = %q{1.6 | 
| 18 | 
            +
              s.rubygems_version = %q{1.8.6}
         | 
| 19 19 | 
             
              s.summary = %q{ORM for Redis (advanced key-value storage) with ActiveRecord API}
         | 
| 20 | 
            -
              s.test_files = [ | 
| 20 | 
            +
              s.test_files = [%q{test/atomicity_test.rb}, %q{test/indices_test.rb}, %q{test/sortable_test.rb}, %q{test/uuid_as_id_test.rb}, %q{test/test_helper.rb}, %q{test/options_test.rb}, %q{test/callbacks_test.rb}, %q{test/exceptions_test.rb}, %q{test/associations_test.rb}, %q{test/validations_test.rb}, %q{test/basic_functionality_test.rb}, %q{test/dynamic_finders_test.rb}, %q{test/changes_array_test.rb}, %q{test/polymorphic_test.rb}, %q{test/association_indices_test.rb}, %q{test/has_one_has_many_test.rb}]
         | 
| 21 21 |  | 
| 22 22 | 
             
              if s.respond_to? :specification_version then
         | 
| 23 23 | 
             
                s.specification_version = 3
         | 
    
        data/test/exceptions_test.rb
    CHANGED
    
    | @@ -47,4 +47,9 @@ describe "exceptions test" do | |
| 47 47 | 
             
                User.find(12).should == nil
         | 
| 48 48 | 
             
                lambda{ User.find! 12 }.should raise_error(RedisOrm::RecordNotFound)
         | 
| 49 49 | 
             
              end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              it "should throw an exception if there was an error while creating object with #create! method" do
         | 
| 52 | 
            +
                jigsaw = Jigsaw.create :title => "jigsaw"
         | 
| 53 | 
            +
                lambda { User.create!(:name => "John", :age => 44, :profile => jigsaw) }.should raise_error(RedisOrm::TypeMismatchError)
         | 
| 54 | 
            +
              end
         | 
| 50 55 | 
             
            end
         | 
    
        data/test/options_test.rb
    CHANGED
    
    | @@ -69,7 +69,7 @@ describe "test options" do | |
| 69 69 | 
             
                Album.find(:all, :limit => 1).size.should == 1
         | 
| 70 70 | 
             
                Album.find!(:all, :limit => 1).size.should == 1
         | 
| 71 71 | 
             
              end
         | 
| 72 | 
            -
             | 
| 72 | 
            +
             | 
| 73 73 | 
             
              it "should return correct array when :limit and :offset options are provided" do
         | 
| 74 74 | 
             
                @album.photos.count.should == 0
         | 
| 75 75 |  | 
| @@ -88,8 +88,9 @@ describe "test options" do | |
| 88 88 | 
             
                @album.photos.find(:all, :limit => 1, :offset => 1).size.should == 1
         | 
| 89 89 |  | 
| 90 90 | 
             
                Photo.find(:all).size.should == 2
         | 
| 91 | 
            -
             | 
| 92 | 
            -
                Photo.find(: | 
| 91 | 
            +
             | 
| 92 | 
            +
                Photo.find(:first).should == @photo1
         | 
| 93 | 
            +
                Photo.find(:last).should == @photo2
         | 
| 93 94 |  | 
| 94 95 | 
             
                Photo.find(:all, :conditions => {:image => "facepalm.jpg"}).size.should == 1
         | 
| 95 96 | 
             
                Photo.find(:all, :conditions => {:image => "boobs.png"}).size.should == 1
         | 
| @@ -97,25 +98,25 @@ describe "test options" do | |
| 97 98 | 
             
                Photo.find(:all, :conditions => {:image => "facepalm.jpg", :image_type => "jpg"}).size.should == 1
         | 
| 98 99 | 
             
                Photo.find(:all, :conditions => {:image => "boobs.png", :image_type => "png"}).size.should == 1
         | 
| 99 100 |  | 
| 100 | 
            -
                Photo.find(:first, :conditions => {:image => "facepalm.jpg"}). | 
| 101 | 
            -
                Photo.find(:first, :conditions => {:image => "boobs.png"}). | 
| 101 | 
            +
                Photo.find(:first, :conditions => {:image => "facepalm.jpg"}).should == @photo1
         | 
| 102 | 
            +
                Photo.find(:first, :conditions => {:image => "boobs.png"}).should == @photo2
         | 
| 102 103 |  | 
| 103 | 
            -
                Photo.find(:first, :conditions => {:image => "facepalm.jpg", :image_type => "jpg"}). | 
| 104 | 
            -
                Photo.find(:first, :conditions => {:image => "boobs.png", :image_type => "png"}). | 
| 104 | 
            +
                Photo.find(:first, :conditions => {:image => "facepalm.jpg", :image_type => "jpg"}).should == @photo1
         | 
| 105 | 
            +
                Photo.find(:first, :conditions => {:image => "boobs.png", :image_type => "png"}).should == @photo2
         | 
| 105 106 |  | 
| 106 | 
            -
                Photo.find(:last, :conditions => {:image => "facepalm.jpg"}). | 
| 107 | 
            -
                Photo.find(:last, :conditions => {:image => "boobs.png"}). | 
| 107 | 
            +
                Photo.find(:last, :conditions => {:image => "facepalm.jpg"}).should == @photo1
         | 
| 108 | 
            +
                Photo.find(:last, :conditions => {:image => "boobs.png"}).should == @photo2
         | 
| 108 109 |  | 
| 109 | 
            -
                Photo.find(:last, :conditions => {:image => "facepalm.jpg", :image_type => "jpg"}). | 
| 110 | 
            -
                Photo.find(:last, :conditions => {:image => "boobs.png", :image_type => "png"}). | 
| 110 | 
            +
                Photo.find(:last, :conditions => {:image => "facepalm.jpg", :image_type => "jpg"}).should == @photo1
         | 
| 111 | 
            +
                Photo.find(:last, :conditions => {:image => "boobs.png", :image_type => "png"}).should == @photo2
         | 
| 111 112 | 
             
              end
         | 
| 112 113 |  | 
| 113 114 | 
             
              it "should accept options for #first and #last methods" do
         | 
| 114 | 
            -
                Photo.first(:conditions => {:image => "facepalm.jpg"}). | 
| 115 | 
            -
                Photo.first(:conditions => {:image => "boobs.png"}). | 
| 115 | 
            +
                Photo.first(:conditions => {:image => "facepalm.jpg"}).should == @photo1
         | 
| 116 | 
            +
                Photo.first(:conditions => {:image => "boobs.png"}).should == @photo2
         | 
| 116 117 |  | 
| 117 | 
            -
                Photo.last(:conditions => {:image => "facepalm.jpg", :image_type => "jpg"}). | 
| 118 | 
            -
                Photo.last(:conditions => {:image => "boobs.png", :image_type => "png"}). | 
| 118 | 
            +
                Photo.last(:conditions => {:image => "facepalm.jpg", :image_type => "jpg"}).should == @photo1
         | 
| 119 | 
            +
                Photo.last(:conditions => {:image => "boobs.png", :image_type => "png"}).should == @photo2
         | 
| 119 120 | 
             
              end
         | 
| 120 121 |  | 
| 121 122 | 
             
              it "should correctly save boolean values" do
         | 
| @@ -11,6 +11,11 @@ class User < RedisOrm::Base | |
| 11 11 | 
             
              index :age
         | 
| 12 12 | 
             
            end
         | 
| 13 13 |  | 
| 14 | 
            +
            class SortableUser < RedisOrm::Base
         | 
| 15 | 
            +
              property :name, String, :sortable => true
         | 
| 16 | 
            +
              index :name
         | 
| 17 | 
            +
            end
         | 
| 18 | 
            +
             | 
| 14 19 | 
             
            describe "test options" do
         | 
| 15 20 | 
             
              before(:each) do
         | 
| 16 21 | 
             
                @dan     = User.create :name => "Daniel",   :age => 26, :wage => 40000.0,   :address => "Bellevue"
         | 
| @@ -18,9 +23,9 @@ describe "test options" do | |
| 18 23 | 
             
                @michael = User.create :name => "Michael",  :age => 25, :wage => 60000.0,   :address => "Bellevue"
         | 
| 19 24 | 
             
                @todd    = User.create :name => "Todd",     :age => 22, :wage => 30000.0,   :address => "Bellevue"
         | 
| 20 25 | 
             
              end
         | 
| 21 | 
            -
             | 
| 26 | 
            +
             | 
| 22 27 | 
             
              it "should return records in specified order" do
         | 
| 23 | 
            -
                $redis. | 
| 28 | 
            +
                $redis.llen("user:name_ids").to_i.should == User.count
         | 
| 24 29 | 
             
                $redis.zcard("user:age_ids").to_i.should == User.count
         | 
| 25 30 | 
             
                $redis.zcard("user:wage_ids").to_i.should == User.count
         | 
| 26 31 |  | 
| @@ -49,11 +54,11 @@ describe "test options" do | |
| 49 54 | 
             
                User.find(:all, :conditions => {:name => "Abe"}, :order => [:wage, :desc]).should == [@abe, @abe2]
         | 
| 50 55 | 
             
                User.find(:all, :conditions => {:name => "Abe"}, :order => [:wage, :asc]).should == [@abe2, @abe]
         | 
| 51 56 | 
             
              end
         | 
| 52 | 
            -
             | 
| 57 | 
            +
             | 
| 53 58 | 
             
              it "should update keys after the persisted object was edited and sort properly" do
         | 
| 54 59 | 
             
                @abe.update_attributes :name => "Zed", :age => 12, :wage => 10.0, :address => "Santa Fe"
         | 
| 55 60 |  | 
| 56 | 
            -
                $redis. | 
| 61 | 
            +
                $redis.llen("user:name_ids").to_i.should == User.count
         | 
| 57 62 | 
             
                $redis.zcard("user:age_ids").to_i.should == User.count
         | 
| 58 63 | 
             
                $redis.zcard("user:wage_ids").to_i.should == User.count
         | 
| 59 64 |  | 
| @@ -66,4 +71,60 @@ describe "test options" do | |
| 66 71 | 
             
                User.find(:all, :order => [:wage, :asc]).should == [@abe, @todd, @dan, @michael]
         | 
| 67 72 | 
             
                User.find(:all, :order => [:wage, :desc]).should == [@michael, @dan, @todd, @abe]
         | 
| 68 73 | 
             
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              it "should update keys after the persisted object was deleted and sort properly" do
         | 
| 76 | 
            +
                user_count = User.count
         | 
| 77 | 
            +
                @abe.destroy
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                $redis.llen("user:name_ids").to_i.should == user_count - 1
         | 
| 80 | 
            +
                $redis.zcard("user:age_ids").to_i.should == user_count - 1
         | 
| 81 | 
            +
                $redis.zcard("user:wage_ids").to_i.should == user_count - 1
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                User.find(:all, :order => [:name, :asc]).should == [@dan, @michael, @todd]
         | 
| 84 | 
            +
                User.find(:all, :order => [:name, :desc]).should == [@todd, @michael, @dan]
         | 
| 85 | 
            +
                    
         | 
| 86 | 
            +
                User.find(:all, :order => [:age, :asc]).should == [@todd, @michael, @dan]
         | 
| 87 | 
            +
                User.find(:all, :order => [:age, :desc]).should == [@dan, @michael, @todd]
         | 
| 88 | 
            +
                
         | 
| 89 | 
            +
                User.find(:all, :order => [:wage, :asc]).should == [@todd, @dan, @michael]
         | 
| 90 | 
            +
                User.find(:all, :order => [:wage, :desc]).should == [@michael, @dan, @todd]
         | 
| 91 | 
            +
              end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
              it "should sort objects with more than 3-4 symbols" do
         | 
| 94 | 
            +
                vladislav = User.create :name => "Vladislav", :age => 19, :wage => 120.0
         | 
| 95 | 
            +
                vladimir = User.create :name => "Vladimir", :age => 22, :wage => 220.5
         | 
| 96 | 
            +
                vlad = User.create :name => "Vlad", :age => 29, :wage => 1200.0
         | 
| 97 | 
            +
                
         | 
| 98 | 
            +
                User.find(:all, :order => [:name, :desc], :limit => 3).should == [vladislav, vladimir, vlad]
         | 
| 99 | 
            +
                User.find(:all, :order => [:name, :desc], :limit => 2, :offset => 4).should == [@michael, @dan]
         | 
| 100 | 
            +
                User.find(:all, :order => [:name, :desc], :offset => 3).should == [@todd, @michael, @dan, @abe]
         | 
| 101 | 
            +
                User.find(:all, :order => [:name, :desc]).should == [vladislav, vladimir, vlad, @todd, @michael, @dan, @abe]
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                User.find(:all, :order => [:name, :asc], :limit => 3, :offset => 4).should == [vlad, vladimir, vladislav]
         | 
| 104 | 
            +
                User.find(:all, :order => [:name, :asc], :offset => 3).should == [@todd, vlad, vladimir, vladislav]
         | 
| 105 | 
            +
                User.find(:all, :order => [:name, :asc], :limit => 3).should == [@abe, @dan, @michael]
         | 
| 106 | 
            +
                User.find(:all, :order => [:name, :asc]).should == [@abe, @dan, @michael, @todd, vlad, vladimir, vladislav]
         | 
| 107 | 
            +
              end
         | 
| 108 | 
            +
             | 
| 109 | 
            +
              it "should properly handle multiple users with almost the same names" do
         | 
| 110 | 
            +
                users = []
         | 
| 111 | 
            +
                20.times{|i| users << SortableUser.create(:name => "user#{i}") }
         | 
| 112 | 
            +
                SortableUser.all(:order => [:name, :asc]).should == users.sort{|n,m| n.name <=> m.name}
         | 
| 113 | 
            +
              end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
              it "should properly handle multiple users with almost the same names (descending order)" do
         | 
| 116 | 
            +
                rev_users = []
         | 
| 117 | 
            +
                20.times{|i| rev_users << SortableUser.create(:name => "user#{i}") }
         | 
| 118 | 
            +
                SortableUser.all(:order => [:name, :desc]).should == rev_users.sort{|n,m| n.name <=> m.name}.reverse
         | 
| 119 | 
            +
              end
         | 
| 120 | 
            +
             | 
| 121 | 
            +
              it "should properly store records with the same names" do
         | 
| 122 | 
            +
                users = []
         | 
| 123 | 
            +
                users << SortableUser.create(:name => "user#1")
         | 
| 124 | 
            +
                users << SortableUser.create(:name => "user#2")
         | 
| 125 | 
            +
                users << SortableUser.create(:name => "user#1")
         | 
| 126 | 
            +
                users << SortableUser.create(:name => "user#2")
         | 
| 127 | 
            +
                SortableUser.all(:order => [:name, :desc]).should == users.sort{|n,m| n.name <=> m.name}.reverse
         | 
| 128 | 
            +
                SortableUser.all(:order => [:name, :asc]).should == users.sort{|n,m| n.name <=> m.name}
         | 
| 129 | 
            +
              end
         | 
| 69 130 | 
             
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: redis_orm
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version:  | 
| 4 | 
            +
              version: 0.6.1
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,12 +9,11 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2011- | 
| 13 | 
            -
            default_executable: 
         | 
| 12 | 
            +
            date: 2011-12-05 00:00:00.000000000 Z
         | 
| 14 13 | 
             
            dependencies:
         | 
| 15 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 16 15 | 
             
              name: activesupport
         | 
| 17 | 
            -
              requirement: & | 
| 16 | 
            +
              requirement: &17352020 !ruby/object:Gem::Requirement
         | 
| 18 17 | 
             
                none: false
         | 
| 19 18 | 
             
                requirements:
         | 
| 20 19 | 
             
                - - ! '>='
         | 
| @@ -22,10 +21,10 @@ dependencies: | |
| 22 21 | 
             
                    version: 3.0.0
         | 
| 23 22 | 
             
              type: :runtime
         | 
| 24 23 | 
             
              prerelease: false
         | 
| 25 | 
            -
              version_requirements: * | 
| 24 | 
            +
              version_requirements: *17352020
         | 
| 26 25 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 27 26 | 
             
              name: activemodel
         | 
| 28 | 
            -
              requirement: & | 
| 27 | 
            +
              requirement: &17367880 !ruby/object:Gem::Requirement
         | 
| 29 28 | 
             
                none: false
         | 
| 30 29 | 
             
                requirements:
         | 
| 31 30 | 
             
                - - ! '>='
         | 
| @@ -33,10 +32,10 @@ dependencies: | |
| 33 32 | 
             
                    version: 3.0.0
         | 
| 34 33 | 
             
              type: :runtime
         | 
| 35 34 | 
             
              prerelease: false
         | 
| 36 | 
            -
              version_requirements: * | 
| 35 | 
            +
              version_requirements: *17367880
         | 
| 37 36 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 38 37 | 
             
              name: redis
         | 
| 39 | 
            -
              requirement: & | 
| 38 | 
            +
              requirement: &17367380 !ruby/object:Gem::Requirement
         | 
| 40 39 | 
             
                none: false
         | 
| 41 40 | 
             
                requirements:
         | 
| 42 41 | 
             
                - - ! '>='
         | 
| @@ -44,10 +43,10 @@ dependencies: | |
| 44 43 | 
             
                    version: 2.2.0
         | 
| 45 44 | 
             
              type: :runtime
         | 
| 46 45 | 
             
              prerelease: false
         | 
| 47 | 
            -
              version_requirements: * | 
| 46 | 
            +
              version_requirements: *17367380
         | 
| 48 47 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 49 48 | 
             
              name: uuid
         | 
| 50 | 
            -
              requirement: & | 
| 49 | 
            +
              requirement: &17366880 !ruby/object:Gem::Requirement
         | 
| 51 50 | 
             
                none: false
         | 
| 52 51 | 
             
                requirements:
         | 
| 53 52 | 
             
                - - ! '>='
         | 
| @@ -55,10 +54,10 @@ dependencies: | |
| 55 54 | 
             
                    version: 2.3.2
         | 
| 56 55 | 
             
              type: :runtime
         | 
| 57 56 | 
             
              prerelease: false
         | 
| 58 | 
            -
              version_requirements: * | 
| 57 | 
            +
              version_requirements: *17366880
         | 
| 59 58 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 60 59 | 
             
              name: rspec
         | 
| 61 | 
            -
              requirement: & | 
| 60 | 
            +
              requirement: &17366380 !ruby/object:Gem::Requirement
         | 
| 62 61 | 
             
                none: false
         | 
| 63 62 | 
             
                requirements:
         | 
| 64 63 | 
             
                - - ! '>='
         | 
| @@ -66,7 +65,7 @@ dependencies: | |
| 66 65 | 
             
                    version: 2.5.0
         | 
| 67 66 | 
             
              type: :development
         | 
| 68 67 | 
             
              prerelease: false
         | 
| 69 | 
            -
              version_requirements: * | 
| 68 | 
            +
              version_requirements: *17366380
         | 
| 70 69 | 
             
            description: ORM for Redis (advanced key-value storage) with ActiveRecord API
         | 
| 71 70 | 
             
            email: germaninthetown@gmail.com
         | 
| 72 71 | 
             
            executables: []
         | 
| @@ -86,10 +85,12 @@ extra_rdoc_files: | |
| 86 85 | 
             
            - lib/redis_orm/utils.rb
         | 
| 87 86 | 
             
            files:
         | 
| 88 87 | 
             
            - CHANGELOG
         | 
| 88 | 
            +
            - Gemfile
         | 
| 89 89 | 
             
            - LICENSE
         | 
| 90 90 | 
             
            - Manifest
         | 
| 91 91 | 
             
            - README.md
         | 
| 92 92 | 
             
            - Rakefile
         | 
| 93 | 
            +
            - benchmarks/sortable_benchmark.rb
         | 
| 93 94 | 
             
            - lib/redis_orm.rb
         | 
| 94 95 | 
             
            - lib/redis_orm/active_model_behavior.rb
         | 
| 95 96 | 
             
            - lib/redis_orm/associations/belongs_to.rb
         | 
| @@ -111,13 +112,12 @@ files: | |
| 111 112 | 
             
            - test/has_one_has_many_test.rb
         | 
| 112 113 | 
             
            - test/indices_test.rb
         | 
| 113 114 | 
             
            - test/options_test.rb
         | 
| 114 | 
            -
            - test/order_test.rb
         | 
| 115 115 | 
             
            - test/polymorphic_test.rb
         | 
| 116 116 | 
             
            - test/redis.conf
         | 
| 117 | 
            +
            - test/sortable_test.rb
         | 
| 117 118 | 
             
            - test/test_helper.rb
         | 
| 118 119 | 
             
            - test/uuid_as_id_test.rb
         | 
| 119 120 | 
             
            - test/validations_test.rb
         | 
| 120 | 
            -
            has_rdoc: true
         | 
| 121 121 | 
             
            homepage: https://github.com/german/redis_orm
         | 
| 122 122 | 
             
            licenses: []
         | 
| 123 123 | 
             
            post_install_message: 
         | 
| @@ -144,24 +144,24 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 144 144 | 
             
                  version: '1.2'
         | 
| 145 145 | 
             
            requirements: []
         | 
| 146 146 | 
             
            rubyforge_project: redis_orm
         | 
| 147 | 
            -
            rubygems_version: 1.6 | 
| 147 | 
            +
            rubygems_version: 1.8.6
         | 
| 148 148 | 
             
            signing_key: 
         | 
| 149 149 | 
             
            specification_version: 3
         | 
| 150 150 | 
             
            summary: ORM for Redis (advanced key-value storage) with ActiveRecord API
         | 
| 151 151 | 
             
            test_files:
         | 
| 152 | 
            +
            - test/atomicity_test.rb
         | 
| 153 | 
            +
            - test/indices_test.rb
         | 
| 154 | 
            +
            - test/sortable_test.rb
         | 
| 155 | 
            +
            - test/uuid_as_id_test.rb
         | 
| 156 | 
            +
            - test/test_helper.rb
         | 
| 152 157 | 
             
            - test/options_test.rb
         | 
| 153 | 
            -
            - test/ | 
| 158 | 
            +
            - test/callbacks_test.rb
         | 
| 159 | 
            +
            - test/exceptions_test.rb
         | 
| 154 160 | 
             
            - test/associations_test.rb
         | 
| 155 161 | 
             
            - test/validations_test.rb
         | 
| 156 | 
            -
            - test/ | 
| 162 | 
            +
            - test/basic_functionality_test.rb
         | 
| 163 | 
            +
            - test/dynamic_finders_test.rb
         | 
| 164 | 
            +
            - test/changes_array_test.rb
         | 
| 157 165 | 
             
            - test/polymorphic_test.rb
         | 
| 158 | 
            -
            - test/uuid_as_id_test.rb
         | 
| 159 | 
            -
            - test/atomicity_test.rb
         | 
| 160 | 
            -
            - test/exceptions_test.rb
         | 
| 161 166 | 
             
            - test/association_indices_test.rb
         | 
| 162 167 | 
             
            - test/has_one_has_many_test.rb
         | 
| 163 | 
            -
            - test/order_test.rb
         | 
| 164 | 
            -
            - test/indices_test.rb
         | 
| 165 | 
            -
            - test/changes_array_test.rb
         | 
| 166 | 
            -
            - test/callbacks_test.rb
         | 
| 167 | 
            -
            - test/basic_functionality_test.rb
         |