mdb 0.0.2 → 0.0.3.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.travis.yml +8 -0
- data/README.md +3 -0
- data/lib/mdb.rb +5 -0
- data/lib/mdb/database.rb +37 -49
- data/lib/mdb/version.rb +1 -1
- data/mdb.gemspec +1 -1
- data/test/data/Example2000.mdb +0 -0
- data/test/data/Example2003.mdb +0 -0
- data/test/database_test.rb +37 -0
- metadata +19 -37
- data/Example2003.mdb +0 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3480b9c2fc35ed39f57547a63d49b16fd9d30acb
|
4
|
+
data.tar.gz: 4325aff61e2ba6ea7e7fbd7bcfb9007464c07868
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 239876d157dbaa9ed429b1a832f1a0a83a12ef17c8e796e4cd09b185dfcde35fc4159f3e618d37fe105fe37590b8ad0374bf07d6c8acf93ea8ad2c7987bfb403
|
7
|
+
data.tar.gz: 294d967caecee1bb7b0081ae500d60e3e21f009240d783c748cfcb71970a4b1b06ae9a8e7e0042e101e1b544f8cbba0ecc24474d30edb0b7fd741f70b6fcf022
|
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Mdb
|
2
2
|
|
3
|
+
[](https://travis-ci.org/concordia-publishing-house/mdb)
|
4
|
+
[](https://codeclimate.com/github/concordia-publishing-house/mdb)
|
5
|
+
|
3
6
|
Wraps [mdb-tools](https://github.com/brianb/mdbtools) for reading Microsoft Access databases
|
4
7
|
|
5
8
|
## Installation
|
data/lib/mdb.rb
CHANGED
@@ -5,6 +5,11 @@ module Mdb
|
|
5
5
|
|
6
6
|
class FileDoesNotExistError < ArgumentError; end
|
7
7
|
class TableDoesNotExistError < ArgumentError; end
|
8
|
+
class MdbToolsNotInstalledError < ArgumentError
|
9
|
+
def message
|
10
|
+
"mdbtools is not installed"
|
11
|
+
end
|
12
|
+
end
|
8
13
|
class Error < RuntimeError; end
|
9
14
|
|
10
15
|
def self.open(file)
|
data/lib/mdb/database.rb
CHANGED
@@ -1,20 +1,24 @@
|
|
1
1
|
require 'tempfile'
|
2
|
+
require 'shellwords'
|
3
|
+
require 'open3'
|
4
|
+
require 'csv'
|
5
|
+
|
2
6
|
|
3
7
|
module Mdb
|
4
8
|
class Database
|
5
9
|
|
6
10
|
|
7
11
|
|
8
|
-
def initialize(file)
|
12
|
+
def initialize(file, options={})
|
9
13
|
raise FileDoesNotExistError, "\"#{file}\" does not exist" unless File.exist?(file)
|
10
14
|
|
11
15
|
@file = file
|
12
|
-
@
|
16
|
+
@delimiter = options.fetch :delimiter, '|'
|
13
17
|
end
|
14
18
|
|
15
19
|
|
16
20
|
|
17
|
-
attr_reader :file
|
21
|
+
attr_reader :file, :delimiter
|
18
22
|
|
19
23
|
|
20
24
|
|
@@ -25,32 +29,27 @@ module Mdb
|
|
25
29
|
|
26
30
|
|
27
31
|
def columns(table)
|
28
|
-
csv
|
29
|
-
first_line = csv[/^(.*)$/]
|
30
|
-
parse_columns(first_line)
|
32
|
+
open_csv(table) { |csv| csv.readline.map(&:to_sym) }
|
31
33
|
end
|
32
34
|
|
33
35
|
|
34
36
|
|
35
37
|
def read_csv(table)
|
36
38
|
csv = execute "mdb-export -d \\| #{file_name} #{table}"
|
37
|
-
if csv.empty?
|
38
|
-
raise TableDoesNotExistError, "#{table.inspect} does not exist in #{file_name.inspect}" if !tables.member?(table.to_s)
|
39
|
-
raise Error, "An error occurred when reading #{table.inspect} in #{file_name.inspect}"
|
40
|
-
end
|
39
|
+
empty_table!(table) if csv.empty?
|
41
40
|
csv
|
42
41
|
end
|
43
42
|
|
44
43
|
|
45
44
|
|
46
|
-
#
|
45
|
+
# Yields a hash for each record
|
47
46
|
def each_record(table, &block)
|
48
47
|
columns = nil
|
49
48
|
read_each(table) do |line|
|
50
49
|
if columns
|
51
|
-
yield
|
50
|
+
yield Hash[columns.zip(line)]
|
52
51
|
else
|
53
|
-
columns =
|
52
|
+
columns = line.map(&:to_sym)
|
54
53
|
end
|
55
54
|
end
|
56
55
|
end
|
@@ -73,61 +72,50 @@ module Mdb
|
|
73
72
|
|
74
73
|
|
75
74
|
|
76
|
-
def
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
(0...columns.length).each do |i|
|
85
|
-
column = columns[i]
|
86
|
-
next if column.nil?
|
87
|
-
value = values[i]
|
88
|
-
hash[column] = value && value.delete("\"")
|
75
|
+
def read_each(table, &block)
|
76
|
+
count = 0
|
77
|
+
|
78
|
+
open_csv(table) do |csv|
|
79
|
+
while line = csv.readline
|
80
|
+
yield line
|
81
|
+
count += 1
|
82
|
+
end
|
89
83
|
end
|
90
|
-
|
84
|
+
|
85
|
+
empty_table!(table) if count == 0
|
86
|
+
|
87
|
+
count
|
91
88
|
end
|
92
89
|
|
93
90
|
|
94
91
|
|
95
|
-
def
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
count += 1
|
100
|
-
end
|
101
|
-
count # don't return the result of read_csv; discard it
|
92
|
+
def empty_table!(table)
|
93
|
+
raise MdbToolsNotInstalledError if `which mdb-export 2> /dev/null`.empty?
|
94
|
+
raise TableDoesNotExistError, "#{table.inspect} does not exist in #{file_name.inspect}" if !tables.member?(table.to_s)
|
95
|
+
raise Error, "An error occurred when reading #{table.inspect} in #{file_name.inspect}"
|
102
96
|
end
|
103
97
|
|
104
98
|
|
105
99
|
|
106
|
-
def
|
107
|
-
|
100
|
+
def file_name
|
101
|
+
Shellwords.escape(file)
|
108
102
|
end
|
109
103
|
|
110
104
|
|
111
105
|
|
112
|
-
def
|
113
|
-
|
106
|
+
def open_csv(table)
|
107
|
+
command = "mdb-export -d #{Shellwords.escape(delimiter)} #{file_name} #{table}"
|
108
|
+
Open3.popen3(command) do |stdin, stdout, stderr|
|
109
|
+
yield CSV.new(stdout, col_sep: delimiter)
|
110
|
+
end
|
114
111
|
end
|
115
112
|
|
116
113
|
|
117
114
|
|
118
115
|
def execute(command)
|
119
|
-
stdout =
|
120
|
-
(1..5).each do |try|
|
121
|
-
Tempfile.open(rand(99999999).to_s) do |t|
|
122
|
-
stdout = `#{command} 2> #{t.path}`
|
123
|
-
t.rewind
|
124
|
-
stderr = t.read.strip
|
125
|
-
break if stderr.empty?
|
126
|
-
|
127
|
-
# Rails.logger.error("[mdb-tools] executed `#{command}`; got \"#{stderr}\"")
|
128
|
-
end
|
129
|
-
end
|
116
|
+
stdout = `#{command} 2> /dev/null`
|
130
117
|
|
118
|
+
# !todo: add fixture data and a test to prove this code
|
131
119
|
if stdout.respond_to?(:force_encoding)
|
132
120
|
stdout.force_encoding("Windows-1252")
|
133
121
|
stdout.encode!("utf-8")
|
data/lib/mdb/version.rb
CHANGED
data/mdb.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.3"
|
22
22
|
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency "rails"
|
23
|
+
spec.add_development_dependency "rails", ">= 3.2.0"
|
24
24
|
spec.add_development_dependency "turn"
|
25
25
|
spec.add_development_dependency "pry"
|
26
26
|
end
|
data/test/data/Example2000.mdb
CHANGED
File without changes
|
data/test/data/Example2003.mdb
CHANGED
File without changes
|
data/test/database_test.rb
CHANGED
@@ -32,6 +32,18 @@ class MdbTest < ActiveSupport::TestCase
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
test "should raise an exception when mdb-tools is not installed" do
|
36
|
+
assert_raises(Mdb::MdbToolsNotInstalledError) do
|
37
|
+
database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
|
38
|
+
|
39
|
+
# This test assumes that the tool `which` is in `/usr/bin`
|
40
|
+
# while `mdb-export` et al are installed elsewhere.
|
41
|
+
with_env "PATH" => "/usr/bin" do
|
42
|
+
database.read :Villains
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
35
47
|
test "should raise an exception if a table is not found" do
|
36
48
|
database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
|
37
49
|
assert_raises(Mdb::TableDoesNotExistError) do
|
@@ -46,4 +58,29 @@ class MdbTest < ActiveSupport::TestCase
|
|
46
58
|
|
47
59
|
|
48
60
|
|
61
|
+
test "should return an array of columns for at able" do
|
62
|
+
database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
|
63
|
+
assert_equal [:ID, :FirstName, :LastName], database.columns(:Actors)
|
64
|
+
end
|
65
|
+
|
66
|
+
test "should treat quotation marks correctly" do
|
67
|
+
database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
|
68
|
+
actor = database.read(:Actors).first
|
69
|
+
assert_equal "Chris", actor[:FirstName] # as opposed to "\"Chris\""
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def with_env(new_env)
|
77
|
+
begin
|
78
|
+
old_env = ENV.to_hash
|
79
|
+
ENV.replace(old_env.merge(new_env))
|
80
|
+
yield
|
81
|
+
ensure
|
82
|
+
ENV.replace(old_env)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
49
86
|
end
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mdb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.3.rc1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Robert Lail
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-10-25 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: bundler
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ~>
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ~>
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,65 +27,57 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rails
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
47
|
+
version: 3.2.0
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
54
|
+
version: 3.2.0
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: turn
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '0'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: pry
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - '>='
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - '>='
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
description: A library for reading Microsoft Access databases
|
@@ -99,7 +88,7 @@ extensions: []
|
|
99
88
|
extra_rdoc_files: []
|
100
89
|
files:
|
101
90
|
- .gitignore
|
102
|
-
-
|
91
|
+
- .travis.yml
|
103
92
|
- Gemfile
|
104
93
|
- LICENSE.txt
|
105
94
|
- README.md
|
@@ -115,33 +104,26 @@ files:
|
|
115
104
|
homepage: ''
|
116
105
|
licenses:
|
117
106
|
- MIT
|
107
|
+
metadata: {}
|
118
108
|
post_install_message:
|
119
109
|
rdoc_options: []
|
120
110
|
require_paths:
|
121
111
|
- lib
|
122
112
|
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
-
none: false
|
124
113
|
requirements:
|
125
|
-
- -
|
114
|
+
- - '>='
|
126
115
|
- !ruby/object:Gem::Version
|
127
116
|
version: '0'
|
128
|
-
segments:
|
129
|
-
- 0
|
130
|
-
hash: 3387175660756308767
|
131
117
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
-
none: false
|
133
118
|
requirements:
|
134
|
-
- -
|
119
|
+
- - '>'
|
135
120
|
- !ruby/object:Gem::Version
|
136
|
-
version:
|
137
|
-
segments:
|
138
|
-
- 0
|
139
|
-
hash: 3387175660756308767
|
121
|
+
version: 1.3.1
|
140
122
|
requirements: []
|
141
123
|
rubyforge_project:
|
142
|
-
rubygems_version:
|
124
|
+
rubygems_version: 2.0.3
|
143
125
|
signing_key:
|
144
|
-
specification_version:
|
126
|
+
specification_version: 4
|
145
127
|
summary: Wraps mdb-tools for reading and Microsoft Access databases (MDB)
|
146
128
|
test_files:
|
147
129
|
- test/data/Example2000.mdb
|
data/Example2003.mdb
DELETED
Binary file
|