datamapper 0.1.1 → 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.
Files changed (131) hide show
  1. data/CHANGELOG +65 -0
  2. data/README +193 -1
  3. data/do_performance.rb +153 -0
  4. data/environment.rb +45 -0
  5. data/example.rb +119 -22
  6. data/lib/data_mapper.rb +36 -16
  7. data/lib/data_mapper/adapters/abstract_adapter.rb +8 -0
  8. data/lib/data_mapper/adapters/data_object_adapter.rb +360 -0
  9. data/lib/data_mapper/adapters/mysql_adapter.rb +30 -179
  10. data/lib/data_mapper/adapters/postgresql_adapter.rb +90 -199
  11. data/lib/data_mapper/adapters/sql/coersion.rb +32 -3
  12. data/lib/data_mapper/adapters/sql/commands/conditions.rb +97 -128
  13. data/lib/data_mapper/adapters/sql/commands/load_command.rb +234 -231
  14. data/lib/data_mapper/adapters/sql/commands/loader.rb +99 -0
  15. data/lib/data_mapper/adapters/sql/mappings/associations_set.rb +30 -0
  16. data/lib/data_mapper/adapters/sql/mappings/column.rb +68 -6
  17. data/lib/data_mapper/adapters/sql/mappings/schema.rb +6 -3
  18. data/lib/data_mapper/adapters/sql/mappings/table.rb +71 -42
  19. data/lib/data_mapper/adapters/sql/quoting.rb +8 -2
  20. data/lib/data_mapper/adapters/sqlite3_adapter.rb +32 -201
  21. data/lib/data_mapper/associations.rb +21 -7
  22. data/lib/data_mapper/associations/belongs_to_association.rb +96 -80
  23. data/lib/data_mapper/associations/has_and_belongs_to_many_association.rb +158 -67
  24. data/lib/data_mapper/associations/has_many_association.rb +96 -78
  25. data/lib/data_mapper/associations/has_n_association.rb +64 -0
  26. data/lib/data_mapper/associations/has_one_association.rb +49 -79
  27. data/lib/data_mapper/associations/reference.rb +47 -0
  28. data/lib/data_mapper/base.rb +216 -50
  29. data/lib/data_mapper/callbacks.rb +71 -24
  30. data/lib/data_mapper/{session.rb → context.rb} +20 -8
  31. data/lib/data_mapper/database.rb +176 -45
  32. data/lib/data_mapper/embedded_value.rb +65 -0
  33. data/lib/data_mapper/identity_map.rb +12 -4
  34. data/lib/data_mapper/support/active_record_impersonation.rb +12 -8
  35. data/lib/data_mapper/support/enumerable.rb +8 -0
  36. data/lib/data_mapper/support/serialization.rb +13 -0
  37. data/lib/data_mapper/support/string.rb +1 -12
  38. data/lib/data_mapper/support/symbol.rb +3 -0
  39. data/lib/data_mapper/validations/unique_validator.rb +1 -2
  40. data/lib/data_mapper/validations/validation_helper.rb +18 -1
  41. data/performance.rb +109 -34
  42. data/plugins/can_has_sphinx/LICENSE +23 -0
  43. data/plugins/can_has_sphinx/README +4 -0
  44. data/plugins/can_has_sphinx/REVISION +1 -0
  45. data/plugins/can_has_sphinx/Rakefile +22 -0
  46. data/plugins/can_has_sphinx/init.rb +1 -0
  47. data/plugins/can_has_sphinx/install.rb +1 -0
  48. data/plugins/can_has_sphinx/lib/acts_as_sphinx.rb +123 -0
  49. data/plugins/can_has_sphinx/lib/sphinx.rb +460 -0
  50. data/plugins/can_has_sphinx/scripts/sphinx.sh +47 -0
  51. data/plugins/can_has_sphinx/tasks/acts_as_sphinx_tasks.rake +41 -0
  52. data/plugins/dataobjects/REVISION +1 -0
  53. data/plugins/dataobjects/Rakefile +7 -0
  54. data/plugins/dataobjects/do.rb +246 -0
  55. data/plugins/dataobjects/do_mysql.rb +179 -0
  56. data/plugins/dataobjects/do_postgres.rb +181 -0
  57. data/plugins/dataobjects/do_sqlite3.rb +153 -0
  58. data/plugins/dataobjects/spec/do_spec.rb +150 -0
  59. data/plugins/dataobjects/spec/spec_helper.rb +81 -0
  60. data/plugins/dataobjects/swig_mysql/do_mysql.bundle +0 -0
  61. data/plugins/dataobjects/swig_mysql/extconf.rb +33 -0
  62. data/plugins/dataobjects/swig_mysql/mysql_c.c +18800 -0
  63. data/plugins/dataobjects/swig_mysql/mysql_c.i +8 -0
  64. data/plugins/dataobjects/swig_mysql/mysql_supp.i +46 -0
  65. data/plugins/dataobjects/swig_postgres/Makefile +146 -0
  66. data/plugins/dataobjects/swig_postgres/extconf.rb +29 -0
  67. data/plugins/dataobjects/swig_postgres/postgres_c.bundle +0 -0
  68. data/plugins/dataobjects/swig_postgres/postgres_c.c +8185 -0
  69. data/plugins/dataobjects/swig_postgres/postgres_c.i +73 -0
  70. data/plugins/dataobjects/swig_sqlite/db +0 -0
  71. data/plugins/dataobjects/swig_sqlite/extconf.rb +9 -0
  72. data/plugins/dataobjects/swig_sqlite/sqlite3_c.c +4725 -0
  73. data/plugins/dataobjects/swig_sqlite/sqlite_c.i +168 -0
  74. data/rakefile.rb +45 -23
  75. data/spec/acts_as_tree_spec.rb +39 -0
  76. data/spec/associations_spec.rb +220 -0
  77. data/spec/attributes_spec.rb +15 -0
  78. data/spec/base_spec.rb +44 -0
  79. data/spec/callbacks_spec.rb +45 -0
  80. data/spec/can_has_sphinx.rb +6 -0
  81. data/spec/coersion_spec.rb +34 -0
  82. data/spec/conditions_spec.rb +49 -0
  83. data/spec/conversions_to_yaml_spec.rb +17 -0
  84. data/spec/count_command_spec.rb +11 -0
  85. data/spec/delete_command_spec.rb +1 -1
  86. data/spec/embedded_value_spec.rb +23 -0
  87. data/spec/fixtures/animals_exhibits.yaml +2 -0
  88. data/spec/fixtures/people.yaml +18 -1
  89. data/spec/{legacy.rb → legacy_spec.rb} +3 -3
  90. data/spec/load_command_spec.rb +157 -20
  91. data/spec/magic_columns_spec.rb +9 -0
  92. data/spec/mock_adapter.rb +20 -0
  93. data/spec/models/animal.rb +1 -1
  94. data/spec/models/animals_exhibit.rb +6 -0
  95. data/spec/models/exhibit.rb +2 -0
  96. data/spec/models/person.rb +26 -1
  97. data/spec/models/project.rb +19 -0
  98. data/spec/models/sales_person.rb +1 -0
  99. data/spec/models/section.rb +6 -0
  100. data/spec/models/zoo.rb +3 -1
  101. data/spec/query_spec.rb +9 -0
  102. data/spec/save_command_spec.rb +65 -1
  103. data/spec/schema_spec.rb +89 -0
  104. data/spec/single_table_inheritance_spec.rb +27 -0
  105. data/spec/spec_helper.rb +9 -55
  106. data/spec/{symbolic_operators.rb → symbolic_operators_spec.rb} +9 -5
  107. data/spec/{validates_confirmation_of.rb → validates_confirmation_of_spec.rb} +4 -3
  108. data/spec/{validates_format_of.rb → validates_format_of_spec.rb} +5 -4
  109. data/spec/{validates_length_of.rb → validates_length_of_spec.rb} +8 -7
  110. data/spec/{validates_uniqueness_of.rb → validates_uniqueness_of_spec.rb} +7 -10
  111. data/spec/{validations.rb → validations_spec.rb} +24 -6
  112. data/tasks/drivers.rb +20 -0
  113. data/tasks/fixtures.rb +42 -0
  114. metadata +181 -42
  115. data/lib/data_mapper/adapters/sql/commands/advanced_load_command.rb +0 -140
  116. data/lib/data_mapper/adapters/sql/commands/delete_command.rb +0 -113
  117. data/lib/data_mapper/adapters/sql/commands/save_command.rb +0 -141
  118. data/lib/data_mapper/adapters/sql/commands/table_exists_command.rb +0 -33
  119. data/lib/data_mapper/adapters/sql_adapter.rb +0 -163
  120. data/lib/data_mapper/associations/advanced_has_many_association.rb +0 -55
  121. data/lib/data_mapper/support/blank_slate.rb +0 -3
  122. data/lib/data_mapper/support/proc.rb +0 -69
  123. data/lib/data_mapper/support/struct.rb +0 -26
  124. data/lib/data_mapper/unit_of_work.rb +0 -38
  125. data/spec/basic_finder.rb +0 -67
  126. data/spec/belongs_to.rb +0 -47
  127. data/spec/has_and_belongs_to_many.rb +0 -25
  128. data/spec/has_many.rb +0 -34
  129. data/spec/new_record.rb +0 -24
  130. data/spec/sub_select.rb +0 -16
  131. data/spec/support/string_spec.rb +0 -7
@@ -0,0 +1,47 @@
1
+ #!/bin/sh
2
+ #
3
+ # start/stop searchd server.
4
+
5
+ if ! [ -x /usr/local/bin/searchd ]; then
6
+ exit 0
7
+ fi
8
+
9
+ case "$1" in
10
+ start)
11
+ echo -n "Starting sphinx searchd server:"
12
+ echo -n " searchd" ;
13
+ /sbin/start-stop-daemon --start --quiet --pidfile /var/run/searchd.pid --chdir /etc --exec /usr/local/bin/searchd
14
+ echo "."
15
+ ;;
16
+ stop)
17
+ echo -n "Stopping sphinx searchd server:"
18
+ echo -n " searchd" ;
19
+ /sbin/start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/searchd.pid --exec /usr/local/bin/searchd
20
+ echo "."
21
+ ;;
22
+ reload)
23
+ echo -n "Reloading sphinx searchd server:"
24
+ echo -n " searchd"
25
+ /sbin/start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/searchd.pid --signal 1
26
+ echo "."
27
+ ;;
28
+ force-reload)
29
+ $0 reload
30
+ ;;
31
+ reindex)
32
+ cd /etc
33
+ /usr/local/bin/indexer --rotate --quiet --all
34
+ ;;
35
+ restart)
36
+ echo -n "Restarting sphinx searchd server:"
37
+ echo -n " searchd"
38
+ /sbin/start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/searchd.pid --exec /usr/local/bin/searchd
39
+ /sbin/start-stop-daemon --start --quiet --pidfile /var/run/searchd.pid --chdir /etc --exec /usr/local/bin/searchd
40
+ echo "."
41
+ ;;
42
+ *)
43
+ echo "Usage: /etc/init.d/searchd {start|stop|reload|restart|reindex}"
44
+ exit 1
45
+ ;;
46
+ esac
47
+ exit 0
@@ -0,0 +1,41 @@
1
+ namespace :sphinx do
2
+ desc "Run indexer"
3
+ task :index do
4
+ cd 'config' do
5
+ system 'indexer --all'
6
+ end
7
+ end
8
+
9
+ desc "Rotate idendexes and restart searchd server"
10
+ task :rotate do
11
+ cd 'config' do
12
+ system 'indexer --rotate --all'
13
+ end
14
+ end
15
+
16
+ desc "Start searchd server"
17
+ task :start do
18
+ if File.exists?('/var/run/searchd.pid')
19
+ puts 'Sphinx searchd server is already started.'
20
+ else
21
+ cd 'config' do
22
+ system 'searchd'
23
+ puts 'Sphinx searchd server started.'
24
+ end
25
+ end
26
+ end
27
+
28
+ desc "Stop searchd server"
29
+ task :stop do
30
+ unless File.exists?('/var/run/searchd.pid')
31
+ puts 'Sphinx searchd server is not running.'
32
+ else
33
+ pid = File.read('/var/run/searchd.pid').chomp
34
+ system "kill #{pid}"
35
+ puts 'Sphinx searchd server stopped.'
36
+ end
37
+ end
38
+
39
+ desc "Restart searchd server"
40
+ task :restart => [:stop, :start]
41
+ end
@@ -0,0 +1 @@
1
+ 18
@@ -0,0 +1,7 @@
1
+ require 'spec/rake/spectask'
2
+
3
+ desc "Run all specs"
4
+ Spec::Rake::SpecTask.new('specs') do |t|
5
+ t.spec_opts = ["--format", "specdoc", "--colour"]
6
+ t.spec_files = Dir['spec/*_spec.rb'].sort
7
+ end
@@ -0,0 +1,246 @@
1
+ require 'date'
2
+
3
+ # Thanks http://www.rubyweeklynews.org/20051120
4
+ class DateTime
5
+ def to_time
6
+ Time.mktime(year, mon, day, hour, min, sec)
7
+ end
8
+
9
+ def to_date
10
+ Date.new(year, mon, day)
11
+ end
12
+ end
13
+
14
+ class Time
15
+ def to_datetime
16
+ DateTime.civil(year, mon, day, hour, min, sec)
17
+ end
18
+
19
+ def to_s_db
20
+ strftime("%Y-%m-%d %X")
21
+ end
22
+ end
23
+
24
+ module DataObject
25
+ STATE_OPEN = 0
26
+ STATE_CLOSED = 1
27
+
28
+ class Connection
29
+
30
+ attr_reader :timeout, :database, :datasource, :server_version, :state
31
+
32
+ def initialize(connection_string)
33
+ end
34
+
35
+ def begin_transaction
36
+ # TODO: Hook this up
37
+ Transaction.new
38
+ end
39
+
40
+ def change_database(database_name)
41
+ raise NotImplementedError
42
+ end
43
+
44
+ def open
45
+ raise NotImplementedError
46
+ end
47
+
48
+ def close
49
+ raise NotImplementedError
50
+ end
51
+
52
+ def create_command(text)
53
+ Command.new(self, text)
54
+ end
55
+
56
+ def closed?
57
+ @state == STATE_CLOSED
58
+ end
59
+
60
+ end
61
+
62
+ class Transaction
63
+
64
+ attr_reader :connection
65
+
66
+ def initialize(conn)
67
+ @connection = conn
68
+ end
69
+
70
+ # Commits the transaction
71
+ def commit
72
+ raise NotImplementedError
73
+ end
74
+
75
+ # Rolls back the transaction
76
+ def rollback(savepoint = nil)
77
+ raise NotImplementedError
78
+ end
79
+
80
+ # Creates a savepoint for rolling back later (not commonly supported)
81
+ def save(name)
82
+ raise NotImplementedError
83
+ end
84
+
85
+ end
86
+
87
+ class Reader
88
+ include Enumerable
89
+
90
+ attr_reader :field_count, :has_rows, :records_affected, :fields
91
+ alias_method :has_rows?, :has_rows
92
+
93
+ def each
94
+ return nil unless has_rows
95
+ while(true) do
96
+ yield
97
+ break unless self.next
98
+ end
99
+ end
100
+
101
+ def current_row
102
+ ret = []
103
+ field_count.times do |i|
104
+ ret[i] = item(i)
105
+ end
106
+ ret
107
+ end
108
+
109
+ def close
110
+ raise NotImplementedError
111
+ end
112
+
113
+ # retrieves the Ruby data type for a particular column number
114
+ def data_type_name(col)
115
+ raise ReaderClosed, "You cannot ask for metadata once the reader is closed" if state_closed?
116
+ end
117
+
118
+ # retrieves the name of a particular column number
119
+ def name(col)
120
+ raise ReaderClosed, "You cannot ask for metadata once the reader is closed" if state_closed?
121
+ end
122
+
123
+ # retrives the index of the column with a particular name
124
+ def get_index(name)
125
+ raise ReaderClosed, "You cannot ask for metadata once the reader is closed" if state_closed?
126
+ end
127
+
128
+ def item(idx)
129
+ raise ReaderClosed, "You cannot ask for information once the reader is closed" if state_closed?
130
+ end
131
+
132
+ # returns an array of hashes containing the following information
133
+ #
134
+ # name: the column name
135
+ # index: the index of the column
136
+ # max_size: the maximum allowed size of the data in the column
137
+ # precision: the precision (for column types that support it)
138
+ # scale: the scale (for column types that support it)
139
+ # unique: boolean specifying whether the values must be unique
140
+ # key: boolean specifying whether this column is, or is part
141
+ # of, the primary key
142
+ # catalog: the name of the database this column is part of
143
+ # base_name: the original name of the column (if AS was used,
144
+ # this will provide the original name)
145
+ # schema: the name of the schema (if supported)
146
+ # table: the name of the table this column is part of
147
+ # data_type: the name of the Ruby data type used
148
+ # allow_null: boolean specifying whether nulls are allowed
149
+ # db_type: the type specified by the DB
150
+ # aliased: boolean specifying whether the column has been
151
+ # renamed using AS
152
+ # calculated: boolean specifying whether the field is calculated
153
+ # serial: boolean specifying whether the field is a serial
154
+ # column
155
+ # blob: boolean specifying whether the field is a BLOB
156
+ # readonly: boolean specifying whether the field is readonly
157
+ def get_schema
158
+ raise ReaderClosed, "You cannot ask for metadata once the reader is closed" if state_closed?
159
+ end
160
+
161
+ # specifies whether the column identified by the passed in index
162
+ # is null.
163
+ def null?(idx)
164
+ raise ReaderClosed, "You cannot ask for column information once the reader is closed" if state_closed?
165
+ end
166
+
167
+ # Consumes the next result. Returns true if a result is consumed and
168
+ # false if none is
169
+ def next
170
+ raise ReaderClosed, "You cannot increment the cursor once the reader is closed" if state_closed?
171
+ end
172
+
173
+ protected
174
+ def state_closed?
175
+ @state == STATE_CLOSED
176
+ end
177
+
178
+ def native_type
179
+ raise ReaderClosed, "You cannot check the type of a column once the reader is closed" if state_closed?
180
+ end
181
+
182
+ end
183
+
184
+ class ResultData
185
+
186
+ def initialize(conn, affected_rows, last_insert_row = nil)
187
+ @conn, @affected_rows, @last_insert_row = conn, affected_rows, last_insert_row
188
+ end
189
+
190
+ attr_reader :affected_rows, :last_insert_row
191
+ alias_method :to_i, :affected_rows
192
+
193
+ end
194
+
195
+ class Schema < Array
196
+
197
+ end
198
+
199
+ class Command
200
+
201
+ attr_reader :text, :timeout, :connection
202
+
203
+ # initialize creates a new Command object
204
+ def initialize(connection, text)
205
+ @connection, @text = connection, text
206
+ end
207
+
208
+ def execute_non_query
209
+ raise LostConnectionError, "the connection to the database has been lost" if @connection.closed?
210
+ end
211
+
212
+ def execute_reader
213
+ raise LostConnectionError, "the connection to the database has been lost" if @connection.closed?
214
+ end
215
+
216
+ def prepare
217
+ raise NotImplementedError
218
+ end
219
+
220
+ end
221
+
222
+ class NotImplementedError < StandardError
223
+ end
224
+
225
+ class ConnectionFailed < StandardError
226
+ end
227
+
228
+ class ReaderClosed < StandardError
229
+ end
230
+
231
+ class ReaderError < StandardError
232
+ end
233
+
234
+ class QueryError < StandardError
235
+ end
236
+
237
+ class NoInsertError < StandardError
238
+ end
239
+
240
+ class LostConnectionError < StandardError
241
+ end
242
+
243
+ class UnknownError < StandardError
244
+ end
245
+
246
+ end
@@ -0,0 +1,179 @@
1
+ require 'mysql_c'
2
+ require 'do'
3
+
4
+ module DataObject
5
+ module Mysql
6
+ TYPES = Hash[*Mysql_c.constants.select {|x| x.include?("MYSQL_TYPE")}.map {|x| [Mysql_c.const_get(x), x.gsub(/^MYSQL_TYPE_/, "")]}.flatten]
7
+
8
+ QUOTE_STRING = "\""
9
+ QUOTE_COLUMN = "`"
10
+
11
+ class Connection < DataObject::Connection
12
+ attr_reader :db
13
+
14
+ def initialize(connection_string)
15
+ @state = STATE_CLOSED
16
+ @connection_string = connection_string
17
+ opts = connection_string.split(" ")
18
+ opts.each do |opt|
19
+ k, v = opt.split("=")
20
+ raise ArgumentError, "you specified an invalid connection component: #{opt}" unless k && v
21
+ instance_variable_set("@#{k}", v)
22
+ end
23
+ end
24
+
25
+ def change_database(database_name)
26
+ @dbname = database_name
27
+ @connection_string.gsub(/db_name=[^ ]*/, "db_name=#{database_name}")
28
+ end
29
+
30
+ def open
31
+ @db = Mysql_c.mysql_init(nil)
32
+ raise ConnectionFailed, "could not allocate a MySQL connection" unless @db
33
+ conn = Mysql_c.mysql_real_connect(@db, @host, @user, @password, @dbname, @port || 0, @socket, @flags || 0)
34
+ raise ConnectionFailed, "The connection with connection string #{@connection_string} failed\n#{Mysql_c.mysql_error(@db)}" unless conn
35
+ @state = STATE_OPEN
36
+ true
37
+ end
38
+
39
+ def close
40
+ if @state == STATE_OPEN
41
+ Mysql_c.mysql_close(@db)
42
+ @state = STATE_CLOSED
43
+ true
44
+ else
45
+ false
46
+ end
47
+ end
48
+
49
+ def create_command(text)
50
+ Command.new(self, text)
51
+ end
52
+
53
+ end
54
+
55
+ class Reader < DataObject::Reader
56
+
57
+ def initialize(db, reader)
58
+ @reader = reader
59
+ unless @reader
60
+ if Mysql_c.mysql_field_count(db) == 0
61
+ @records_affected = Mysql_c.mysql_affected_rows(db)
62
+ close
63
+ else
64
+ raise UnknownError, "An unknown error has occured while trying to process a MySQL query.\n#{Mysql_c.mysql_error(db)}"
65
+ end
66
+ else
67
+ @field_count = Mysql_c.mysql_num_fields(@reader)
68
+ @state = STATE_OPEN
69
+ self.next
70
+ fields = Mysql_c.mysql_fetch_fields(@reader)
71
+ @native_fields = fields
72
+ raise UnknownError, "An unknown error has occured while trying to process a MySQL query. There were no fields in the resultset\n#{Mysql_c.mysql_error(db)}" unless fields
73
+ @fields = fields.map {|field| field.name}
74
+ @rows = Mysql_c.mysql_num_rows(@reader)
75
+ @has_rows = @rows > 0
76
+ end
77
+ end
78
+
79
+ def close
80
+ if @state != STATE_CLOSED
81
+ Mysql_c.mysql_free_result(@reader)
82
+ @state = STATE_CLOSED
83
+ true
84
+ else
85
+ false
86
+ end
87
+ end
88
+
89
+ def name(col)
90
+ super
91
+ @fields[col]
92
+ end
93
+
94
+ def get_index(name)
95
+ super
96
+ @fields.index(name)
97
+ end
98
+
99
+ def null?(idx)
100
+ super
101
+ @row[idx] == nil
102
+ end
103
+
104
+ def item(idx)
105
+ super
106
+ typecast(@row[idx], idx)
107
+ end
108
+
109
+ def next
110
+ super
111
+ @row = Mysql_c.mysql_fetch_row(@reader)
112
+ close if @row.nil?
113
+ @row ? true : nil
114
+ end
115
+
116
+ protected
117
+ def native_type(col)
118
+ super
119
+ TYPES[@native_fields[col].type]
120
+ end
121
+
122
+ def typecast(val, idx)
123
+ return nil if val.nil?
124
+ field = @native_fields[idx]
125
+ case TYPES[field.type]
126
+ when "TINY"
127
+ if field.max_length == 1
128
+ val != "0"
129
+ else
130
+ val.to_i
131
+ end
132
+ when "BIT"
133
+ val.to_i(2)
134
+ when "SHORT", "LONG", "INT24", "LONGLONG"
135
+ val.to_i
136
+ when "DECIMAL", "NEWDECIMAL", "FLOAT", "DOUBLE", "YEAR"
137
+ val.to_f
138
+ when "TIMESTAMP", "DATETIME"
139
+ DateTime.parse(val) rescue nil
140
+ when "TIME"
141
+ DateTime.parse(val).to_time rescue nil
142
+ when "DATE"
143
+ Date.parse(val) rescue nil
144
+ when "NULL"
145
+ nil
146
+ else
147
+ val
148
+ end
149
+ end
150
+
151
+
152
+ end
153
+
154
+ class Command < DataObject::Command
155
+
156
+ def execute_reader
157
+ super
158
+ result = Mysql_c.mysql_query(@connection.db, @text)
159
+ # TODO: Real Error
160
+ raise QueryError, "Your query failed.\n#{Mysql_c.mysql_error(@connection.db)}\n#{@text}" unless result == 0
161
+ reader = Mysql_c.mysql_store_result(@connection.db)
162
+ Reader.new(@connection.db, reader)
163
+ end
164
+
165
+ def execute_non_query
166
+ super
167
+ result = Mysql_c.mysql_query(@connection.db, @text)
168
+ raise QueryError, "Your query failed.\n#{Mysql_c.mysql_error(@connection.db)}\n#{@text}" unless result == 0
169
+ reader = Mysql_c.mysql_store_result(@connection.db)
170
+ raise QueryError, "You called execute_non_query on a query: #{@text}" if reader
171
+ rows_affected = Mysql_c.mysql_affected_rows(@connection.db)
172
+ Mysql_c.mysql_free_result(reader)
173
+ return ResultData.new(@connection, rows_affected, Mysql_c.mysql_insert_id(@connection.db))
174
+ end
175
+
176
+ end
177
+
178
+ end
179
+ end