Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Native sorting when possible.

  • Loading branch information...
commit f7fe570ea0558643fbe821b1d64db4636cfb7732 1 parent 09e1c0b
@shanna authored
Showing with 36 additions and 14 deletions.
  1. +35 −14 lib/dm-tokyo-adapter/query.rb
  2. +1 −0  test/helper.rb
View
49 lib/dm-tokyo-adapter/query.rb
@@ -18,31 +18,29 @@ class Query
def initialize(connection, query)
assert_kind_of 'connection', connection, Rufus::Tokyo::Table
assert_kind_of 'query', query, DataMapper::Query
- @connection, @query, @native = connection, query, true
+ @connection, @query, @native = connection, query, []
end
#--
- # TODO: Log when a query cannot be performed natively by TC.
- # TODO: Use native sorting if there is only a single order condition.
# TODO: connection[] if I have everything I need to fetch by the primary key.
def read
records = @connection.query do |statements|
if @query.conditions.kind_of?(OrOperation)
- @native = false
+ fail_native("Operation '#{@query.conditions.slug}'.")
else
@query.conditions.each do |condition|
condition_statement(statements, condition)
end
end
- statements.no_pk
- if @native
- statements.limit(@query.limit) if @query.limit
- # TODO: Native sorting when only one order field.
+ if native? && !@query.order.empty?
+ sort_statement(statements, @query.order)
end
+
+ statements.limit(@query.limit) if native? && @query.limit
+ statements.no_pk
end
- # Typecast return values.
records.each do |record|
@query.fields.each do |property|
field = property.field
@@ -50,9 +48,18 @@ def read
end
end
+ return records if native?
+ # TODO: Move log entry out to adapter sublcass and use #name?
+ DataMapper.logger.warn(
+ "TokyoAdapter: No native TableQuery support for conditions: #{@native.join(' ')}"
+ )
@query.filter_records(records)
end
+ def native?
+ @native.empty?
+ end
+
private
def condition_statement(statements, conditions, affirmative = true)
case conditions
@@ -63,9 +70,9 @@ def condition_statement(statements, conditions, affirmative = true)
def operation_statement(statements, operation, affirmative = true)
case operation
- when OrOperation then @native = false
when NotOperation then condition_statement(statements, operation.first, !affirmative)
when AndOperation then operation.each{|op| condition_statement(statements, op, affirmative)}
+ else fail_native("Operation '#{operation.slug}'.")
end
end
@@ -91,18 +98,32 @@ def comparison_statement(statements, comparison, affirmative = true)
when LessThanComparison then :lt
when GreaterThanOrEqualToComparison then :gte
when LessThanOrEqualToComparison then :lte
+ else fail_native("Comparison #{comparison.slug}'.") && return
end
- unless operator
- @native = false
- return
- end
statements.add(comparison.property.field, operator, quote_value(value), affirmative)
end
def quote_value(value)
"#{value}"
end
+
+ def sort_statement(statements, conditions)
+ fail_native("Multiple (#{conditions.size}) order conditions.") if conditions.size > 1
+
+ sort_order = conditions.first
+ primitive = sort_order.target.primitive
+ direction = case sort_order.operator
+ when :asc then primitive == Integer ? :numasc : :asc
+ when :desc then primitive == Integer ? :numdesc : :desc
+ end
+
+ statements.order_by(sort_order.target.field, direction)
+ end
+
+ def fail_native(why)
+ @native << why
+ end
end # Query
end # Tokyo
end # Adapters
View
1  test/helper.rb
@@ -8,6 +8,7 @@
class Test::Unit::TestCase
end
+DataMapper::Logger.new(STDOUT, :debug) if $VERBOSE
DataMapper.setup(:default, {
:adapter => 'tokyo_cabinet',
:database => 'tc',
Please sign in to comment.
Something went wrong with that request. Please try again.