activemdb 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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