mdb 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 743fac27121ba7755e9bd504da03a4dd5067c5ee
4
- data.tar.gz: 6132d6430e369e4252bc398095b66a30ec5e1f2d
3
+ metadata.gz: 55c6c7c1cdcb9921dfebf67418cd17e2fdac1bb1
4
+ data.tar.gz: ddc03a93b64636f6db253f639e49030429864c11
5
5
  SHA512:
6
- metadata.gz: ace168b10d293ad77f5527730ade2d549f4869ebfc73baafcb6220d4d4f42f8257575e601202df3204dbcf11be335e91204e6fc7eb09b8af10b3ba2f523fa679
7
- data.tar.gz: 39a9b268a36d122bc14005a64ee5448e8e43f076699b1b3e79bf1da538781e8f74a7d8deb5f6cfdabaee908db9b830ab02ff94c7d629ff7a9cecfd70536eddde
6
+ metadata.gz: 2b456701c7e7d5868ffe856f5b3330a551d357e52b63e902b40f903dcdf64f0fdcbba8c0a5a0c62695164ff050dbb5cb8f32c4873d3340e8caf7dfba1ed7ae8f
7
+ data.tar.gz: 6186198dc546f16abea449e60e384e941be21339174c655b467e7e9df609062a1376296f5be7610c74b058e354151caf0a9e70767d75d0974d7ebd8299edbf3c
data/README.md CHANGED
@@ -31,6 +31,14 @@ database.tables
31
31
  database[:Movies]
32
32
  ```
33
33
 
34
+ ## Heroku
35
+
36
+ mdb-tools on heroku requires a custom buildpack.
37
+
38
+ Here is a sample project using this gem on heroku with configuration instructions:
39
+
40
+ https://github.com/jkotchoff/heroku_rails_microsoft_access_mdb_example
41
+
34
42
  ## Contributing
35
43
 
36
44
  1. Fork it
data/lib/mdb.rb CHANGED
@@ -2,7 +2,7 @@ require "mdb/version"
2
2
  require "mdb/database"
3
3
 
4
4
  module Mdb
5
-
5
+
6
6
  class FileDoesNotExistError < ArgumentError; end
7
7
  class TableDoesNotExistError < ArgumentError; end
8
8
  class MdbToolsNotInstalledError < ArgumentError
@@ -11,9 +11,9 @@ module Mdb
11
11
  end
12
12
  end
13
13
  class Error < RuntimeError; end
14
-
14
+
15
15
  def self.open(file)
16
16
  Mdb::Database.new(file)
17
17
  end
18
-
18
+
19
19
  end
@@ -1,48 +1,54 @@
1
- require 'tempfile'
2
- require 'shellwords'
3
- require 'open3'
4
- require 'csv'
1
+ require "tempfile"
2
+ require "shellwords"
3
+ require "csv"
5
4
 
6
5
 
7
6
  module Mdb
8
7
  class Database
9
-
10
-
11
-
8
+
9
+
10
+
12
11
  def initialize(file, options={})
13
12
  file = file.to_path if file.respond_to?(:to_path)
14
13
  raise FileDoesNotExistError, "\"#{file}\" does not exist" unless File.exist?(file)
15
-
14
+
16
15
  @file = file
17
- @delimiter = options.fetch :delimiter, '|'
16
+ @delimiter = options.fetch :delimiter, "|"
18
17
  end
19
-
20
-
21
-
18
+
19
+
20
+
22
21
  attr_reader :file, :delimiter
23
-
24
-
25
-
22
+
23
+
24
+
26
25
  def tables
27
26
  @tables ||= execute("mdb-tables -1 #{file_name}").scan(/[^\n]+/)
28
27
  end
29
-
30
-
31
-
28
+
29
+
30
+
32
31
  def columns(table)
33
- open_csv(table) { |csv| csv.readline.map(&:to_sym) }
32
+ open_csv(table) do |csv|
33
+ line = csv.readline
34
+ unless line || tables.member?(table.to_s)
35
+ raise TableDoesNotExistError, "#{table.inspect} does not exist in #{file_name.inspect}"
36
+ end
37
+
38
+ (line || []).map(&:to_sym)
39
+ end
34
40
  end
35
-
36
-
37
-
41
+
42
+
43
+
38
44
  def read_csv(table)
39
- csv = execute "mdb-export -D '%F %T' -d \\| #{file_name} #{table}"
45
+ csv = execute "mdb-export -D '%F %T' -d \\| #{file_name} #{Shellwords.escape(table)}"
40
46
  empty_table!(table) if csv.empty?
41
47
  csv
42
48
  end
43
-
44
-
45
-
49
+
50
+
51
+
46
52
  # Yields a hash for each record
47
53
  def each_record(table, &block)
48
54
  columns = nil
@@ -55,9 +61,9 @@ module Mdb
55
61
  end
56
62
  end
57
63
  alias :each :each_record
58
-
59
-
60
-
64
+
65
+
66
+
61
67
  # Returns an array of hashes. Each hash represents a record
62
68
  def read_records(table)
63
69
  hashes = []
@@ -66,66 +72,64 @@ module Mdb
66
72
  end
67
73
  alias :read :read_records
68
74
  alias :[] :read_records
69
-
70
-
71
-
75
+
76
+
77
+
72
78
  private
73
-
74
-
75
-
79
+
80
+
81
+
76
82
  def read_each(table, &block)
77
83
  count = 0
78
-
84
+
79
85
  open_csv(table) do |csv|
80
86
  while line = csv.readline
81
87
  yield line
82
88
  count += 1
83
89
  end
84
90
  end
85
-
91
+
86
92
  empty_table!(table) if count == 0
87
-
93
+
88
94
  count
89
95
  end
90
-
91
-
92
-
96
+
97
+
98
+
93
99
  def empty_table!(table)
94
- raise MdbToolsNotInstalledError if `which mdb-export 2> /dev/null`.empty?
100
+ raise MdbToolsNotInstalledError unless system("which mdb-export")
95
101
  raise TableDoesNotExistError, "#{table.inspect} does not exist in #{file_name.inspect}" if !tables.member?(table.to_s)
96
102
  raise Error, "An error occurred when reading #{table.inspect} in #{file_name.inspect}"
97
103
  end
98
-
99
-
100
-
104
+
105
+
106
+
101
107
  def file_name
102
108
  Shellwords.escape(file)
103
109
  end
104
-
105
-
106
-
110
+
111
+
112
+
107
113
  def open_csv(table)
108
- command = "mdb-export -D '%F %T' -d #{Shellwords.escape(delimiter)} #{file_name} #{table}"
109
- Open3.popen3(command) do |stdin, stdout, stderr|
110
- yield CSV.new(stdout, col_sep: delimiter)
114
+ command = "mdb-export -D '%F %T' -d #{Shellwords.escape(delimiter)} #{file_name} #{Shellwords.escape(table)}"
115
+ execute(command) do |file|
116
+ yield CSV.new(file, col_sep: delimiter)
111
117
  end
112
118
  end
113
-
114
-
115
-
119
+
120
+
121
+
116
122
  def execute(command)
117
- stdout = `#{command} 2> /dev/null`
118
-
119
- # !todo: add fixture data and a test to prove this code
120
- if stdout.respond_to?(:force_encoding)
121
- stdout.force_encoding("Windows-1252")
122
- stdout.encode!("utf-8")
123
- end
124
-
125
- stdout
123
+ file = Tempfile.new("mdb")
124
+ system "#{command} > #{file.path} 2> /dev/null"
125
+ return file.read unless block_given?
126
+ yield file
127
+ ensure
128
+ file.close
129
+ file.unlink
126
130
  end
127
-
128
-
129
-
131
+
132
+
133
+
130
134
  end
131
135
  end
@@ -1,3 +1,3 @@
1
1
  module Mdb
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -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", ">= 3.2.0"
23
+ spec.add_development_dependency "rails", ">= 3.2.0", "< 4.1.0"
24
24
  spec.add_development_dependency "turn"
25
25
  spec.add_development_dependency "pry"
26
26
  end
Binary file
Binary file
@@ -1,37 +1,37 @@
1
1
  require "test_helper"
2
2
 
3
3
  class MdbTest < ActiveSupport::TestCase
4
-
5
-
4
+
5
+
6
6
  { "Access 2000" => "Example2000.mdb",
7
7
  "Acesss 2003" => "Example2003.mdb" }.each do |format, file|
8
8
  path = "#{File.dirname(__FILE__)}/data/#{file}"
9
-
9
+
10
10
  test "should identify three tables in #{file} (#{format})" do
11
11
  database = Mdb.open(path)
12
12
  assert_equal %w{Actors EmptyTable Movies}, database.tables.sort
13
13
  end
14
-
14
+
15
15
  test "should find all the rows in each table (#{format})" do
16
16
  database = Mdb.open(path)
17
-
17
+
18
18
  expected_counts = {
19
- :Actors => 4,
19
+ :Actors => 5,
20
20
  :Movies => 7 }
21
21
  expected_counts.each do |table, expected_count|
22
22
  assert_equal expected_count, database[table].count, "The count of '#{table}' is off"
23
23
  end
24
24
  end
25
25
  end
26
-
27
-
28
-
26
+
27
+
28
+
29
29
  test "should raise an exception when instatiated with a missing database" do
30
30
  assert_raises(Mdb::FileDoesNotExistError) do
31
31
  Mdb.open "#{File.dirname(__FILE__)}/data/nope.mdb"
32
32
  end
33
33
  end
34
-
34
+
35
35
  test "should raise an exception when mdb-tools is not installed" do
36
36
  assert_raises(Mdb::MdbToolsNotInstalledError) do
37
37
  database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
@@ -40,44 +40,57 @@ class MdbTest < ActiveSupport::TestCase
40
40
  end
41
41
  end
42
42
  end
43
-
43
+
44
44
  test "should raise an exception if a table is not found" do
45
45
  database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
46
46
  assert_raises(Mdb::TableDoesNotExistError) do
47
47
  database.read :Villains
48
48
  end
49
49
  end
50
-
50
+
51
51
  test "should return an empty array if a table is empty" do
52
52
  database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
53
53
  assert_equal [], database.read(:EmptyTable)
54
54
  end
55
-
56
-
57
-
55
+
56
+
57
+
58
58
  test "should return an array of columns for at able" do
59
59
  database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
60
60
  assert_equal [:ID, :FirstName, :LastName, :Birthdate], database.columns(:Actors)
61
61
  end
62
-
62
+
63
+ test "should raise an exception if asked for the columns of a nonexistent table" do
64
+ database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
65
+ assert_raises(Mdb::TableDoesNotExistError) do
66
+ database.columns :Directors
67
+ end
68
+ end
69
+
63
70
  test "should treat quotation marks correctly" do
64
71
  database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
65
72
  actor = database.read(:Actors).first
66
73
  assert_equal "Chris", actor[:FirstName] # as opposed to "\"Chris\""
67
74
  end
68
-
69
-
70
-
75
+
76
+ test "should treat non-ASCII characters correctly" do
77
+ database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
78
+ actor = database.read(:Actors).last
79
+ assert_equal "Skarsgård", actor[:LastName]
80
+ end
81
+
82
+
83
+
71
84
  test "should format dates ISO 8601" do
72
85
  database = Mdb.open "#{File.dirname(__FILE__)}/data/Example2000.mdb"
73
86
  actor = database.read(:Actors).first
74
87
  assert_equal "1981-06-13 00:00:00", actor[:Birthdate]
75
88
  end
76
-
77
-
78
-
89
+
90
+
91
+
79
92
  private
80
-
93
+
81
94
  def with_env(new_env)
82
95
  begin
83
96
  old_env = ENV.to_hash
@@ -87,5 +100,5 @@ private
87
100
  ENV.replace(old_env)
88
101
  end
89
102
  end
90
-
103
+
91
104
  end
metadata CHANGED
@@ -1,83 +1,89 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Lail
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-06 00:00:00.000000000 Z
11
+ date: 2016-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rails
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: 3.2.0
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: 4.1.0
48
51
  type: :development
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
51
54
  requirements:
52
- - - '>='
55
+ - - ">="
53
56
  - !ruby/object:Gem::Version
54
57
  version: 3.2.0
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: 4.1.0
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: turn
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
- - - '>='
65
+ - - ">="
60
66
  - !ruby/object:Gem::Version
61
67
  version: '0'
62
68
  type: :development
63
69
  prerelease: false
64
70
  version_requirements: !ruby/object:Gem::Requirement
65
71
  requirements:
66
- - - '>='
72
+ - - ">="
67
73
  - !ruby/object:Gem::Version
68
74
  version: '0'
69
75
  - !ruby/object:Gem::Dependency
70
76
  name: pry
71
77
  requirement: !ruby/object:Gem::Requirement
72
78
  requirements:
73
- - - '>='
79
+ - - ">="
74
80
  - !ruby/object:Gem::Version
75
81
  version: '0'
76
82
  type: :development
77
83
  prerelease: false
78
84
  version_requirements: !ruby/object:Gem::Requirement
79
85
  requirements:
80
- - - '>='
86
+ - - ">="
81
87
  - !ruby/object:Gem::Version
82
88
  version: '0'
83
89
  description: A library for reading Microsoft Access databases
@@ -87,8 +93,8 @@ executables: []
87
93
  extensions: []
88
94
  extra_rdoc_files: []
89
95
  files:
90
- - .gitignore
91
- - .travis.yml
96
+ - ".gitignore"
97
+ - ".travis.yml"
92
98
  - Gemfile
93
99
  - LICENSE.txt
94
100
  - README.md
@@ -111,17 +117,17 @@ require_paths:
111
117
  - lib
112
118
  required_ruby_version: !ruby/object:Gem::Requirement
113
119
  requirements:
114
- - - '>='
120
+ - - ">="
115
121
  - !ruby/object:Gem::Version
116
122
  version: '0'
117
123
  required_rubygems_version: !ruby/object:Gem::Requirement
118
124
  requirements:
119
- - - '>='
125
+ - - ">="
120
126
  - !ruby/object:Gem::Version
121
127
  version: '0'
122
128
  requirements: []
123
129
  rubyforge_project:
124
- rubygems_version: 2.2.1
130
+ rubygems_version: 2.4.5.1
125
131
  signing_key:
126
132
  specification_version: 4
127
133
  summary: Wraps mdb-tools for reading and Microsoft Access databases (MDB)