mdb 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,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Example2003.mdb ADDED
Binary file
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mdb.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Robert Lail
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Mdb
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'mdb'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install mdb
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "lib"
6
+ t.libs << "test"
7
+ t.pattern = "test/**/*_test.rb"
8
+ t.verbose = false
9
+ end
@@ -0,0 +1,137 @@
1
+ module Mdb
2
+ class Database
3
+
4
+
5
+
6
+ def initialize(file)
7
+ raise FileDoesNotExistError, "\"#{file}\" does not exist" unless File.exist?(file)
8
+
9
+ @file = file
10
+ @delim = '|' # We're going to assume no pipes in data
11
+ end
12
+
13
+
14
+
15
+ attr_reader :file
16
+
17
+
18
+
19
+ def tables
20
+ @tables ||= execute("mdb-tables -1 #{file_name}").scan(/^\w+$/)
21
+ end
22
+
23
+
24
+
25
+ def columns(table)
26
+ csv = read_csv(table)
27
+ first_line = csv[/^(.*)$/]
28
+ parse_columns(first_line)
29
+ end
30
+
31
+
32
+
33
+ def read_csv(table)
34
+ csv = execute "mdb-export -d \\| #{file_name} #{table}"
35
+ if csv.blank?
36
+ raise TableDoesNotExistError, "#{table.inspect} does not exist in #{file_name.inspect}" if !tables.member?(table.to_s)
37
+ raise Error, "An error occurred when reading #{table.inspect} in #{file_name.inspect}"
38
+ end
39
+ csv
40
+ end
41
+
42
+
43
+
44
+ # Returns an array of hashes. Each hash represents a record
45
+ def each_record(table, &block)
46
+ columns = nil
47
+ read_each(table) do |line|
48
+ if columns
49
+ yield map_to_hash(line.split(@delim), columns)
50
+ else
51
+ columns = parse_columns(line)
52
+ end
53
+ end
54
+ end
55
+ alias :each :each_record
56
+
57
+
58
+
59
+ # Returns an array of hashes. Each hash represents a record
60
+ def read_records(table)
61
+ hashes = []
62
+ each(table) {|hash| hashes << hash}
63
+ hashes
64
+ end
65
+ alias :read :read_records
66
+ alias :[] :read_records
67
+
68
+
69
+
70
+ private
71
+
72
+
73
+
74
+ def parse_columns(line)
75
+ line.split(@delim).map {|name| name.empty? ? nil : name.to_sym }
76
+ end
77
+
78
+
79
+
80
+ def map_to_hash(values, columns)
81
+ hash = {}
82
+ (0...columns.length).each do |i|
83
+ column = columns[i]
84
+ next if column.nil?
85
+ value = values[i]
86
+ hash[column] = value && value.delete("\"")
87
+ end
88
+ hash
89
+ end
90
+
91
+
92
+
93
+ def read_each(table, &block)
94
+ read_csv(table).each_line do |line|
95
+ yield line.chomp
96
+ end
97
+ end
98
+
99
+
100
+
101
+ def parse(csv)
102
+ csv.split /\n/
103
+ end
104
+
105
+
106
+
107
+ def file_name
108
+ @file.gsub(' ', '\ ')
109
+ end
110
+
111
+
112
+
113
+ def execute(command)
114
+ stdout = ""
115
+ (1..5).each do |try|
116
+ Tempfile.open(rand(99999999).to_s) do |t|
117
+ stdout = `#{command} 2> #{t.path}`
118
+ t.rewind
119
+ stderr = t.read.strip
120
+ break if stderr.blank?
121
+
122
+ # Rails.logger.error("[mdb-tools] executed `#{command}`; got \"#{stderr}\"")
123
+ end
124
+ end
125
+
126
+ if stdout.respond_to?(:force_encoding)
127
+ stdout.force_encoding("Windows-1252")
128
+ stdout.encode!("utf-8")
129
+ end
130
+
131
+ stdout
132
+ end
133
+
134
+
135
+
136
+ end
137
+ end
@@ -0,0 +1,3 @@
1
+ module Mdb
2
+ VERSION = "0.0.1"
3
+ end
data/lib/mdb.rb ADDED
@@ -0,0 +1,14 @@
1
+ require "mdb/version"
2
+ require "mdb/database"
3
+
4
+ module Mdb
5
+
6
+ class FileDoesNotExistError < ArgumentError; end
7
+ class TableDoesNotExistError < ArgumentError; end
8
+ class Error < RuntimeError; end
9
+
10
+ def self.open(file)
11
+ Mdb::Database.new(file)
12
+ end
13
+
14
+ end
data/mdb.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mdb/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mdb"
8
+ spec.version = Mdb::VERSION
9
+ spec.authors = ["Robert Lail"]
10
+ spec.email = ["robert.lail@cph.org"]
11
+ spec.description = %q{A library for reading Microsoft Access databases}
12
+ spec.summary = %q{Wraps mdb-tools for reading and Microsoft Access databases (MDB)}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rails"
24
+ spec.add_development_dependency "turn"
25
+ spec.add_development_dependency "pry"
26
+ end
Binary file
Binary file
@@ -0,0 +1,49 @@
1
+ require "test_helper"
2
+
3
+ class MdbTest < ActiveSupport::TestCase
4
+
5
+
6
+ { "Access 2000" => "Example2000.mdb",
7
+ "Acesss 2003" => "Example2003.mdb" }.each do |format, file|
8
+ path = "#{File.dirname(__FILE__)}/data/#{file}"
9
+
10
+ test "should identify three tables in #{file} (#{format})" do
11
+ database = Mdb.open(path)
12
+ assert_equal %w{Actors EmptyTable Movies}, database.tables.sort
13
+ end
14
+
15
+ test "should find all the rows in each table (#{format})" do
16
+ database = Mdb.open(path)
17
+
18
+ expected_counts = {
19
+ :Actors => 4,
20
+ :Movies => 7 }
21
+ expected_counts.each do |table, expected_count|
22
+ assert_equal expected_count, database[table].count, "The count of '#{table}' is off"
23
+ end
24
+ end
25
+ end
26
+
27
+
28
+
29
+ test "should raise an exception when instatiated with a missing database" do
30
+ assert_raises(Mdb::FileDoesNotExistError) do
31
+ Mdb.open "#{File.dirname(__FILE__)}/data/nope.mdb"
32
+ end
33
+ end
34
+
35
+ test "should raise an exception if a table is not found" do
36
+ database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
37
+ assert_raises(Mdb::TableDoesNotExistError) do
38
+ database.read :Villains
39
+ end
40
+ end
41
+
42
+ test "should return an empty array if a table is empty" do
43
+ database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
44
+ assert_equal [], database.read(:EmptyTable)
45
+ end
46
+
47
+
48
+
49
+ end
@@ -0,0 +1,5 @@
1
+ require "rails"
2
+ require "rails/test_help"
3
+ require "turn"
4
+ require "pry"
5
+ require "mdb"
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mdb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Robert Lail
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rails
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: turn
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: pry
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: A library for reading Microsoft Access databases
95
+ email:
96
+ - robert.lail@cph.org
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - .gitignore
102
+ - Example2003.mdb
103
+ - Gemfile
104
+ - LICENSE.txt
105
+ - README.md
106
+ - Rakefile
107
+ - lib/mdb.rb
108
+ - lib/mdb/database.rb
109
+ - lib/mdb/version.rb
110
+ - mdb.gemspec
111
+ - test/data/Example2000.mdb
112
+ - test/data/Example2003.mdb
113
+ - test/database_test.rb
114
+ - test/test_helper.rb
115
+ homepage: ''
116
+ licenses:
117
+ - MIT
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ segments:
129
+ - 0
130
+ hash: 827409863156524609
131
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
+ none: false
133
+ requirements:
134
+ - - ! '>='
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ segments:
138
+ - 0
139
+ hash: 827409863156524609
140
+ requirements: []
141
+ rubyforge_project:
142
+ rubygems_version: 1.8.25
143
+ signing_key:
144
+ specification_version: 3
145
+ summary: Wraps mdb-tools for reading and Microsoft Access databases (MDB)
146
+ test_files:
147
+ - test/data/Example2000.mdb
148
+ - test/data/Example2003.mdb
149
+ - test/database_test.rb
150
+ - test/test_helper.rb