Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

added simple db-helper to work around the db differences

  • Loading branch information...
commit d0eb96071797b3cf65b1b79d08976f0eb1db4c85 1 parent 252056d
@kronn kronn authored
View
4 lib/simple_nested_set.rb
@@ -16,6 +16,8 @@ module Move
autoload :Impossible, 'simple_nested_set/move/protection'
autoload :Inconsistent, 'simple_nested_set/move/protection'
end
+
+ autoload :DbHelper, 'simple_nested_set/db_helper.rb'
end
-ActiveRecord::Base.send :extend, SimpleNestedSet::ActMacro
+ActiveRecord::Base.send :extend, SimpleNestedSet::ActMacro
View
20 lib/simple_nested_set/db_helper.rb
@@ -0,0 +1,20 @@
+module SimpleNestedSet
+ module DbHelper
+ module_function
+
+ # return a database-specific 'GROUP_CONCAT'-statement, ready to be
+ # inserted into arel.project()
+ def group_concat(database = :no_database, field = 'slug', separator = '/')
+ case database.to_sym
+ when :sqlite, :sqlite3
+ "GROUP_CONCAT(#{field}, '#{separator}')"
+ when :mysql
+ "GROUP_CONCAT(`#{field}`, '#{separator}')"
+ when :postgresql
+ "array_to_string(array_agg(\"#{field}\"), '#{separator}')"
+ else
+ raise ArgumentError, "#{database} is not supported by SimpleNestedSet::DbHelper#group_concat"
+ end
+ end
+ end
+end
View
10 lib/simple_nested_set/nested_set.rb
@@ -36,7 +36,7 @@ def save!
denormalize!
end
- # FIXME we don't always want to call this on after_save, do we? it's only relevant when
+ # FIXME we don't always want to call this on after_save, do we? it's only relevant when
# either the structure or the slug has changed
def denormalize!
sql = []
@@ -106,11 +106,15 @@ def denormalize_level_query
def denormalize_path_query
query = arel_table.as(:l)
- query = query.project("GROUP_CONCAT(slug, '/')").
+ query = query.project(DbHelper.group_concat(db_adapter)).
where(query[:lft].lteq(arel_table[:lft])).
where(query[:rgt].gteq(arel_table[:rgt])).
where(where_clauses.map { |clause| clause.gsub(table_name, 'l') })
"path = (#{query.to_sql})"
end
+
+ def db_adapter
+ node.class.connection.instance_variable_get('@config')[:adapter].to_sym
+ end
end
-end
+end
View
30 test/simple_nested_set_test.rb
@@ -507,4 +507,32 @@ def teardown
end
-end
+ # DATABASE ADAPTERS
+
+ test "a simple database helper" do
+ assert defined?(SimpleNestedSet::DbHelper), "DbHelper should be defined"
+ assert_respond_to SimpleNestedSet::DbHelper, :group_concat
+
+ assert_raise ArgumentError do
+ SimpleNestedSet::DbHelper.group_concat()
+ end
+ assert_raise ArgumentError do
+ SimpleNestedSet::DbHelper.group_concat(:something)
+ end
+ assert_nothing_raised ArgumentError do
+ [:sqlite, :sqlite3, :mysql, :postgresql].each do |db|
+ SimpleNestedSet::DbHelper.group_concat(db)
+ end
+ end
+
+ assert_nothing_raised Exception, "concating a string aggregate works with different databases" do
+ assert_equal "GROUP_CONCAT(slug, '/')", SimpleNestedSet::DbHelper.group_concat(:sqlite)
+ assert_equal "GROUP_CONCAT(field, '/')", SimpleNestedSet::DbHelper.group_concat(:sqlite, 'field')
+ assert_equal "GROUP_CONCAT(field, ',')", SimpleNestedSet::DbHelper.group_concat(:sqlite, 'field', ',')
+
+ assert_equal "GROUP_CONCAT(`field`, ',')", SimpleNestedSet::DbHelper.group_concat(:mysql, 'field', ',')
+
+ assert_equal "array_to_string(array_agg(\"field\"), ',')", SimpleNestedSet::DbHelper.group_concat(:postgresql, 'field', ',')
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.