Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

extended the exporter and updated README

  • Loading branch information...
commit de66be8fb498b533976030716716f755a15beea3 1 parent b85b2ea
@mwlang authored
View
26 README.md
@@ -3,7 +3,9 @@
This library starts the collection of plugins and possibly extension I assemble for the Ruby Sequel
ORM.
-Currently, it only contains a plugin for Trees to mimic the Rails acts_as_tree plugin.
+Currently, it contains:
+ * plugin for Trees to mimic the Rails acts_as_tree plugin.
+ * extension for Exporting data using Dataset#export.
NOTE: Authors of other plugins and extensions for Sequel are welcome to contact me for inclusion
of your plugin and extension to this project.
@@ -12,21 +14,39 @@ Released under MIT license.
# For the Impatient
+## Install
+
This gem is released to gemcutter. Rubyforge is not utilized.
gem install sequel_plus
-And then, in your project:
+## Use Tree Plugin
require 'sequel'
class Node < Sequel::Model
plugin :tree
end
+
+## Use Exporter
+
+require 'sequel'
+require 'sequel_plus'
+
+DB = Sequel.sqlite
+
+ # Every row, every column, tab delimited, unquoted...
+ File.open("nodes.txt", "w"){|file| DB[:nodes].export(file)}
+
+ # Every row, every column, comma delimited double-quotes
+ File.open("nodes.txt", "w"){|file| DB[:nodes].export(file, :delimiter => ',', :quote_char => '"')}
+ # Specific rows and columns
+ File.open("nodes.txt", "w"){|file| DB[:nodes].filter(:id < 5).select(:id, :name).export(file)}
+
# Note on Patches/Pull Requests
-* First release!
+* This release adds an export facility to the Sequel::Dataset
# Copyright
View
1  Rakefile
@@ -15,6 +15,7 @@ begin
"README.md",
"Rakefile",
"lib/*",
+ "lib/**/*",
"test/*"
]
View
2  VERSION
@@ -1 +1 @@
-0.0.6
+0.0.9
View
79 lib/extensions/export.rb
@@ -3,42 +3,59 @@
module Sequel
class Dataset
- # Pretty prints the records in the dataset as plain-text table.
- def export(delimiter="\t", *cols)
- Sequel::Export.output(delimiter, naked.all, cols.empty? ? columns : cols)
+ # outputs the records in the dataset as plain-text table.
+ def export(fd = $stdout, options = {})
+ opts[:delimiter] = options[:delimiter] || "\t"
+ opts[:quote_char] = options[:quote_char] || '"'
+ opts[:headers] = options[:headers] != false
+ Sequel::Export::Writer.new(fd, self, opts).output
end
end
module Export
- def self.output(delimiter, records, columns = nil)
- rows = []
- columns ||= records.first.keys.sort_by{|x|x.to_s}
- rows << columns.join(delimiter)
- records.each {|r| rows << data_line(delimiter, columns, r)}
- rows.join("\n")
- end
-
- ### Private Module Methods ###
-
- # String for each data line
- def self.data_line(delimiter, columns, record) # :nodoc:
- columns.map {|c| format_cell(record[c])}.join(delimiter)
- end
-
- # Format the value so it takes up exactly size characters
- def self.format_cell(v) # :nodoc:
- case v
- when Bignum, Fixnum
- v.to_i.to_s
- when Float, BigDecimal
- v.to_f.to_s
- else
- v.to_s
+ class Writer
+ def initialize(fd, dataset, options)
+ @file = fd
+ @dataset = dataset
+ @options = options
end
- end
- # private_class_method :column_sizes, :data_line, :format_cell, :header_line, :separator_line
- end
-end
+ class ::Date; def to_export(q); ; end; end
+ class ::DateTime; def to_export(q); "#{q}#{iso8601}#{q}"; end; end
+ class ::Time; def to_export(q); "#{q}#{iso8601}#{q}"; end; end
+ class ::Float; def to_export(q); to_f.to_s; end; end
+ class ::BigDecimal; def to_export(q); to_f.to_s; end; end
+ class ::Bignum; def to_export(q); to_i.to_s; end; end
+ class ::Fixnum; def to_export(q); to_i.to_s; end; end
+ class ::Object; def to_export(q); "#{q}#{to_s}#{q}"; end; end
+
+ def output
+ quot = @options[:quote_char]
+ @columns ||= @dataset.first.keys.sort_by{|x|x.to_s}
+
+ if @options[:headers] == true
+ @file.puts @columns.map{|col| "#{quot}#{col}#{quot}"}.join(@options[:delimiter])
+ end
+
+ @dataset.each do |row|
+ data = @columns.map do |col|
+ case row[col]
+ when Date, DateTime, Time then "#{quot}#{row[col].iso8601}#{quot}"
+ when Float, BigDecimal then row[col].to_f
+ when BigDecimal, Bignum, Fixnum then row[col].to_i
+ else "#{quot}#{row[col].to_s}#{quot}"
+ end
+ end
+ @file.puts data.join(@options[:delimiter])
+ end
+ end
+
+ def build_row(row)
+ quot = @options[:quote_char]
+ @columns.map{|col| row[col].to_export(quot)}.join(@options[:delimiter])
+ end
+ end # Writer
+ end # Export
+end # Sequel
View
2  lib/sequel_plus.rb
@@ -1,2 +1,2 @@
require 'sequel_tree'
-require 'extensions/export'
+require File.join(File.dirname(__FILE__), 'extensions', 'export')
View
2  lib/sequel_tree.rb
@@ -61,7 +61,7 @@ def ancestors
# subchild1.ancestors # => [child1, root]
def descendants
nodes = self.children
- self.children.each{|c| nodes + c.descendants}
+ nodes.each{|child| nodes + child.descendants}
nodes
end
View
109 test/test_export.rb
@@ -51,11 +51,114 @@ module ExportTest
end
it "should export everything" do
- DB[:nodes].export.should == "id\tname\tparent_id\tposition\n1\tone\t\t1\n2\ttwo\t\t2\n3\tthree\t\t3\n4\ttwo.one\t2\t1\n5\ttwo.two\t2\t2\n6\ttwo.two.one\t5\t1\n7\tone.two\t1\t2\n8\tone.one\t1\t1\n9\tfive\t\t5\n10\tfour\t\t4\n11\tfive.one\t9\t1\n12\ttwo.three\t2\t3"
+ mem_stream = StringIO.new("", "w+")
+ DB[:nodes].export(mem_stream)
+ mem_stream.pos = 0
+ mem_stream.read.should == <<-TEXT
+"id" "name" "parent_id" "position"
+1 "one" "" 1
+2 "two" "" 2
+3 "three" "" 3
+4 "two.one" 2 1
+5 "two.two" 2 2
+6 "two.two.one" 5 1
+7 "one.two" 1 2
+8 "one.one" 1 1
+9 "five" "" 5
+10 "four" "" 4
+11 "five.one" 9 1
+12 "two.three" 2 3
+ TEXT
end
-
+
+ it "should export everything with comma delimiter" do
+ mem_stream = StringIO.new("", "w+")
+ DB[:nodes].export(mem_stream, :delimiter => ',')
+ mem_stream.pos = 0
+ mem_stream.read.should == <<-TEXT
+"id","name","parent_id","position"
+1,"one","",1
+2,"two","",2
+3,"three","",3
+4,"two.one",2,1
+5,"two.two",2,2
+6,"two.two.one",5,1
+7,"one.two",1,2
+8,"one.one",1,1
+9,"five","",5
+10,"four","",4
+11,"five.one",9,1
+12,"two.three",2,3
+ TEXT
+ end
+
+ it "should export everything with comma delimiter and no quote characters" do
+ mem_stream = StringIO.new("", "w+")
+ DB[:nodes].export(mem_stream, :delimiter => ',', :quote_char => '')
+ mem_stream.pos = 0
+ mem_stream.read.should == <<-TEXT
+id,name,parent_id,position
+1,one,,1
+2,two,,2
+3,three,,3
+4,two.one,2,1
+5,two.two,2,2
+6,two.two.one,5,1
+7,one.two,1,2
+8,one.one,1,1
+9,five,,5
+10,four,,4
+11,five.one,9,1
+12,two.three,2,3
+ TEXT
+ end
+
it "should export selected" do
- DB[:nodes].filter(:id < 3).select(:id, :name).export.should == "id\tname\n1\tone\n2\ttwo"
+ mem_stream = StringIO.new("", "w+")
+ DB[:nodes].filter(:id < 3).select(:id, :name).export(mem_stream)
+ mem_stream.pos = 0
+ mem_stream.read.should == "\"id\"\t\"name\"\n1\t\"one\"\n2\t\"two\"\n"
+ end
+
+ it "should not export headers" do
+ mem_stream = StringIO.new("", "w+")
+ DB[:nodes].export(mem_stream, :headers => false)
+ mem_stream.pos = 0
+ mem_stream.read.should == <<-TEXT
+1 "one" "" 1
+2 "two" "" 2
+3 "three" "" 3
+4 "two.one" 2 1
+5 "two.two" 2 2
+6 "two.two.one" 5 1
+7 "one.two" 1 2
+8 "one.one" 1 1
+9 "five" "" 5
+10 "four" "" 4
+11 "five.one" 9 1
+12 "two.three" 2 3
+ TEXT
+ end
+
+ it "should explicitly export headers" do
+ mem_stream = StringIO.new("", "w+")
+ DB[:nodes].export(mem_stream, :headers => true)
+ mem_stream.pos = 0
+ mem_stream.read.should == <<-TEXT
+"id" "name" "parent_id" "position"
+1 "one" "" 1
+2 "two" "" 2
+3 "three" "" 3
+4 "two.one" 2 1
+5 "two.two" 2 2
+6 "two.two.one" 5 1
+7 "one.two" 1 2
+8 "one.one" 1 1
+9 "five" "" 5
+10 "four" "" 4
+11 "five.one" 9 1
+12 "two.three" 2 3
+ TEXT
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.