Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Initial implementation.

  • Loading branch information...
commit c808771d636cec00bc138da7f0a2376be31dfa5b 1 parent 5dea1ff
@knaveofdiamonds authored
View
64 lib/sequel/fast_columns.rb
@@ -0,0 +1,64 @@
+module Sequel
+ class Dataset
+ def columns
+ return @columns if @columns
+ @columns = if opts[:select]
+ if opts[:select].map(&:class).any? {|x| x == Sequel::LiteralString } ||
+ (opts[:joins] && opts[:select].any? {|x| x == :* })
+ query_db_for_columns
+ else
+ opts[:select].map do |column|
+ case column
+ when Sequel::SQL::AliasedExpression
+ column.aliaz.to_sym
+ when Sequel::SQL::QualifiedIdentifier
+ column_name_from_symbol column.column
+ when Sequel::SQL::ColumnAll
+ get_all_columns(column.table)
+ when Symbol
+ column_name_from_symbol column
+ when Sequel::SQL::Expression
+ column.to_s(db).to_sym
+ else
+ column.to_s.to_sym
+ end
+ end.flatten
+ end
+ else
+ if opts[:joins]
+ query_db_for_columns
+ else
+ get_all_columns opts[:from]
+ end
+ end
+ end
+
+ private
+
+ def get_all_columns(table)
+ table = table.first if table.kind_of? Array
+ if table.kind_of?(Symbol)
+ db.schema(table).map {|c| c.first }
+ else
+ query_db_for_columns
+ end
+ end
+
+ def column_name_from_symbol(column)
+ if column == :*
+ get_all_columns opts[:from]
+ else
+ t, col, aliaz = split_symbol(column)
+ aliaz ? aliaz.to_sym : col.to_sym
+ end
+ end
+
+ # This is the original Sequel Method
+ def query_db_for_columns
+ ds = unfiltered.unordered.clone(:distinct => nil, :limit => 1)
+ ds.each{break}
+ @columns = ds.instance_variable_get(:@columns)
+ @columns || []
+ end
+ end
+end
View
1  lib/sequel_fast_columns.rb
@@ -0,0 +1 @@
+require 'sequel/fast_columns'
View
69 spec/sequel_fast_columns_spec.rb
@@ -1,7 +1,70 @@
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
-describe "SequelFastColumns" do
- it "fails" do
- fail "hey buddy, you should probably rename this file and start specing for real"
+describe "Fast column queries" do
+ before :each do
+ @dataset = TEST_DB[:a]
+ @dataset.should_not_receive(:unfiltered)
+ end
+
+ it "should just return the selected column symbols" do
+ @dataset.select(:foo).columns.should == [:foo]
+ end
+
+ it "should return the column name from symbols with __" do
+ @dataset.select(:a__foo).columns.should == [:foo]
+ end
+
+ it "should return the aliased column name from symbols with ___" do
+ @dataset.select(:a__foo___baz).columns.should == [:baz]
+ @dataset.select(:foo___baz).columns.should == [:baz]
+ end
+
+ it "should return the aliased column name from aliased expressions" do
+ @dataset.select(:foo.as(:baz)).columns.should == [:baz]
+ end
+
+ it "should return the column name from qualified expressions" do
+ @dataset.select(:foo.qualify(:b)).columns.should == [:foo]
+ end
+
+ it "should return the column name from qualified aliased expressions" do
+ @dataset.select(:a__foo.as(:bar)).columns.should == [:bar]
+ @dataset.select(:foo.qualify(:a).as(:bar)).columns.should == [:bar]
+ end
+
+ it "should return the columns from the schema if no columns specified" do
+ @dataset.columns.should == [:id, :foo]
+ end
+
+ it "should return all columns from the schema if :* specified" do
+ @dataset.select(:*).columns.should == [:id, :foo]
+ end
+
+ it "should return all columns from the schema if qualfied :* specified" do
+ @dataset.select(:*.qualify(:a)).columns.should == [:id, :foo]
+ end
+
+ it "should return the value as the column" do
+ @dataset.select("hello", 1).columns.should == [:hello, :"1"]
+ end
+
+ it "should return the SQL for the column for unaliased calculated values" do
+ # doesn't work with Sqlite
+ # @dataset.select(:sum[:foo]).columns.should == [:"SUM(`foo`)"]
+ end
+end
+
+describe "Falling back to database query" do
+ it "should return all columns when select_append is used" do
+ TEST_DB[:a].select_append(:foo).columns.should == [:id, :foo, :foo]
+ end
+
+ it "should fall back to querying the db if the dataset is derived" do
+ TEST_DB[TEST_DB[:a]].columns.should == [:id, :foo]
+ end
+
+ it "should fall back if unqualfied * is used and there are joins" do
+ # Again can't get this working with sqlite.
+ # TEST_DB.join(:b, :id => :id).columns.should == [:id, :foo, :id, :bar]
end
end
View
2  spec/spec.opts
@@ -1 +1 @@
---color
+--backtrace --color
View
16 spec/spec_helper.rb
@@ -1,9 +1,25 @@
+require 'rubygems'
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+
+require 'sequel'
require 'sequel_fast_columns'
+
require 'spec'
require 'spec/autorun'
+TEST_DB = Sequel.sqlite
+TEST_DB.create_table(:a) do
+ integer :id
+ integer :foo
+end
+
+TEST_DB.create_table(:b) do
+ integer :id
+ integer :bar
+end
+
Spec::Runner.configure do |config|
end
Please sign in to comment.
Something went wrong with that request. Please try again.