christiank-turntable 0.6.4.3 → 0.7

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.
Files changed (3) hide show
  1. data/bin/sqlite3-to-turntable +9 -10
  2. data/turntable.rb +77 -19
  3. metadata +2 -2
@@ -10,16 +10,17 @@ require 'turntable'
10
10
 
11
11
  # There must be 2 arguments
12
12
  if ARGV.length != 2
13
- puts 'Usage: sqlite3-to-turntable [sqlite3 database] [column name]'
13
+ puts 'Usage: sqlite3-to-turntable [sqlite3 database] [table name]'
14
14
  exit 1
15
15
  end
16
16
 
17
- # Find out about the SQLite3 database
18
- db_filename = ARGV[0].split('.').first
19
- sqlite_db = SQLite3::Database.new ARGV[0]
17
+ db_name = ARGV[0]
18
+ table_name = ARGV[1]
20
19
 
21
- sqlite_db_columns = sqlite_db.query("select * from #{ARGV[1]}") { |result| result.columns }.dup
22
- sqlite_db_rows = sqlite_db.execute "select * from #{ARGV[1]}"
20
+ # Find out about the SQLite3 database
21
+ sqlite_db = SQLite3::Database.new db_name if File.file?(db_name)
22
+ sqlite_db_columns = sqlite_db.query("select * from #{table_name}") { |result| result.columns }.dup
23
+ sqlite_db_rows = sqlite_db.execute "select * from #{table_name}"
23
24
 
24
25
  p sqlite_db_columns
25
26
 
@@ -31,10 +32,8 @@ end
31
32
  # Convert the remaining column names to symbols
32
33
  sqlite_db_columns.collect! { |column| column.to_sym }
33
34
 
34
- # Create the new Turntable
35
- turntable_db = Turntable.new "#{ARGV[1]}.turn", sqlite_db_columns
36
-
37
- # Fill up the Turntable
35
+ # Create the new Turntable and fill it up
36
+ turntable_db = Turntable.new "#{table_name}.turn", sqlite_db_columns
38
37
  sqlite_db_rows.each { |row| turntable_db.insert_array row }
39
38
 
40
39
  puts "Created #{turntable_db.filename}"
data/turntable.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # turntable v0.6.4.3
2
+ # turntable v0.7
3
3
  # Christian Koch <ckoch002@student.ucr.edu>
4
4
  #
5
5
 
@@ -8,12 +8,21 @@ require 'ostruct'
8
8
 
9
9
  class Turntable < Array
10
10
 
11
- @@version = 'v0.6.4.3'
11
+ @@version = 'v0.7'
12
12
 
13
13
  @@insert_proc = %q(
14
14
  if args.length != @columns.length
15
15
  raise ArgumentError, "wrong number of arguments (#{args.length} for #{@columns.length})"
16
16
  end
17
+
18
+ if @types
19
+ test_types = @types.dup
20
+ args.each do |arg|
21
+ type_should_be = test_types.shift
22
+ raise TypeError, "expected #{type_should_be} instead of #{arg.class}" unless arg.is_a?(type_should_be)
23
+ end
24
+ end
25
+
17
26
  row = Row.new
18
27
  self.empty? ? (row.id = 0) : (row.id = self.last.id + 1)
19
28
  @columns.each { |column| eval "row.#{column} = args.shift" }
@@ -36,6 +45,7 @@ class Turntable < Array
36
45
  end
37
46
 
38
47
  @filename = File.expand_path(filename)
48
+ @types = nil
39
49
 
40
50
  self.save_to @filename
41
51
  end
@@ -59,15 +69,37 @@ class Turntable < Array
59
69
 
60
70
  # Reader methods for this Turntable's metadata.
61
71
  def Turntable.version; @@version; end
62
- attr_reader :filename, :columns
72
+ attr_reader :filename, :columns, :types
73
+
74
+ # Inserts a new column to the database. If the table is strictly typed, then
75
+ # all the preexisting rows are filled with new objects of that class. If the
76
+ # class is numeric, then the rows are filled with the appropriate form of 0.
77
+ # Otherwise, they're filled with just nil. Returns the new columns list.
78
+ def add_column column_name, column_type=nil
79
+ if @types
80
+ raise ArgumentError, 'expecting a class name' unless column_type.is_a?(Class)
81
+ @columns.push column_name
82
+ @types.push column_type
83
+
84
+ # For some reason you can't switch through classes, but you can if
85
+ # it's a string
86
+ case column_type.inspect
87
+ when 'Fixnum', 'Integer'
88
+ what_to_add = "0"
89
+ when 'Float'
90
+ what_to_add = "0.0"
91
+ else
92
+ what_to_add = "#{column_type}.new"
93
+ end
94
+
95
+ self.each { |row| eval "row.#{column_name} = #{what_to_add}" }
96
+ else
97
+ @columns.push column_name
98
+ self.each { |row| eval "row.#{column_name} = nil" }
99
+ end
63
100
 
64
- # Inserts a new column to the database. Fills all the pre-existing rows with
65
- # nil. Returns the new database.
66
- def add_column column_name
67
- @columns.push column_name
68
- self.each { |row| eval "row.#{column_name} = nil" }
69
101
  self.save_to @filename
70
- self
102
+ self.columns
71
103
  end
72
104
 
73
105
  # Removes a specific row. Returns the deleted row.
@@ -95,6 +127,7 @@ class Turntable < Array
95
127
 
96
128
  # Same as Turntable#insert, except this method accepts only one array filled
97
129
  # with values.
130
+ # TODO: this isn't necessary
98
131
  def insert_array args
99
132
  raise ArgumentError, 'Turntable#insert_array requires one array' unless args.is_a?(Array)
100
133
  eval @@insert_proc
@@ -102,7 +135,7 @@ class Turntable < Array
102
135
 
103
136
  # Custom inspect() makes working in IRB much cleaner.
104
137
  def inspect
105
- "#<#{self.class}:#{self.object_id} @filename=#{self.filename.inspect}, @columns=#{self.columns.inspect}>"
138
+ "#<#{self.class}:#{self.object_id} @filename=#{self.filename.inspect}, @columns=#{self.columns.inspect}, @types=#{self.types.inspect}>"
106
139
  end
107
140
 
108
141
  # Prints the entire database to STDOUT. It's just a wrapper for
@@ -111,13 +144,38 @@ class Turntable < Array
111
144
  self.to_a.to_stdout
112
145
  end
113
146
 
114
- # Since []= is too much of a pain to implement with structs, we'll just
115
- # provide a PStore-style kind of transaction.
147
+ # Changes to preexisting rows must occur inside an update() block. It's sort
148
+ # of like PStore#transaction.
116
149
  def update
117
150
  what_happened = yield
118
151
  self.save_to @filename
119
152
  what_happened
120
153
  end
154
+
155
+ # Causes self to become strictly typed. Accepts either a list of classes, or
156
+ # one array which contains the same thing.
157
+ def use_strict_typing! *args
158
+ if args.length == 1
159
+ unless args[0].is_a?(Array) and (args[0].length == @columns.length)
160
+ raise ArgumentError, "wrong number of elements (#{args.length} for #{@columns.length})"
161
+ end
162
+ args = args[0]
163
+ else
164
+ if args.length != @columns.length
165
+ raise ArgumentError, "wrong number of arguments (#{args.length} for #{@columns.length})"
166
+ end
167
+ end
168
+
169
+ # All arguments must be classes.
170
+ if args.select { |arg| arg.is_a?(Class) } == args
171
+ @types = args
172
+ else
173
+ raise TypeError, "use_strict_typing!() requires a list of classes"
174
+ end
175
+
176
+ self.save_to @filename
177
+ @types
178
+ end
121
179
 
122
180
  protected
123
181
  # Saves self to an external file.
@@ -136,16 +194,16 @@ class Array
136
194
 
137
195
  # Returns an array of rows in a HTML-formatted table.
138
196
  def to_html
139
- string = '<table>'
197
+ string = "<table>\n"
140
198
 
141
- string += '<tr>'
142
- self.first.table.each_key { |column| string += "<th>#{column}</th>" }
143
- string += '</tr>'
199
+ string += "\t<tr>\n"
200
+ self.first.table.each_key { |column| string += "\t\t<th>#{column}</th>\n" }
201
+ string += "\t</tr>\n"
144
202
 
145
203
  self.each do |row|
146
- string += '<tr>'
147
- row.table.each_value { |value| string += "<td>#{value}</td>" }
148
- string += '</tr>'
204
+ string += "\t<tr>\n"
205
+ row.table.each_value { |value| string += "\t\t<td>#{value}</td>\n" }
206
+ string += "\t</tr>\n"
149
207
  end
150
208
  string += '</table>'
151
209
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: christiank-turntable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4.3
4
+ version: "0.7"
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Koch
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-24 00:00:00 -07:00
12
+ date: 2009-07-01 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15