Project

General

Profile

« Previous | Next » 

Revision 12687

Added by Toshi MARUYAMA over 11 years ago

View differences:

trunk/lib/plugins/awesome_nested_set/init.rb
1
require File.dirname(__FILE__) + '/lib/awesome_nested_set'
trunk/lib/plugins/awesome_nested_set/.travis.yml
1
before_install: gem install bundler --pre
1
language: ruby
2 2
notifications:
3 3
  email:
4 4
    - [email protected]
5
script: bundle exec rspec spec
5 6
env:
6 7
  - DB=sqlite3
7 8
  - DB=sqlite3mem
9
  - DB=postgresql
10
  - DB=mysql
8 11
rvm:
12
  - 2.0.0
13
  - 1.9.3
9 14
  - 1.8.7
10
  - 1.9.2
11
  - 1.9.3
12
  - rbx
13
  - jruby
15
  - rbx-19mode
16
  - jruby-19mode
17
  - rbx-18mode
18
  - jruby-18mode
14 19
gemfile:
15 20
  - gemfiles/Gemfile.rails-3.0.rb
16 21
  - gemfiles/Gemfile.rails-3.1.rb
17
  - gemfiles/Gemfile.rails-3.2.rb
22
  - gemfiles/Gemfile.rails-3.2.rb
trunk/lib/plugins/awesome_nested_set/CHANGELOG
1
2.1.6
2
* Fixed rebuild! when there is a default_scope with order [Adrian Serafin]
3
* Testing with stable bundler, ruby 2.0, MySQL and PostgreSQL [Philip Arndt]
4
* Optimized move_to for large trees [ericsmith66]
5

  
1 6
2.1.5
2 7
* Worked around issues where AR#association wasn't present on Rails 3.0.x. [Philip Arndt]
3 8
* Adds option 'order_column' which defaults to 'left_column_name'. [gudata]
trunk/lib/plugins/awesome_nested_set/Rakefile
4 4
require 'bundler/setup'
5 5
require 'awesome_nested_set/version'
6 6

  
7
require "rspec/core/rake_task"
8
RSpec::Core::RakeTask.new(:spec)
9

  
10 7
task :default => :spec
11 8

  
9
task :spec do
10
  %w(3.0 3.1 3.2).each do |rails_version|
11
    puts "\n" + (cmd = "BUNDLE_GEMFILE='gemfiles/Gemfile.rails-#{rails_version}.rb' bundle exec rspec spec")
12
    system cmd
13
  end
14
end
15

  
12 16
task :build do
13 17
  system "gem build awesome_nested_set.gemspec"
14 18
end
trunk/lib/plugins/awesome_nested_set/awesome_nested_set.gemspec
1 1
# -*- encoding: utf-8 -*-
2
lib = File.expand_path('../lib/', __FILE__)
3
$:.unshift lib unless $:.include?(lib)
4
require 'awesome_nested_set/version'
2
require File.expand_path('../lib/awesome_nested_set/version', __FILE__)
5 3

  
6 4
Gem::Specification.new do |s|
7 5
  s.name = %q{awesome_nested_set}
......
9 7
  s.authors = ["Brandon Keepers", "Daniel Morrison", "Philip Arndt"]
10 8
  s.description = %q{An awesome nested set implementation for Active Record}
11 9
  s.email = %q{[email protected]}
12
  s.extra_rdoc_files = [
13
    "README.rdoc"
14
  ]
10
  s.extra_rdoc_files = %w[README.rdoc]
15 11
  s.files = Dir.glob("lib/**/*") + %w(MIT-LICENSE README.rdoc CHANGELOG)
16 12
  s.homepage = %q{http://github.com/collectiveidea/awesome_nested_set}
17 13
  s.rdoc_options = ["--main", "README.rdoc", "--inline-source", "--line-numbers"]
18 14
  s.require_paths = ["lib"]
19 15
  s.rubygems_version = %q{1.3.6}
20 16
  s.summary = %q{An awesome nested set implementation for Active Record}
17
  s.license = %q{MIT}
18

  
21 19
  s.add_runtime_dependency 'activerecord', '>= 3.0.0'
22
  s.add_development_dependency 'rspec-rails', '~> 2.8'
20

  
21
  s.add_development_dependency 'rspec-rails', '~> 2.12'
22
  s.add_development_dependency 'rake', '~> 10'
23
  s.add_development_dependency 'combustion', '>= 0.3.3'
23 24
end
trunk/lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb
181 181
          # Rebuilds the left & rights if unset or invalid.
182 182
          # Also very useful for converting from acts_as_tree.
183 183
          def rebuild!(validate_nodes = true)
184
            # Don't rebuild a valid tree.
185
            return true if valid?
184
            # default_scope with order may break database queries so we do all operation without scope
185
            unscoped do
186
              # Don't rebuild a valid tree.
187
              return true if valid?
186 188

  
187
            scope = lambda{|node|}
188
            if acts_as_nested_set_options[:scope]
189
              scope = lambda{|node|
190
                scope_column_names.inject(""){|str, column_name|
191
                  str << "AND #{connection.quote_column_name(column_name)} = #{connection.quote(node.send(column_name.to_sym))} "
189
              scope = lambda{|node|}
190
              if acts_as_nested_set_options[:scope]
191
                scope = lambda{|node|
192
                  scope_column_names.inject(""){|str, column_name|
193
                    str << "AND #{connection.quote_column_name(column_name)} = #{connection.quote(node.send(column_name.to_sym))} "
194
                  }
192 195
                }
193
              }
194
            end
195
            indices = {}
196
              end
197
              indices = {}
196 198

  
197
            set_left_and_rights = lambda do |node|
198
              # set left
199
              node[left_column_name] = indices[scope.call(node)] += 1
200
              # find
201
              where(["#{quoted_parent_column_full_name} = ? #{scope.call(node)}", node]).order("#{quoted_left_column_full_name}, #{quoted_right_column_full_name}, id").each{|n| set_left_and_rights.call(n) }
202
              # set right
203
              node[right_column_name] = indices[scope.call(node)] += 1
204
              node.save!(:validate => validate_nodes)
205
            end
199
              set_left_and_rights = lambda do |node|
200
                # set left
201
                node[left_column_name] = indices[scope.call(node)] += 1
202
                # find
203
                where(["#{quoted_parent_column_full_name} = ? #{scope.call(node)}", node]).order("#{quoted_left_column_full_name}, #{quoted_right_column_full_name}, id").each{|n| set_left_and_rights.call(n) }
204
                # set right
205
                node[right_column_name] = indices[scope.call(node)] += 1
206
                node.save!(:validate => validate_nodes)
207
              end
206 208

  
207
            # Find root node(s)
208
            root_nodes = where("#{quoted_parent_column_full_name} IS NULL").order("#{quoted_left_column_full_name}, #{quoted_right_column_full_name}, id").each do |root_node|
209
              # setup index for this scope
210
              indices[scope.call(root_node)] ||= 0
211
              set_left_and_rights.call(root_node)
209
              # Find root node(s)
210
              root_nodes = where("#{quoted_parent_column_full_name} IS NULL").order("#{quoted_left_column_full_name}, #{quoted_right_column_full_name}, id").each do |root_node|
211
                # setup index for this scope
212
                indices[scope.call(root_node)] ||= 0
213
                set_left_and_rights.call(root_node)
214
              end
212 215
            end
213 216
          end
214 217

  
......
590 593
              ["#{quoted_right_column_name} = (#{quoted_right_column_name} - ?)", diff]
591 594
            )
592 595

  
593
            # Reload is needed because children may have updated their parent (self) during deletion.
594
            reload
595 596
            # Don't allow multiple calls to destroy to corrupt the set
596 597
            self.skip_before_destroy = true
597 598
          end
......
654 655
                else          target[parent_column_name]
655 656
              end
656 657

  
657
              self.nested_set_scope.update_all([
658
              where_statement = ["not (#{quoted_left_column_name} = CASE " +
659
                                     "WHEN #{quoted_left_column_name} BETWEEN :a AND :b " +
660
                                     "THEN #{quoted_left_column_name} + :d - :b " +
661
                                     "WHEN #{quoted_left_column_name} BETWEEN :c AND :d " +
662
                                     "THEN #{quoted_left_column_name} + :a - :c " +
663
                                     "ELSE #{quoted_left_column_name} END AND " +
664
                                     "#{quoted_right_column_name} = CASE " +
665
                                     "WHEN #{quoted_right_column_name} BETWEEN :a AND :b " +
666
                                     "THEN #{quoted_right_column_name} + :d - :b " +
667
                                     "WHEN #{quoted_right_column_name} BETWEEN :c AND :d " +
668
                                     "THEN #{quoted_right_column_name} + :a - :c " +
669
                                     "ELSE #{quoted_right_column_name} END AND " +
670
                                     "#{quoted_parent_column_name} = CASE " +
671
                                     "WHEN #{self.class.base_class.primary_key} = :id THEN :new_parent " +
672
                                     "ELSE #{quoted_parent_column_name} END)" ,
673
                                 {:a => a, :b => b, :c => c, :d => d, :id => self.id, :new_parent => new_parent}    ]
674

  
675

  
676

  
677

  
678
              self.nested_set_scope.where(*where_statement).update_all([
658 679
                "#{quoted_left_column_name} = CASE " +
659 680
                  "WHEN #{quoted_left_column_name} BETWEEN :a AND :b " +
660 681
                    "THEN #{quoted_left_column_name} + :d - :b " +
trunk/lib/plugins/awesome_nested_set/lib/awesome_nested_set/version.rb
1 1
module AwesomeNestedSet
2
  VERSION = '2.1.5' unless defined?(::AwesomeNestedSet::VERSION)
2
  VERSION = '2.1.6' unless defined?(::AwesomeNestedSet::VERSION)
3 3
end
trunk/lib/plugins/awesome_nested_set/spec/awesome_nested_set/helper_spec.rb
1 1
require 'spec_helper'
2
require 'awesome_nested_set/helper'
2 3

  
3 4
describe "Helper" do
4 5
  include CollectiveIdea::Acts::NestedSet::Helper
trunk/lib/plugins/awesome_nested_set/spec/awesome_nested_set_spec.rb
1006 1006
    end
1007 1007
  end
1008 1008

  
1009
  describe 'rebuilding tree with a default scope ordering' do
1010
    it "doesn't throw exception" do
1011
      expect { Position.rebuild! }.not_to raise_error
1012
    end
1013
  end
1014

  
1009 1015
  describe 'creating roots with a default scope ordering' do
1010 1016
    it "assigns rgt and lft correctly" do
1011 1017
      alpha = Order.create(:name => 'Alpha')
trunk/lib/plugins/awesome_nested_set/spec/db/database.yml
6 6
  database: ":memory:"
7 7
postgresql:
8 8
  adapter: postgresql
9
  encoding: unicode
10
  database: awesome_nested_set_plugin_test
11
  pool: 5
9 12
  username: postgres
10 13
  password: postgres
11
  database: awesome_nested_set_plugin_test
12
  min_messages: ERROR
14
  min_messages: warning
13 15
mysql:
14 16
  adapter: mysql2
15 17
  host: localhost
16 18
  username: root
17
  password: 
19
  password:
18 20
  database: awesome_nested_set_plugin_test
19 21
## Add DB Configuration to run Oracle tests
20 22
oracle:
21 23
  adapter: oracle_enhanced
22 24
  host: localhost
23 25
  username: awesome_nested_set_dev
24
  password: 
26
  password:
25 27
  database: xe
trunk/lib/plugins/awesome_nested_set/spec/db/schema.rb
56 56
    t.column :depth, :integer
57 57
  end
58 58

  
59
  create_table :positions, :force => true do |t|
60
    t.column :name, :string
61
    t.column :parent_id, :integer
62
    t.column :lft, :integer
63
    t.column :rgt, :integer
64
    t.column :depth, :integer
65
    t.column :position, :integer
66
  end
67

  
59 68
  create_table :no_depths, :force => true do |t|
60 69
    t.column :name, :string
61 70
    t.column :parent_id, :integer
trunk/lib/plugins/awesome_nested_set/spec/spec_helper.rb
1
$:.unshift(File.dirname(__FILE__) + '/../lib')
2 1
plugin_test_dir = File.dirname(__FILE__)
3 2

  
4 3
require 'rubygems'
5 4
require 'bundler/setup'
6 5

  
7
require 'rspec'
8 6
require 'logger'
9

  
10
require 'active_support'
11
require 'active_model'
12 7
require 'active_record'
13
require 'action_controller'
14

  
15
require 'awesome_nested_set'
16

  
17 8
ActiveRecord::Base.logger = Logger.new(plugin_test_dir + "/debug.log")
18 9

  
19 10
require 'yaml'
20 11
require 'erb'
21 12
ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(plugin_test_dir + "/db/database.yml")).result)
22
ActiveRecord::Base.establish_connection(ENV["DB"] || "sqlite3mem")
13
ActiveRecord::Base.establish_connection(ENV["DB"] ||= "sqlite3mem")
23 14
ActiveRecord::Migration.verbose = false
15

  
16
require 'combustion/database'
17
Combustion::Database.create_database(ActiveRecord::Base.configurations[ENV["DB"]])
24 18
load(File.join(plugin_test_dir, "db", "schema.rb"))
25 19

  
20
require 'awesome_nested_set'
26 21
require 'support/models'
27 22

  
23
require 'action_controller'
28 24
require 'rspec/rails'
29 25
RSpec.configure do |config|
30 26
  config.fixture_path = "#{plugin_test_dir}/fixtures"
31 27
  config.use_transactional_fixtures = true
28
  config.after(:suite) do
29
    unless /sqlite/ === ENV['DB']
30
      Combustion::Database.drop_database(ActiveRecord::Base.configurations[ENV['DB']])
31
    end
32
  end
32 33
end
trunk/lib/plugins/awesome_nested_set/spec/support/models.rb
85 85
  default_scope order(:name)
86 86
end
87 87

  
88
class Position < ActiveRecord::Base
89
  acts_as_nested_set
90

  
91
  default_scope order(:position)
92
end
93

  
88 94
class NoDepth < ActiveRecord::Base
89 95
  acts_as_nested_set
90 96
end

Also available in: Unified diff