text_ferry 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.swp
6
+ .DS_Store
7
+ bin
8
+ test/sample_data/sample.db
9
+ doc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in text_ferry.gemspec
4
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,58 @@
1
+ = Text Ferry
2
+ Text Ferry is a super simple DSL for quickly loading CSV text files into a
3
+ database.
4
+
5
+ == Installation
6
+ gem install text_ferry
7
+ or in your Gemfile:
8
+ gem "text_ferry"
9
+
10
+ == Notes / Use
11
+ Text Ferry relies on Sequel[http://sequel.rubyforge.org/documentation.html] to
12
+ do the heavy lifting. You will need to be familiar with how to define a table
13
+ schema using Sequel. For example, to load a CSV file named "data.csv" that is
14
+ located in a folder named "/my_data":
15
+
16
+ loader = TextFerry::Loader.new("sqlite://sample.db", "/my_data")
17
+ loader.load_table(:data) do
18
+ primary_key :id
19
+ String :name
20
+ String :phone
21
+ end
22
+
23
+ This will load data from the CSV file into a database named "sample.db" using
24
+ the given column names and types. Note that if the table already exists in the
25
+ database, it will be dropped and re-created using the given schema.
26
+
27
+ == Patches / Pull Requests
28
+ * Fork the project.
29
+ * Make your feature addition or bug fix.
30
+ * Add tests for it. This is important so I don’t break it in a future version
31
+ unintentionally.
32
+ * Commit, do not mess with rakefile, version, or history (if you want to have
33
+ your own version, that is fine but bump version in a commit by itself I can
34
+ ignore when I pull).
35
+ * Send me a pull request. Bonus points for topic branches.
36
+
37
+ == License
38
+ The MIT License
39
+
40
+ Copyright © 2011 Bob Nadler, Jr.
41
+
42
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
43
+ this software and associated documentation files (the "Software"), to deal in
44
+ the Software without restriction, including without limitation the rights to
45
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
46
+ of the Software, and to permit persons to whom the Software is furnished to do
47
+ so, subject to the following conditions:
48
+
49
+ The above copyright notice and this permission notice shall be included in all
50
+ copies or substantial portions of the Software.
51
+
52
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
58
+ SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+ require 'rdoc/task'
4
+
5
+ EXTRA_RDOC_FILES = ['README.rdoc']
6
+ MAIN_RDOC = 'README.rdoc'
7
+ TEST_FILES = Dir["test/**/*_test.rb"]
8
+ TITLE = 'Text Ferry'
9
+
10
+ task :default => ['test']
11
+
12
+ Rake::TestTask.new do |t|
13
+ t.libs << 'test'
14
+ t.test_files = TEST_FILES
15
+ end
16
+
17
+ RDoc::Task.new do |t|
18
+ t.main = MAIN_RDOC
19
+ t.rdoc_dir = 'doc'
20
+ t.rdoc_files.include(EXTRA_RDOC_FILES, 'lib/**/*.rb')
21
+ t.options << '-q'
22
+ t.title = TITLE
23
+ end
@@ -0,0 +1,48 @@
1
+ require "csv"
2
+ require "sequel"
3
+
4
+ module TextFerry
5
+ # Loads CSV data into a database.
6
+ class Loader
7
+ # database_uri::
8
+ # A URI that points to a database. See
9
+ # http://sequel.rubyforge.org/rdoc/classes/Sequel.html#method-c-connect
10
+ # for more info.
11
+ #
12
+ # data_path::
13
+ # The full path to a folder that contains one or more CSV files.
14
+ def initialize(database_uri, data_path)
15
+ @db = Sequel.connect(database_uri)
16
+ @data_path = data_path
17
+ end
18
+
19
+ # Loads data from a CSV file into the database. Assumes that +table_name+
20
+ # corresponds to a CSV file in +data_path+. Warning: if the table already
21
+ # exists, it will be dropped!
22
+ #
23
+ # table_name::
24
+ # The name of the CSV file to load; will also be used as the table name
25
+ # in the database.
26
+ #
27
+ # schema::
28
+ # A block that specifies the schema of the CSV file / table. See
29
+ # http://sequel.rubyforge.org/rdoc/files/doc/schema_modification_rdoc.html
30
+ # for more info.
31
+ def load_table(table_name, &schema)
32
+ @db.create_table!(table_name, &schema)
33
+ load_data(table_name)
34
+ end
35
+
36
+ private
37
+ def fields_for(table_name)
38
+ @db.schema(table_name).map { |c| c[0] }
39
+ end
40
+
41
+ def load_data(table_name)
42
+ CSV.table(File.join(@data_path, "#{table_name}.csv")).each do |row|
43
+ mapping = fields_for(table_name).map { |f| [f, row[f]] }
44
+ @db[table_name].insert(Hash[mapping])
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,3 @@
1
+ module TextFerry
2
+ VERSION = "0.0.1"
3
+ end
data/lib/text_ferry.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "text_ferry/version"
2
+ require "text_ferry/loader"
@@ -0,0 +1,20 @@
1
+ route_id,agency_id,route_short_name,route_long_name,route_type,route_url,route_color
2
+ 1,2,"","Princeton Shuttle",2,"",
3
+ 2,2,"","Atlantic City Rail Line",2,"",
4
+ 3,2,"","Montclair-Boonton Line",2,"",
5
+ 4,2,"","Montclair-Boonton Line",2,"",
6
+ 5,2,"","Hudson-Bergen Light Rail",0,"",
7
+ 6,2,"","Main/Bergen County Line",2,"",
8
+ 7,2,"","Port Jervis Line",2,"",
9
+ 8,2,"","Morris & Essex Line",2,"",
10
+ 9,2,"","Gladstone Branch",2,"",
11
+ 10,2,"MNRG","",2,"",
12
+ 11,2,"","Northeast Corridor",2,"",
13
+ 12,2,"","North Jersey Coast Line",2,"",
14
+ 13,2,"","North Jersey Coast Line",2,"",
15
+ 14,2,"","Newark Light Rail",0,"",
16
+ 15,2,"","Pascack Valley Line",2,"",
17
+ 16,2,"","Princeton Shuttle",2,"",
18
+ 17,2,"","Raritan Valley Line",2,"",
19
+ 18,2,"","Riverline Light Rail",0,"",
20
+ 19,2,"","Meadowlands Rail Line",2,"",
@@ -0,0 +1,4 @@
1
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require "test/unit"
4
+ require "contest"
@@ -0,0 +1,47 @@
1
+ require "test_helper"
2
+ require "text_ferry"
3
+
4
+ class LoadTest < Test::Unit::TestCase
5
+ DATA_PATH = File.join(File.dirname(__FILE__), "..", "sample_data")
6
+ DB_FILE = File.join(DATA_PATH, "sample.db")
7
+ DB = Sequel.sqlite(DB_FILE)
8
+
9
+ setup do
10
+ @loader = TextFerry::Loader.new("sqlite://#{DB_FILE}", DATA_PATH)
11
+ end
12
+
13
+ test "create a new loader" do
14
+ assert @loader, "expected to be able to create a new Loader"
15
+ end
16
+
17
+ context "table creation" do
18
+ test "creates table if it doesn't exist" do
19
+ load_routes
20
+ assert DB[:routes].all.length
21
+ end
22
+
23
+ test "drops table if it already exists" do
24
+ DB.drop_table(:routes) if DB[:routes]
25
+ DB.create_table :routes do
26
+ primary_key :id
27
+ end
28
+
29
+ assert_nothing_raised { load_routes }
30
+ end
31
+ end
32
+
33
+ context "table data" do
34
+ test "loads all data from csv file" do
35
+ load_routes
36
+ assert_equal 19, DB[:routes].all.length
37
+ end
38
+ end
39
+
40
+ private
41
+ def load_routes
42
+ @loader.load_table(:routes) do
43
+ primary_key :route_id
44
+ String :route_long_name
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "text_ferry/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "text_ferry"
7
+ s.version = TextFerry::VERSION
8
+ s.authors = ["Bob Nadler"]
9
+ s.email = ["bnadlerjr@gmail.com"]
10
+ s.homepage = "https://github.com/bnadlerjr/text_ferry"
11
+ s.summary = %q{A DSL for loading CSV text files into a database.}
12
+ s.description = %q{A DSL for loading CSV text files into a database.}
13
+
14
+ s.rubyforge_project = "text_ferry"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency "contest", "~> 0.1.3"
22
+ s.add_development_dependency "rake", "~> 0.9.2"
23
+ s.add_development_dependency "rdoc", "~> 3.11"
24
+
25
+ s.add_runtime_dependency "sequel", "~> 3.28.0"
26
+ s.add_runtime_dependency "sqlite3", "~> 1.3.4"
27
+ end
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: text_ferry
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Bob Nadler
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-10-31 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: contest
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 0.1.3
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: rake
28
+ requirement: &id002 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: rdoc
39
+ requirement: &id003 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ version: "3.11"
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: sequel
50
+ requirement: &id004 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: 3.28.0
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: sqlite3
61
+ requirement: &id005 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ~>
65
+ - !ruby/object:Gem::Version
66
+ version: 1.3.4
67
+ type: :runtime
68
+ prerelease: false
69
+ version_requirements: *id005
70
+ description: A DSL for loading CSV text files into a database.
71
+ email:
72
+ - bnadlerjr@gmail.com
73
+ executables: []
74
+
75
+ extensions: []
76
+
77
+ extra_rdoc_files: []
78
+
79
+ files:
80
+ - .gitignore
81
+ - Gemfile
82
+ - README.rdoc
83
+ - Rakefile
84
+ - lib/text_ferry.rb
85
+ - lib/text_ferry/loader.rb
86
+ - lib/text_ferry/version.rb
87
+ - test/sample_data/routes.csv
88
+ - test/test_helper.rb
89
+ - test/text_ferry/loader_test.rb
90
+ - text_ferry.gemspec
91
+ homepage: https://github.com/bnadlerjr/text_ferry
92
+ licenses: []
93
+
94
+ post_install_message:
95
+ rdoc_options: []
96
+
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ hash: 3922030537894335762
105
+ segments:
106
+ - 0
107
+ version: "0"
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3922030537894335762
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ requirements: []
118
+
119
+ rubyforge_project: text_ferry
120
+ rubygems_version: 1.8.5
121
+ signing_key:
122
+ specification_version: 3
123
+ summary: A DSL for loading CSV text files into a database.
124
+ test_files:
125
+ - test/sample_data/routes.csv
126
+ - test/test_helper.rb
127
+ - test/text_ferry/loader_test.rb