activemdb 0.1.0 → 0.2.0

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.
@@ -2,9 +2,13 @@ History.txt
2
2
  Manifest.txt
3
3
  README.txt
4
4
  Rakefile
5
+ db/.DS_Store
6
+ db/not_an_mdb.txt
7
+ db/retreat.mdb
5
8
  db/sample.mdb
6
9
  irb.rc
7
10
  lib/active_mdb.rb
11
+ lib/active_mdb/base.rb
8
12
  lib/active_mdb/column.rb
9
13
  lib/active_mdb/mdb.rb
10
14
  lib/active_mdb/mdb_tools.rb
@@ -12,6 +16,7 @@ lib/active_mdb/record.rb
12
16
  lib/active_mdb/table.rb
13
17
  support/a.insert
14
18
  test/test_activemdb.rb
19
+ test/test_base.rb
15
20
  test/test_helper.rb
16
21
  test/test_mdb.rb
17
22
  test/test_mdb_tools.rb
data/README.txt CHANGED
@@ -4,24 +4,38 @@ http://rubyforge.org/projects/activemdb/
4
4
 
5
5
  == DESCRIPTION:
6
6
 
7
- Lib for getting info out of MS Access (.mdb) files, which uses ActiveRecord-ish reflection to parse table and column names.
7
+ Library for getting info out of MS Access (.mdb) files, which uses ActiveRecord-ish reflection to parse table and column names.
8
8
 
9
- Intended for exploration and migration, not production. ActiveMDB provides a thin wrapper around the mdb-tables, mdb-schema, mdb-sql, and mdb-export binaries from Brian Bruns's MDB Tools project (http://mdbtools.sourceforge.net/).
9
+ Intended for exploration and migration, not production. And it's *READ ONLY*, so don't try to get fresh. ActiveMDB provides a wrapper of varying thickness around the utilities from Brian Bruns's MDB Tools project (http://mdbtools.sourceforge.net/). Kudos to Mr. Bruns.
10
10
 
11
11
  == FEATURES/PROBLEMS:
12
12
 
13
- * MDB, Table, and Record classes do reflection to provide easy attribute readers
14
- * I really need to refactor the above classes to something more like ActiveRecord::Base, so that you can subclass to make models.
13
+ * MDBTools - Straightforward wrapper around the CLI tools that you get with libmdb
14
+ * ActiveMDB::Base - Subclass to make your models, just like the big shots do.
15
+
15
16
 
16
17
  == SYNOPSIS:
17
18
 
18
- @mdb = MDB.new('db/sample.mdb', :exclude => 'lookups')
19
- @employees = @mdb.employees
19
+ # When your Access database schema conforms to the 37s stylebook:
20
+ class Bacon < ActiveMDB::Base
21
+ set_mdb_file 'db/wherefore.mdb'
22
+ end
20
23
 
21
24
  # in the find_* methods, the entries in the hash
22
25
  # get turned into "WHERE #{key} like %#{value}%" conditions,
23
- # unless the column is a boolean, in which case the WHERE uses "="
24
- @employees.find_first :f_name => 'Matthew', :l_name => 'King'
26
+ # which fails when the column is a boolean, which is a regression from 0.1.0.
27
+ # I could fix this tonight, but my son is yelling at me to come out for dinner.
28
+ best_bacon = Bacon.find_all(:rind => 'creamy', :sodium_content => 'Awesome!' )
29
+
30
+ # When it doesn't:
31
+ class Employee < ActiveMDB::Base
32
+ set_mdb_file 'db/sample.mdb'
33
+ set_table_name 'Employee'
34
+ set_primary_key 'Emp_Id'
35
+ end
36
+
37
+ paula = Employee.find_first(:Department => 'Engineering', :Specialty => 'paulaBeans')
38
+
25
39
 
26
40
  == REQUIREMENTS:
27
41
 
@@ -29,7 +43,7 @@ Intended for exploration and migration, not production. ActiveMDB provides a thi
29
43
 
30
44
  == INSTALL:
31
45
 
32
- * Sadly, no easy install at this time.
46
+ * Sadly, no easy install of MDB Tools at this time. It compiles on Mac OS X 10.4.x, both PPC and Intel. Haven't tested on Linuxes yet, but that's what Parallels is for, right?
33
47
 
34
48
  == LICENSE:
35
49
 
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ Hoe.new('activemdb', ActiveMDB::VERSION) do |p|
8
8
  p.rubyforge_name = 'activemdb'
9
9
  p.author = 'Matthew King'
10
10
  p.email = 'automatthew@gmail.com'
11
- p.summary = 'a reflective wrapper around MDB Tools, which lets POSIX platforms read MS Access (.mdb) files'
11
+ p.summary = 'ActiveRecordy wrapper around MDB Tools, which lets POSIX platforms read MS Access (.mdb) files'
12
12
  p.description = p.paragraphs_of('README.txt', 2).join("\n\n")
13
13
  p.url = p.paragraphs_of('README.txt',0).first.split(/\n/)[2..-1]
14
14
  # p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
Binary file
File without changes
Binary file
@@ -1,16 +1,17 @@
1
1
  $:.unshift(File.dirname(__FILE__))
2
2
  module ActiveMDB
3
- VERSION = '0.1.0'
3
+ VERSION = '0.2.0'
4
4
  end
5
5
 
6
6
 
7
7
  require 'rubygems'
8
- require 'active_support/inflector'
8
+ require 'active_support'
9
9
  require 'active_mdb/mdb_tools'
10
10
  load 'active_mdb/mdb.rb'
11
11
  load 'active_mdb/table.rb'
12
12
  load 'active_mdb/record.rb'
13
13
  load 'active_mdb/column.rb'
14
+ load 'active_mdb/base.rb'
14
15
  require 'faster_csv'
15
16
 
16
17
 
@@ -0,0 +1,126 @@
1
+ module ActiveMDB
2
+ class Base
3
+
4
+ def initialize(attributes=nil)
5
+ @attributes = attributes unless attributes.nil?
6
+ end
7
+
8
+
9
+
10
+ cattr_accessor :pluralize_table_names, :instance_writer => false
11
+ @@pluralize_table_names = true
12
+
13
+ class << self # Class methods
14
+ attr_accessor :mdb_file
15
+ attr_reader :mdb
16
+
17
+ def set_mdb_file(file)
18
+ @mdb_file = file
19
+ @mdb = MDB.new(file)
20
+ end
21
+
22
+ def table_name
23
+ table_name = Inflector.underscore(Inflector.demodulize(self.to_s))
24
+ table_name = Inflector.pluralize(table_name) if pluralize_table_names
25
+ table_name
26
+ end
27
+
28
+ # borrowed from ActiveRecord
29
+ def set_table_name(value = nil, &block)
30
+ define_attr_method :table_name, value, &block
31
+ end
32
+ alias :table_name= :set_table_name
33
+
34
+ # Returns an array of column objects for the table associated with this class.
35
+ def columns
36
+ unless @columns
37
+ @columns = @mdb.columns(table_name)
38
+ # @columns.each {|column| column.primary = column.name == primary_key}
39
+ end
40
+ @columns
41
+ end
42
+
43
+ def column_names
44
+ @mdb.column_names(table_name)
45
+ end
46
+
47
+ def primary_key
48
+ 'id'
49
+ end
50
+
51
+ def set_primary_key(value = nil, &block)
52
+ define_attr_method :primary_key, value, &block
53
+ end
54
+ alias :primary_key= :set_primary_key
55
+
56
+ def table_exists?
57
+ @mdb.tables.include? table_name
58
+ end
59
+
60
+ def count
61
+ @mdb.count(table_name, primary_key)
62
+ end
63
+
64
+ def find_first(conditions_hash)
65
+ # rekey_hash(conditions_hash)
66
+ sql_search(conditions_hash).first
67
+ end
68
+
69
+ def find_all(conditions_hash)
70
+ sql_search(conditions_hash)
71
+ end
72
+
73
+ # borrowed from ActiveRecord
74
+ def define_attr_method(name, value=nil, &block)
75
+ sing = class << self; self; end
76
+ sing.send :alias_method, "original_#{name}", name
77
+ if block_given?
78
+ sing.send :define_method, name, &block
79
+ else
80
+ # use eval instead of a block to work around a memory leak in dev
81
+ # mode in fcgi
82
+ sing.class_eval "def #{name}; #{value.to_s.inspect}; end"
83
+ end
84
+ end
85
+
86
+ # relies on stuff that doesn't work right now
87
+ def rekey_hash(conditions_hash)
88
+ conditions_hash.each do |key,value|
89
+ column = self[key.to_s]
90
+ if column.boolean?
91
+ key = column.name + '!'
92
+ else
93
+ key = column.name
94
+ end
95
+ end
96
+ end
97
+
98
+ # the conditions hash keys are column names, the values are search values
99
+ # e.g. sql_search(:first_name => 'Matthew', :last_name => 'King')
100
+ def sql_search(conditions_hash)
101
+ conditions = MDBTools.compile_conditions(conditions_hash)
102
+ MDBTools.sql_select(mdb_file, table_name, nil, conditions).collect! { |record| instantiate(record) }
103
+ end
104
+
105
+ private
106
+
107
+ def instantiate(record)
108
+ new(record)
109
+ end
110
+
111
+
112
+ end
113
+
114
+ private
115
+
116
+ def method_missing(method_id, *args, &block)
117
+ method_name = method_id.to_s
118
+ if @attributes.include?(method_name)
119
+ value = @attributes[method_name]
120
+ else
121
+ super
122
+ end
123
+ end
124
+
125
+ end
126
+ end
@@ -4,14 +4,51 @@ class Column
4
4
  attr_reader :method_name, :name, :type, :size
5
5
 
6
6
  def initialize(name, type, size)
7
- @name = name
8
- @method_name, @type, @size = methodize(name), methodize(type), size.to_i
7
+ @name, @type = name, type
8
+ @method_name, @size = methodize(name), size.to_i
9
9
  end
10
10
 
11
11
  def self.new_from_describe(describe_hash)
12
12
  self.new(describe_hash["Column Name"], describe_hash["Type"], describe_hash["Size"])
13
13
  end
14
14
 
15
+ # return Ruby class corresponding to data type.
16
+ # Borrowed from ActiveRecord
17
+ def klass
18
+ case type
19
+ when 'Text', 'Character' then String
20
+ when 'Long Integer' then Fixnum
21
+ when 'Currency', 'Float' then Float
22
+ when 'DateTime (Short)' then Time
23
+ when 'Boolean' then Object
24
+ when 'Decimal' then BigDecimal
25
+ when 'Binary' then String
26
+ end
27
+ end
28
+
29
+ # Casts value (which is a String) to an appropriate instance.
30
+ # Totally borrowed from ActiveRecord
31
+ def type_cast(value)
32
+ return nil if value.nil?
33
+ case type
34
+ when 'Text', 'Character' then value
35
+ when 'Long Integer' then value.to_i rescue value ? 1 : 0
36
+ when 'Currency', 'Float' then value.to_f
37
+ when 'DateTime (Short)' then self.class.string_to_time(value)
38
+ when 'Boolean' then self.class.value_to_boolean(value)
39
+ when 'Decimal' then self.class.value_to_decimal(value)
40
+ when 'Binary' then self.class.binary_to_string(value)
41
+ else value
42
+ end
43
+ end
44
+
45
+ def self.value_to_boolean(value)
46
+ if value == true || value == false
47
+ value
48
+ else
49
+ %w(true t 1).include?(value.to_s.downcase)
50
+ end
51
+ end
15
52
 
16
53
  def boolean?
17
54
  self.type == 'boolean'
@@ -3,25 +3,35 @@
3
3
  class MDB
4
4
  include MDBTools
5
5
 
6
- attr_reader :mdb_file, :prefix, :exclude, :table_names
6
+ attr_reader :mdb_file, :prefix, :exclude, :tables
7
7
 
8
8
  def initialize(mdb_file, options = {})
9
9
  @mdb_file = check_file(mdb_file)
10
10
  @prefix = options[:prefix] || ''
11
11
  @exclude, @include = options[:exclude], options[:include]
12
12
  @export_syntax = options[:sql_syntax] || 'mysql'
13
- @table_names = mdb_tables(@mdb_file, :exclude => @exclude, :include => @include)
14
- @tables = create_table_objects
13
+ @tables = mdb_tables(@mdb_file, :exclude => @exclude, :include => @include)
14
+ # @tables = create_table_objects
15
15
  end
16
16
 
17
- def tables
18
- @table_names.collect { |table| methodize(table)}
17
+ def count(table_name, attribute)
18
+ MDBTools.faked_count(@mdb_file, table_name, attribute)
19
19
  end
20
20
 
21
+ def columns(table_name)
22
+ MDBTools.describe_table(@mdb_file, table_name).map do |column|
23
+ Column.new_from_describe(column)
24
+ end
25
+ end
26
+
27
+ def column_names(table_name)
28
+ MDBTools.field_names_for(@mdb_file, table_name)
29
+ end
21
30
 
22
31
 
23
32
  private
24
-
33
+
34
+ # Deprecated.
25
35
  def create_table_objects
26
36
  tables = {}
27
37
  @table_names.each do |table|
@@ -1,5 +1,6 @@
1
1
  module MDBTools
2
- include Inflector
2
+
3
+ extend self
3
4
 
4
5
  DELIMITER = '::'
5
6
  LINEBREAK = "\n"
@@ -15,6 +16,14 @@ module MDBTools
15
16
  mdb_file
16
17
  end
17
18
 
19
+ def valid_file?(file)
20
+ !mdb_version(file).blank?
21
+ end
22
+
23
+ def mdb_version(file)
24
+ `mdb-ver #{file} 2> /dev/null`.chomp
25
+ end
26
+
18
27
  def check_table(mdb_file, table_name)
19
28
  unless mdb_tables(mdb_file).include?(table_name)
20
29
  raise ArgumentError, "mdbtools does not think a table named \"#{table_name}\" exists"
@@ -22,6 +31,7 @@ module MDBTools
22
31
  table_name
23
32
  end
24
33
 
34
+
25
35
  def mdb_tables(mdb_file, options = {})
26
36
  included, excluded = options[:include], options[:exclude]
27
37
  return `mdb-tables -1 #{mdb_file}`.split(LINEBREAK) if not (included || excluded)
@@ -37,19 +47,49 @@ module MDBTools
37
47
  tables
38
48
  end
39
49
 
40
- def sql_select(mdb_file, table_name, attributes = nil, conditions ={})
41
- attributes ||= ['*']
42
- sql = "select #{attributes.join(' ')} from #{table_name} where #{conditions}".dump
50
+ def sql_select(mdb_file, table_name, attributes = nil, conditions=nil)
51
+ if attributes.respond_to?(:join)
52
+ fields = attributes.join(' ')
53
+ else
54
+ attributes ||= '*'
55
+ end
56
+ where = conditions ? "where #{conditions}" : ""
57
+ sql = "select #{attributes} from #{table_name} #{where}"
43
58
  mdb_sql(mdb_file, sql)
44
59
  end
45
60
 
61
+ def mdb_sql(mdb_file,sql)
62
+ command = "mdb-sql -Fp -d '#{DELIMITER}' #{mdb_file}\n"
63
+ array = []
64
+ IO.popen(command, 'r+') do |pipe|
65
+ pipe << "#{sql}\ngo\n"
66
+ pipe.close_write
67
+ pipe.readline
68
+ fields = pipe.readline.chomp.split(DELIMITER)
69
+ pipe.each do |row|
70
+ hash = {}
71
+ row = row.chomp.split(DELIMITER)
72
+ fields.each_index do |i|
73
+ hash[fields[i]] = row[i]
74
+ end
75
+ array << hash
76
+ end
77
+ end
78
+ array
79
+ end
46
80
 
47
- def mdb_sql(mdb_file, sql)
48
- # puts sql
81
+ def old_mdb_sql(mdb_file, sql)
49
82
  result = `echo -n #{sql} | mdb-sql -Fp -H -d '#{DELIMITER}' #{mdb_file}`.strip
50
- arrays = delimited_to_arrays(result)
83
+ delimited_to_arrays(result)
84
+ end
85
+
86
+ def field_names_for(mdb_file, table)
87
+ fields = `echo -n 'select * from #{table} where 1 = 2' | mdb-sql -Fp -d '#{DELIMITER}' #{mdb_file}`.chomp.sub(/^\n+/, '')
88
+ fields.split(DELIMITER)
51
89
  end
52
90
 
91
+
92
+
53
93
  def compile_conditions(conditions_hash, *args)
54
94
  conditions = conditions_hash.sort_by{|k,v| k.to_s}.map do |column_name, value|
55
95
  if block_given?
@@ -60,6 +100,10 @@ module MDBTools
60
100
  end.join(' AND ')
61
101
  end
62
102
 
103
+ def faked_count(*args)
104
+ sql_select(*args).size
105
+ end
106
+
63
107
  def mdb_export(mdb_file, table_name, options = {})
64
108
  defaults = { :format => 'sql',
65
109
  :headers => false,
@@ -83,10 +127,8 @@ module MDBTools
83
127
  end
84
128
 
85
129
  def describe_table(mdb_file, table_name)
86
- command = "describe table \"#{table_name}\"".dump
87
- description = `echo -n #{command} | mdb-sql -Fp -d '#{DELIMITER}' #{mdb_file}`.strip
88
- arrays = delimited_to_arrays(description)
89
- arrays_to_hashes(arrays.shift, arrays)
130
+ command = "describe table \"#{table_name}\""
131
+ mdb_sql(mdb_file,command)
90
132
  end
91
133
 
92
134
  def mdb_schema(mdb_file, table_name)
@@ -118,7 +160,7 @@ module MDBTools
118
160
 
119
161
 
120
162
  def methodize(table_name)
121
- underscore table_name
163
+ Inflector.underscore table_name
122
164
  end
123
165
 
124
166
  def backends
@@ -0,0 +1,55 @@
1
+ require File.join(File.dirname(__FILE__), "..", 'lib', 'active_mdb')
2
+ require 'test/unit'
3
+ require File.join(File.dirname(__FILE__), 'test_helper')
4
+
5
+ class RealWorldTest < Test::Unit::TestCase
6
+
7
+ RETREAT = File.join(File.dirname(__FILE__), '..', 'db', 'retreat.mdb')
8
+
9
+ class Family < ActiveMDB::Base
10
+ set_mdb_file RETREAT
11
+ set_table_name 'tblFamilyData'
12
+ end
13
+
14
+ class Cabin < ActiveMDB::Base
15
+ set_mdb_file RETREAT
16
+ set_table_name 'tCabins'
17
+ end
18
+
19
+ def setup
20
+ @retreat = MDB.new(RETREAT)
21
+ end
22
+
23
+ def test_tables
24
+ tables = ["JobAssignmentsByCabin","Switchboard Items","tblAdultChildCode","tblCities","tblFamilyData","tblGender","tblIndividData","tblStatusChurch","tblStatusIndiv","tCabinAssignments","tCabins","tCampRates","tCampScholarships","tJobs","tJobsR","tParkAreas","tPayments","tRetreatEnrollment","tSponsors","tblStatusFamily"]
25
+ assert_equal tables, @retreat.tables
26
+ end
27
+
28
+ def test_column_names
29
+ column_names = ["FamKey","LName", "HisName", "HerName", "HmAddress", "AddressNumber", "StreetDirection", "StreetName", "HmAddress2", "City", "State", "Zip", "HmPhone", "UnLstHmPho?"]
30
+ assert_equal column_names, Family.column_names
31
+ end
32
+
33
+ def test_columns
34
+ column = Family.columns[2]
35
+ assert_kind_of Column, column
36
+ assert_respond_to column, 'type'
37
+ assert_respond_to column, 'name'
38
+ assert_respond_to column, 'size'
39
+ Family.columns.each do |c|
40
+ assert_not_nil c.name
41
+ assert_not_nil c.type
42
+ end
43
+ end
44
+
45
+ def test_column_klass
46
+ column = Family.columns[1]
47
+ assert_equal String, column.klass
48
+ Family.columns.each do |c|
49
+ assert_not_nil c.klass
50
+ assert_kind_of Class, c.klass
51
+ end
52
+ end
53
+
54
+
55
+ end
@@ -0,0 +1,86 @@
1
+ require File.join(File.dirname(__FILE__), "..", 'lib', 'active_mdb')
2
+ require 'test/unit'
3
+ require File.join(File.dirname(__FILE__), 'test_helper')
4
+
5
+ class BaseTest < Test::Unit::TestCase
6
+
7
+ class NonExistentTable < ActiveMDB::Base
8
+ set_mdb_file TEST_DB
9
+ end
10
+ class Employee < ActiveMDB::Base
11
+ set_mdb_file TEST_DB
12
+ set_table_name 'Employee'
13
+ set_primary_key 'Emp_Id'
14
+ end
15
+ class Room < ActiveMDB::Base
16
+ set_mdb_file TEST_DB
17
+ set_table_name 'Room'
18
+ set_primary_key 'Room'
19
+ end
20
+
21
+
22
+
23
+ def test_setting_mdb_file
24
+ assert_equal TEST_DB, Employee.mdb_file
25
+ end
26
+
27
+ def test_mdb_creation
28
+ mdb = Employee.mdb
29
+ assert_not_nil mdb
30
+ assert_respond_to mdb, :tables
31
+ end
32
+
33
+ def test_get_table_name
34
+ assert_equal 'non_existent_tables', NonExistentTable.table_name
35
+ ActiveMDB::Base.pluralize_table_names = false
36
+ assert_equal 'non_existent_table', NonExistentTable.table_name
37
+ end
38
+
39
+ def test_set_table_name
40
+ Employee.set_table_name('foo')
41
+ assert_equal 'foo', Employee.table_name
42
+ assert_equal 'Room', Room.table_name
43
+ Employee.set_table_name('Employee')
44
+ end
45
+
46
+ def test_table_exists
47
+ assert !NonExistentTable.table_exists?
48
+ assert Room.table_exists?
49
+ end
50
+
51
+ def test_get_and_set_primary_key
52
+ assert_equal 'Emp_Id', Employee.primary_key
53
+ Employee.set_primary_key 'employee_id'
54
+ assert_equal 'employee_id', Employee.primary_key
55
+ end
56
+
57
+ def test_count
58
+ assert_equal 92, Room.count
59
+ assert_equal 53, Employee.count
60
+ end
61
+
62
+ def test_instantiate
63
+ hash = [{"Department"=>"Engineering", "Gender"=>"M", "Room"=>"6072", "Title"=>"Programmer", "Emp_Id"=>"1045", "First_Name"=>"Robert", "Last_Name"=>"Weinfeld"}]
64
+ record = Employee.send(:instantiate, hash)
65
+ assert_equal hash, record.instance_variable_get('@attributes')
66
+ end
67
+
68
+ def test_sql_search
69
+ record = Employee.sql_search(:Room => '6072').first
70
+ assert_kind_of Employee, record
71
+ end
72
+
73
+ def test_attribute_magic
74
+ record = Employee.sql_search(:Room => '6072').first
75
+ assert_equal '6072', record.Room
76
+ end
77
+
78
+
79
+ def test_find_all
80
+ assert_equal 2, Employee.find_all(:First_Name => 'G').size
81
+ end
82
+
83
+
84
+
85
+
86
+ end
@@ -1,8 +1,9 @@
1
1
  require 'test/unit'
2
+ TEST_DB = File.join(File.dirname(__FILE__), '..', 'db', 'sample.mdb')
3
+ NOT_A_DB = File.join(File.dirname(__FILE__), '..', 'db', 'not_an_mdb.txt')
2
4
 
3
5
  class Test::Unit::TestCase
4
6
 
5
- TEST_DB = File.join(File.dirname(__FILE__), '..', 'db', 'sample.mdb')
6
7
 
7
8
 
8
9
  protected
@@ -11,6 +12,7 @@ class Test::Unit::TestCase
11
12
  excluded = options[:exclude]
12
13
  included = options[:include]
13
14
  assert_nothing_raised { @db = MDB.new(TEST_DB, :exclude => excluded, :include => included ) }
15
+ assert_not_nil @db
14
16
  end
15
17
 
16
18
  end
@@ -3,8 +3,6 @@ require 'test/unit'
3
3
  require File.join(File.dirname(__FILE__), 'test_helper')
4
4
 
5
5
  class MDBTest < Test::Unit::TestCase
6
-
7
-
8
6
 
9
7
  def setup
10
8
 
@@ -12,20 +10,15 @@ class MDBTest < Test::Unit::TestCase
12
10
 
13
11
  def test_table_exclusion
14
12
  create_mdb(:exclude => ['Inventory'])
15
- assert !@db.table_names.include?('Inventory')
13
+ assert !@db.tables.include?('Inventory')
16
14
  end
17
15
 
18
16
  def test_table_inclusion
19
17
  create_mdb(:include => ['Inventory', 'Room'])
20
- assert_equal ['Inventory', 'Room'], @db.table_names.sort
18
+ assert_equal ['Inventory', 'Room'], @db.tables.sort
21
19
  end
22
20
 
23
- def test_reflection
24
- create_mdb
25
- assert_respond_to @db, 'computer'
26
- assert_respond_to @db, 'employee'
27
- assert_respond_to @db, 'room'
28
- end
21
+
29
22
 
30
23
 
31
24
 
@@ -28,6 +28,16 @@ class MDBToolsTest < Test::Unit::TestCase
28
28
  assert_raise(ArgumentError) { check_file README}
29
29
  end
30
30
 
31
+ def test_valid_file
32
+ assert valid_file?(TEST_DB)
33
+ assert !valid_file?(NOT_A_DB)
34
+ end
35
+
36
+ def test_mdb_version
37
+ assert_equal 'JET3', mdb_version(TEST_DB)
38
+ assert_equal '', mdb_version(NOT_A_DB)
39
+ end
40
+
31
41
  def test_check_table
32
42
  assert_nothing_raised { check_table TEST_DB, 'Employee'}
33
43
  assert_raises(ArgumentError) { check_table TEST_DB, 'foobarbaz' }
@@ -59,6 +69,28 @@ class MDBToolsTest < Test::Unit::TestCase
59
69
  assert_match /DROP TABLE/, @schema
60
70
  end
61
71
 
72
+ def test_describe_table
73
+ descriptions = describe_table(TEST_DB, 'Employee')
74
+ assert_kind_of Array, descriptions
75
+ assert_kind_of Hash, descriptions.first
76
+ assert_equal 3, descriptions.first.size
77
+ assert_not_nil descriptions.first['Type']
78
+ end
79
+
80
+ def test_mdb_sql
81
+ result = [{"Department"=>"Human Resources", "Gender"=>"F", "Room"=>"6150", "Title"=>"Vice President", "Emp_Id"=>"1025", "First_Name"=>"Kathy", "Last_Name"=>"Ragerie"}]
82
+ assert_equal result, mdb_sql(TEST_DB, "select * from Employee where Room = '6150'")
83
+ bees = mdb_sql(TEST_DB, "select * from Employee where Last_Name like 'B%'")
84
+ assert_kind_of Array, bees
85
+ b = bees.first
86
+ assert_kind_of Hash, b
87
+ end
88
+
89
+ def test_field_names_for
90
+ fields = ["Last_Name","First_Name", "Gender", "Title", "Department", "Room", "Emp_Id"]
91
+ assert_equal fields, field_names_for(TEST_DB, 'Employee')
92
+ end
93
+
62
94
 
63
95
  # def test_csv_to_hashes
64
96
  # employee_hash = csv_to_hashes(@employees_csv)
@@ -66,8 +98,8 @@ class MDBToolsTest < Test::Unit::TestCase
66
98
  # end
67
99
 
68
100
  def test_sql_select
69
- assert_equal ["Torbati","Yolanda", "F", "Programmer", "Engineering", "6044", "1000"],
70
- sql_select(TEST_DB, 'Employee', ['*'], "First_Name LIKE 'Yolanda'" ).first
101
+ yo = {"Department"=>"Engineering", "Gender"=>"F", "Room"=>"6044", "Title"=>"Programmer", "Emp_Id"=>"1000", "First_Name"=>"Yolanda", "Last_Name"=>"Torbati"}
102
+ assert_equal yo, sql_select(TEST_DB, 'Employee', ['*'], "First_Name LIKE 'Yolanda'" ).first
71
103
  end
72
104
 
73
105
  def test_compile_conditions
@@ -79,6 +111,10 @@ class MDBToolsTest < Test::Unit::TestCase
79
111
  sql_select(TEST_DB, 'Employee', nil, compile_conditions(:first_name => 'Yolanda'))
80
112
  end
81
113
 
114
+ def test_count
115
+ assert_equal 92, faked_count(TEST_DB, 'Room', 'Room', nil)
116
+ end
117
+
82
118
  def test_export_table_to_sql
83
119
  # this test is dependent on specific content in the sample database
84
120
  export = mdb_export(TEST_DB, 'Computer', :format => 'sql').split(LINEBREAK)
@@ -1,24 +1,24 @@
1
- require File.join(File.dirname(__FILE__), "..", 'lib', 'active_mdb')
2
- require 'test/unit'
3
- require File.join(File.dirname(__FILE__), 'test_helper')
4
-
5
- class RecordTest < Test::Unit::TestCase
6
-
7
- def setup
8
- create_mdb
9
- @employee = @db.employee
10
- @line = ["Torbati","Yolanda", "F", "Programmer", "Engineering", "6044", "1000"]
11
- assert_nothing_raised { @record = Record.new(@employee, @line) }
12
- end
13
-
14
- def test_reflection
15
- assert_respond_to @record, 'gender'
16
- assert_respond_to @record, 'emp_id'
17
- assert_equal 'Yolanda', @record.first_name
18
- end
19
-
20
- def test_display
21
-
22
- end
23
-
24
- end
1
+ # require File.join(File.dirname(__FILE__), "..", 'lib', 'active_mdb')
2
+ # require 'test/unit'
3
+ # require File.join(File.dirname(__FILE__), 'test_helper')
4
+ #
5
+ # class RecordTest < Test::Unit::TestCase
6
+ #
7
+ # def setup
8
+ # create_mdb
9
+ # @employee = @db.employee
10
+ # @line = ["Torbati","Yolanda", "F", "Programmer", "Engineering", "6044", "1000"]
11
+ # assert_nothing_raised { @record = Record.new(@employee, @line) }
12
+ # end
13
+ #
14
+ # def test_reflection
15
+ # assert_respond_to @record, 'gender'
16
+ # assert_respond_to @record, 'emp_id'
17
+ # assert_equal 'Yolanda', @record.first_name
18
+ # end
19
+ #
20
+ # def test_display
21
+ #
22
+ # end
23
+ #
24
+ # end
@@ -1,50 +1,50 @@
1
- require File.join(File.dirname(__FILE__), "..", 'lib', 'active_mdb')
2
- require 'test/unit'
3
- require File.join(File.dirname(__FILE__), 'test_helper')
4
-
5
- class TableTest < Test::Unit::TestCase
6
-
7
-
8
- def setup
9
- create_mdb
10
- @employee = @db.employee
11
- end
12
-
13
- def test_columns
14
- columns = @employee.columns
15
- assert_kind_of Array, columns
16
- assert_kind_of Column, columns.first
17
- assert_equal 7, columns.size
18
- end
19
-
20
- def test_create_record_struct
21
- assert_kind_of Class, @employee.record_struct
22
- members = @employee.record_struct.members
23
- assert_equal 7, members.size
24
- assert members.include?('emp_id')
25
- end
26
-
27
- def test_to_csv
28
- csv_text = @employee.to_csv
29
- assert_kind_of String, csv_text
30
- arrays = csv_text.split(MDBTools::LINEBREAK)
31
-
32
- # grab the headers and test for content
33
- assert arrays.shift.include?('Emp_Id')
34
- assert_equal 53, arrays.size
35
- end
36
-
37
- def test_find_first
38
- y = @employee.find_first(:first_name => 'Yolanda')
39
- assert_kind_of Record, y
40
- assert_equal 'Yolanda', y.first_name
41
- end
42
-
43
- def test_find_all
44
- a_names = @employee.find_all(:last_name => 'A')
45
- assert_kind_of Array, a_names
46
- assert_kind_of Record, a_names.first
47
- assert_equal 2, a_names.size
48
- end
49
-
50
- end
1
+ # require File.join(File.dirname(__FILE__), "..", 'lib', 'active_mdb')
2
+ # require 'test/unit'
3
+ # require File.join(File.dirname(__FILE__), 'test_helper')
4
+ #
5
+ # class TableTest < Test::Unit::TestCase
6
+ #
7
+ #
8
+ # def setup
9
+ # create_mdb
10
+ # @employee = @db.employee
11
+ # end
12
+ #
13
+ # def test_columns
14
+ # columns = @employee.columns
15
+ # assert_kind_of Array, columns
16
+ # assert_kind_of Column, columns.first
17
+ # assert_equal 7, columns.size
18
+ # end
19
+ #
20
+ # def test_create_record_struct
21
+ # assert_kind_of Class, @employee.record_struct
22
+ # members = @employee.record_struct.members
23
+ # assert_equal 7, members.size
24
+ # assert members.include?('emp_id')
25
+ # end
26
+ #
27
+ # def test_to_csv
28
+ # csv_text = @employee.to_csv
29
+ # assert_kind_of String, csv_text
30
+ # arrays = csv_text.split(MDBTools::LINEBREAK)
31
+ #
32
+ # # grab the headers and test for content
33
+ # assert arrays.shift.include?('Emp_Id')
34
+ # assert_equal 53, arrays.size
35
+ # end
36
+ #
37
+ # def test_find_first
38
+ # y = @employee.find_first(:first_name => 'Yolanda')
39
+ # assert_kind_of Record, y
40
+ # assert_equal 'Yolanda', y.first_name
41
+ # end
42
+ #
43
+ # def test_find_all
44
+ # a_names = @employee.find_all(:last_name => 'A')
45
+ # assert_kind_of Array, a_names
46
+ # assert_kind_of Record, a_names.first
47
+ # assert_equal 2, a_names.size
48
+ # end
49
+ #
50
+ # end
metadata CHANGED
@@ -3,15 +3,15 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: activemdb
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.0
7
- date: 2007-03-12 00:00:00 -05:00
8
- summary: a reflective wrapper around MDB Tools, which lets POSIX platforms read MS Access (.mdb) files
6
+ version: 0.2.0
7
+ date: 2007-04-05 00:00:00 -05:00
8
+ summary: ActiveRecordy wrapper around MDB Tools, which lets POSIX platforms read MS Access (.mdb) files
9
9
  require_paths:
10
10
  - lib
11
11
  email: automatthew@gmail.com
12
12
  homepage: http://rubyforge.org/projects/activemdb/
13
13
  rubyforge_project: activemdb
14
- description: Intended for exploration and migration, not production. ActiveMDB provides a thin wrapper around the mdb-tables, mdb-schema, mdb-sql, and mdb-export binaries from Brian Bruns's MDB Tools project (http://mdbtools.sourceforge.net/).
14
+ description: Intended for exploration and migration, not production. And it's *READ ONLY*, so don't try to get fresh. ActiveMDB provides a wrapper of varying thickness around the utilities from Brian Bruns's MDB Tools project (http://mdbtools.sourceforge.net/). Kudos to Mr. Bruns.
15
15
  autorequire:
16
16
  default_executable:
17
17
  bindir: bin
@@ -33,9 +33,13 @@ files:
33
33
  - Manifest.txt
34
34
  - README.txt
35
35
  - Rakefile
36
+ - db/.DS_Store
37
+ - db/not_an_mdb.txt
38
+ - db/retreat.mdb
36
39
  - db/sample.mdb
37
40
  - irb.rc
38
41
  - lib/active_mdb.rb
42
+ - lib/active_mdb/base.rb
39
43
  - lib/active_mdb/column.rb
40
44
  - lib/active_mdb/mdb.rb
41
45
  - lib/active_mdb/mdb_tools.rb
@@ -43,6 +47,7 @@ files:
43
47
  - lib/active_mdb/table.rb
44
48
  - support/a.insert
45
49
  - test/test_activemdb.rb
50
+ - test/test_base.rb
46
51
  - test/test_helper.rb
47
52
  - test/test_mdb.rb
48
53
  - test/test_mdb_tools.rb
@@ -50,6 +55,7 @@ files:
50
55
  - test/test_table.rb
51
56
  test_files:
52
57
  - test/test_activemdb.rb
58
+ - test/test_base.rb
53
59
  - test/test_helper.rb
54
60
  - test/test_mdb.rb
55
61
  - test/test_mdb_tools.rb