activerecord_csi 2.3.5.p6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (333) hide show
  1. data/CHANGELOG +5858 -0
  2. data/README +351 -0
  3. data/RUNNING_UNIT_TESTS +36 -0
  4. data/Rakefile +270 -0
  5. data/examples/associations.png +0 -0
  6. data/examples/performance.rb +162 -0
  7. data/install.rb +30 -0
  8. data/lib/active_record/aggregations.rb +261 -0
  9. data/lib/active_record/association_preload.rb +389 -0
  10. data/lib/active_record/associations/association_collection.rb +475 -0
  11. data/lib/active_record/associations/association_proxy.rb +278 -0
  12. data/lib/active_record/associations/belongs_to_association.rb +76 -0
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +53 -0
  14. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +143 -0
  15. data/lib/active_record/associations/has_many_association.rb +122 -0
  16. data/lib/active_record/associations/has_many_through_association.rb +266 -0
  17. data/lib/active_record/associations/has_one_association.rb +133 -0
  18. data/lib/active_record/associations/has_one_through_association.rb +37 -0
  19. data/lib/active_record/associations.rb +2241 -0
  20. data/lib/active_record/attribute_methods.rb +388 -0
  21. data/lib/active_record/autosave_association.rb +364 -0
  22. data/lib/active_record/base.rb +3171 -0
  23. data/lib/active_record/batches.rb +81 -0
  24. data/lib/active_record/calculations.rb +311 -0
  25. data/lib/active_record/callbacks.rb +360 -0
  26. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +371 -0
  27. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +139 -0
  28. data/lib/active_record/connection_adapters/abstract/database_statements.rb +289 -0
  29. data/lib/active_record/connection_adapters/abstract/query_cache.rb +94 -0
  30. data/lib/active_record/connection_adapters/abstract/quoting.rb +69 -0
  31. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +722 -0
  32. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +434 -0
  33. data/lib/active_record/connection_adapters/abstract_adapter.rb +241 -0
  34. data/lib/active_record/connection_adapters/mysql_adapter.rb +630 -0
  35. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1113 -0
  36. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -0
  37. data/lib/active_record/connection_adapters/sqlite_adapter.rb +453 -0
  38. data/lib/active_record/dirty.rb +183 -0
  39. data/lib/active_record/dynamic_finder_match.rb +41 -0
  40. data/lib/active_record/dynamic_scope_match.rb +25 -0
  41. data/lib/active_record/fixtures.rb +996 -0
  42. data/lib/active_record/i18n_interpolation_deprecation.rb +26 -0
  43. data/lib/active_record/locale/en.yml +58 -0
  44. data/lib/active_record/locking/optimistic.rb +148 -0
  45. data/lib/active_record/locking/pessimistic.rb +55 -0
  46. data/lib/active_record/migration.rb +566 -0
  47. data/lib/active_record/named_scope.rb +192 -0
  48. data/lib/active_record/nested_attributes.rb +392 -0
  49. data/lib/active_record/observer.rb +197 -0
  50. data/lib/active_record/query_cache.rb +33 -0
  51. data/lib/active_record/reflection.rb +320 -0
  52. data/lib/active_record/schema.rb +51 -0
  53. data/lib/active_record/schema_dumper.rb +182 -0
  54. data/lib/active_record/serialization.rb +101 -0
  55. data/lib/active_record/serializers/json_serializer.rb +91 -0
  56. data/lib/active_record/serializers/xml_serializer.rb +357 -0
  57. data/lib/active_record/session_store.rb +326 -0
  58. data/lib/active_record/test_case.rb +66 -0
  59. data/lib/active_record/timestamp.rb +71 -0
  60. data/lib/active_record/transactions.rb +235 -0
  61. data/lib/active_record/validations.rb +1135 -0
  62. data/lib/active_record/version.rb +9 -0
  63. data/lib/active_record.rb +84 -0
  64. data/lib/activerecord.rb +2 -0
  65. data/test/assets/example.log +1 -0
  66. data/test/assets/flowers.jpg +0 -0
  67. data/test/cases/aaa_create_tables_test.rb +24 -0
  68. data/test/cases/active_schema_test_mysql.rb +100 -0
  69. data/test/cases/active_schema_test_postgresql.rb +24 -0
  70. data/test/cases/adapter_test.rb +145 -0
  71. data/test/cases/aggregations_test.rb +167 -0
  72. data/test/cases/ar_schema_test.rb +32 -0
  73. data/test/cases/associations/belongs_to_associations_test.rb +425 -0
  74. data/test/cases/associations/callbacks_test.rb +161 -0
  75. data/test/cases/associations/cascaded_eager_loading_test.rb +131 -0
  76. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -0
  77. data/test/cases/associations/eager_load_nested_include_test.rb +130 -0
  78. data/test/cases/associations/eager_singularization_test.rb +145 -0
  79. data/test/cases/associations/eager_test.rb +834 -0
  80. data/test/cases/associations/extension_test.rb +62 -0
  81. data/test/cases/associations/habtm_join_table_test.rb +56 -0
  82. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +822 -0
  83. data/test/cases/associations/has_many_associations_test.rb +1134 -0
  84. data/test/cases/associations/has_many_through_associations_test.rb +346 -0
  85. data/test/cases/associations/has_one_associations_test.rb +330 -0
  86. data/test/cases/associations/has_one_through_associations_test.rb +209 -0
  87. data/test/cases/associations/inner_join_association_test.rb +93 -0
  88. data/test/cases/associations/join_model_test.rb +712 -0
  89. data/test/cases/associations_test.rb +262 -0
  90. data/test/cases/attribute_methods_test.rb +305 -0
  91. data/test/cases/autosave_association_test.rb +1142 -0
  92. data/test/cases/base_test.rb +2154 -0
  93. data/test/cases/batches_test.rb +61 -0
  94. data/test/cases/binary_test.rb +30 -0
  95. data/test/cases/calculations_test.rb +348 -0
  96. data/test/cases/callbacks_observers_test.rb +38 -0
  97. data/test/cases/callbacks_test.rb +438 -0
  98. data/test/cases/class_inheritable_attributes_test.rb +32 -0
  99. data/test/cases/column_alias_test.rb +17 -0
  100. data/test/cases/column_definition_test.rb +70 -0
  101. data/test/cases/connection_pool_test.rb +25 -0
  102. data/test/cases/connection_test_firebird.rb +8 -0
  103. data/test/cases/connection_test_mysql.rb +64 -0
  104. data/test/cases/copy_table_test_sqlite.rb +80 -0
  105. data/test/cases/database_statements_test.rb +12 -0
  106. data/test/cases/datatype_test_postgresql.rb +204 -0
  107. data/test/cases/date_time_test.rb +37 -0
  108. data/test/cases/default_test_firebird.rb +16 -0
  109. data/test/cases/defaults_test.rb +111 -0
  110. data/test/cases/deprecated_finder_test.rb +30 -0
  111. data/test/cases/dirty_test.rb +316 -0
  112. data/test/cases/finder_respond_to_test.rb +76 -0
  113. data/test/cases/finder_test.rb +1066 -0
  114. data/test/cases/fixtures_test.rb +656 -0
  115. data/test/cases/helper.rb +68 -0
  116. data/test/cases/i18n_test.rb +46 -0
  117. data/test/cases/inheritance_test.rb +262 -0
  118. data/test/cases/invalid_date_test.rb +24 -0
  119. data/test/cases/json_serialization_test.rb +205 -0
  120. data/test/cases/lifecycle_test.rb +193 -0
  121. data/test/cases/locking_test.rb +304 -0
  122. data/test/cases/method_scoping_test.rb +704 -0
  123. data/test/cases/migration_test.rb +1523 -0
  124. data/test/cases/migration_test_firebird.rb +124 -0
  125. data/test/cases/mixin_test.rb +96 -0
  126. data/test/cases/modules_test.rb +81 -0
  127. data/test/cases/multiple_db_test.rb +85 -0
  128. data/test/cases/named_scope_test.rb +361 -0
  129. data/test/cases/nested_attributes_test.rb +581 -0
  130. data/test/cases/pk_test.rb +119 -0
  131. data/test/cases/pooled_connections_test.rb +103 -0
  132. data/test/cases/query_cache_test.rb +123 -0
  133. data/test/cases/readonly_test.rb +107 -0
  134. data/test/cases/reflection_test.rb +194 -0
  135. data/test/cases/reload_models_test.rb +22 -0
  136. data/test/cases/repair_helper.rb +50 -0
  137. data/test/cases/reserved_word_test_mysql.rb +176 -0
  138. data/test/cases/sanitize_test.rb +25 -0
  139. data/test/cases/schema_authorization_test_postgresql.rb +75 -0
  140. data/test/cases/schema_dumper_test.rb +211 -0
  141. data/test/cases/schema_test_postgresql.rb +178 -0
  142. data/test/cases/serialization_test.rb +47 -0
  143. data/test/cases/synonym_test_oracle.rb +17 -0
  144. data/test/cases/timestamp_test.rb +75 -0
  145. data/test/cases/transactions_test.rb +522 -0
  146. data/test/cases/unconnected_test.rb +32 -0
  147. data/test/cases/validations_i18n_test.rb +955 -0
  148. data/test/cases/validations_test.rb +1640 -0
  149. data/test/cases/xml_serialization_test.rb +240 -0
  150. data/test/config.rb +5 -0
  151. data/test/connections/jdbc_jdbcderby/connection.rb +18 -0
  152. data/test/connections/jdbc_jdbch2/connection.rb +18 -0
  153. data/test/connections/jdbc_jdbchsqldb/connection.rb +18 -0
  154. data/test/connections/jdbc_jdbcmysql/connection.rb +26 -0
  155. data/test/connections/jdbc_jdbcpostgresql/connection.rb +26 -0
  156. data/test/connections/jdbc_jdbcsqlite3/connection.rb +25 -0
  157. data/test/connections/native_db2/connection.rb +25 -0
  158. data/test/connections/native_firebird/connection.rb +26 -0
  159. data/test/connections/native_frontbase/connection.rb +27 -0
  160. data/test/connections/native_mysql/connection.rb +25 -0
  161. data/test/connections/native_openbase/connection.rb +21 -0
  162. data/test/connections/native_oracle/connection.rb +27 -0
  163. data/test/connections/native_postgresql/connection.rb +25 -0
  164. data/test/connections/native_sqlite/connection.rb +25 -0
  165. data/test/connections/native_sqlite3/connection.rb +25 -0
  166. data/test/connections/native_sqlite3/in_memory_connection.rb +18 -0
  167. data/test/connections/native_sybase/connection.rb +23 -0
  168. data/test/fixtures/accounts.yml +29 -0
  169. data/test/fixtures/all/developers.yml +0 -0
  170. data/test/fixtures/all/people.csv +0 -0
  171. data/test/fixtures/all/tasks.yml +0 -0
  172. data/test/fixtures/author_addresses.yml +5 -0
  173. data/test/fixtures/author_favorites.yml +4 -0
  174. data/test/fixtures/authors.yml +9 -0
  175. data/test/fixtures/binaries.yml +132 -0
  176. data/test/fixtures/books.yml +7 -0
  177. data/test/fixtures/categories/special_categories.yml +9 -0
  178. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
  179. data/test/fixtures/categories.yml +14 -0
  180. data/test/fixtures/categories_ordered.yml +7 -0
  181. data/test/fixtures/categories_posts.yml +23 -0
  182. data/test/fixtures/categorizations.yml +17 -0
  183. data/test/fixtures/clubs.yml +6 -0
  184. data/test/fixtures/comments.yml +59 -0
  185. data/test/fixtures/companies.yml +56 -0
  186. data/test/fixtures/computers.yml +4 -0
  187. data/test/fixtures/courses.yml +7 -0
  188. data/test/fixtures/customers.yml +26 -0
  189. data/test/fixtures/developers.yml +21 -0
  190. data/test/fixtures/developers_projects.yml +17 -0
  191. data/test/fixtures/edges.yml +6 -0
  192. data/test/fixtures/entrants.yml +14 -0
  193. data/test/fixtures/fixture_database.sqlite3 +0 -0
  194. data/test/fixtures/fixture_database_2.sqlite3 +0 -0
  195. data/test/fixtures/fk_test_has_fk.yml +3 -0
  196. data/test/fixtures/fk_test_has_pk.yml +2 -0
  197. data/test/fixtures/funny_jokes.yml +10 -0
  198. data/test/fixtures/items.yml +4 -0
  199. data/test/fixtures/jobs.yml +7 -0
  200. data/test/fixtures/legacy_things.yml +3 -0
  201. data/test/fixtures/mateys.yml +4 -0
  202. data/test/fixtures/member_types.yml +6 -0
  203. data/test/fixtures/members.yml +6 -0
  204. data/test/fixtures/memberships.yml +20 -0
  205. data/test/fixtures/minimalistics.yml +2 -0
  206. data/test/fixtures/mixed_case_monkeys.yml +6 -0
  207. data/test/fixtures/mixins.yml +29 -0
  208. data/test/fixtures/movies.yml +7 -0
  209. data/test/fixtures/naked/csv/accounts.csv +1 -0
  210. data/test/fixtures/naked/yml/accounts.yml +1 -0
  211. data/test/fixtures/naked/yml/companies.yml +1 -0
  212. data/test/fixtures/naked/yml/courses.yml +1 -0
  213. data/test/fixtures/organizations.yml +5 -0
  214. data/test/fixtures/owners.yml +7 -0
  215. data/test/fixtures/parrots.yml +27 -0
  216. data/test/fixtures/parrots_pirates.yml +7 -0
  217. data/test/fixtures/people.yml +15 -0
  218. data/test/fixtures/pets.yml +14 -0
  219. data/test/fixtures/pirates.yml +9 -0
  220. data/test/fixtures/posts.yml +52 -0
  221. data/test/fixtures/price_estimates.yml +7 -0
  222. data/test/fixtures/projects.yml +7 -0
  223. data/test/fixtures/readers.yml +9 -0
  224. data/test/fixtures/references.yml +17 -0
  225. data/test/fixtures/reserved_words/distinct.yml +5 -0
  226. data/test/fixtures/reserved_words/distincts_selects.yml +11 -0
  227. data/test/fixtures/reserved_words/group.yml +14 -0
  228. data/test/fixtures/reserved_words/select.yml +8 -0
  229. data/test/fixtures/reserved_words/values.yml +7 -0
  230. data/test/fixtures/ships.yml +5 -0
  231. data/test/fixtures/sponsors.yml +9 -0
  232. data/test/fixtures/subscribers.yml +7 -0
  233. data/test/fixtures/subscriptions.yml +12 -0
  234. data/test/fixtures/taggings.yml +28 -0
  235. data/test/fixtures/tags.yml +7 -0
  236. data/test/fixtures/tasks.yml +7 -0
  237. data/test/fixtures/topics.yml +42 -0
  238. data/test/fixtures/toys.yml +4 -0
  239. data/test/fixtures/treasures.yml +10 -0
  240. data/test/fixtures/vertices.yml +4 -0
  241. data/test/fixtures/warehouse-things.yml +3 -0
  242. data/test/migrations/broken/100_migration_that_raises_exception.rb +10 -0
  243. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -0
  244. data/test/migrations/duplicate/1_people_have_last_names.rb +9 -0
  245. data/test/migrations/duplicate/2_we_need_reminders.rb +12 -0
  246. data/test/migrations/duplicate/3_foo.rb +7 -0
  247. data/test/migrations/duplicate/3_innocent_jointable.rb +12 -0
  248. data/test/migrations/duplicate_names/20080507052938_chunky.rb +7 -0
  249. data/test/migrations/duplicate_names/20080507053028_chunky.rb +7 -0
  250. data/test/migrations/interleaved/pass_1/3_innocent_jointable.rb +12 -0
  251. data/test/migrations/interleaved/pass_2/1_people_have_last_names.rb +9 -0
  252. data/test/migrations/interleaved/pass_2/3_innocent_jointable.rb +12 -0
  253. data/test/migrations/interleaved/pass_3/1_people_have_last_names.rb +9 -0
  254. data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +8 -0
  255. data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +12 -0
  256. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -0
  257. data/test/migrations/missing/1_people_have_last_names.rb +9 -0
  258. data/test/migrations/missing/3_we_need_reminders.rb +12 -0
  259. data/test/migrations/missing/4_innocent_jointable.rb +12 -0
  260. data/test/migrations/valid/1_people_have_last_names.rb +9 -0
  261. data/test/migrations/valid/2_we_need_reminders.rb +12 -0
  262. data/test/migrations/valid/3_innocent_jointable.rb +12 -0
  263. data/test/models/author.rb +146 -0
  264. data/test/models/auto_id.rb +4 -0
  265. data/test/models/binary.rb +2 -0
  266. data/test/models/bird.rb +3 -0
  267. data/test/models/book.rb +4 -0
  268. data/test/models/categorization.rb +5 -0
  269. data/test/models/category.rb +34 -0
  270. data/test/models/citation.rb +6 -0
  271. data/test/models/club.rb +13 -0
  272. data/test/models/column_name.rb +3 -0
  273. data/test/models/comment.rb +29 -0
  274. data/test/models/company.rb +171 -0
  275. data/test/models/company_in_module.rb +61 -0
  276. data/test/models/computer.rb +3 -0
  277. data/test/models/contact.rb +16 -0
  278. data/test/models/contract.rb +5 -0
  279. data/test/models/course.rb +3 -0
  280. data/test/models/customer.rb +73 -0
  281. data/test/models/default.rb +2 -0
  282. data/test/models/developer.rb +101 -0
  283. data/test/models/edge.rb +5 -0
  284. data/test/models/entrant.rb +3 -0
  285. data/test/models/essay.rb +3 -0
  286. data/test/models/event.rb +3 -0
  287. data/test/models/guid.rb +2 -0
  288. data/test/models/item.rb +7 -0
  289. data/test/models/job.rb +5 -0
  290. data/test/models/joke.rb +3 -0
  291. data/test/models/keyboard.rb +3 -0
  292. data/test/models/legacy_thing.rb +3 -0
  293. data/test/models/matey.rb +4 -0
  294. data/test/models/member.rb +12 -0
  295. data/test/models/member_detail.rb +5 -0
  296. data/test/models/member_type.rb +3 -0
  297. data/test/models/membership.rb +9 -0
  298. data/test/models/minimalistic.rb +2 -0
  299. data/test/models/mixed_case_monkey.rb +3 -0
  300. data/test/models/movie.rb +5 -0
  301. data/test/models/order.rb +4 -0
  302. data/test/models/organization.rb +6 -0
  303. data/test/models/owner.rb +5 -0
  304. data/test/models/parrot.rb +16 -0
  305. data/test/models/person.rb +16 -0
  306. data/test/models/pet.rb +5 -0
  307. data/test/models/pirate.rb +70 -0
  308. data/test/models/post.rb +100 -0
  309. data/test/models/price_estimate.rb +3 -0
  310. data/test/models/project.rb +30 -0
  311. data/test/models/reader.rb +4 -0
  312. data/test/models/reference.rb +4 -0
  313. data/test/models/reply.rb +46 -0
  314. data/test/models/ship.rb +10 -0
  315. data/test/models/ship_part.rb +5 -0
  316. data/test/models/sponsor.rb +4 -0
  317. data/test/models/subject.rb +4 -0
  318. data/test/models/subscriber.rb +8 -0
  319. data/test/models/subscription.rb +4 -0
  320. data/test/models/tag.rb +7 -0
  321. data/test/models/tagging.rb +10 -0
  322. data/test/models/task.rb +3 -0
  323. data/test/models/topic.rb +80 -0
  324. data/test/models/toy.rb +6 -0
  325. data/test/models/treasure.rb +8 -0
  326. data/test/models/vertex.rb +9 -0
  327. data/test/models/warehouse_thing.rb +5 -0
  328. data/test/schema/mysql_specific_schema.rb +24 -0
  329. data/test/schema/postgresql_specific_schema.rb +114 -0
  330. data/test/schema/schema.rb +493 -0
  331. data/test/schema/schema2.rb +6 -0
  332. data/test/schema/sqlite_specific_schema.rb +25 -0
  333. metadata +420 -0
@@ -0,0 +1,722 @@
1
+ require 'date'
2
+ require 'set'
3
+ require 'bigdecimal'
4
+ require 'bigdecimal/util'
5
+
6
+ module ActiveRecord
7
+ module ConnectionAdapters #:nodoc:
8
+ # An abstract definition of a column in a table.
9
+ class Column
10
+ TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].to_set
11
+ FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set
12
+
13
+ module Format
14
+ ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
15
+ ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/
16
+ end
17
+
18
+ attr_reader :name, :default, :type, :limit, :null, :sql_type, :precision, :scale
19
+ attr_accessor :primary
20
+
21
+ # Instantiates a new column in the table.
22
+ #
23
+ # +name+ is the column's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
24
+ # +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
25
+ # +sql_type+ is only used to extract the column's length, if necessary. For example +60+ in <tt>company_name varchar(60)</tt>.
26
+ # +null+ determines if this column allows +NULL+ values.
27
+ def initialize(name, default, sql_type = nil, null = true)
28
+ @name, @sql_type, @null = name, sql_type, null
29
+ @limit, @precision, @scale = extract_limit(sql_type), extract_precision(sql_type), extract_scale(sql_type)
30
+ @type = simplified_type(sql_type)
31
+ @default = extract_default(default)
32
+
33
+ @primary = nil
34
+ end
35
+
36
+ # Returns +true+ if the column is either of type string or text.
37
+ def text?
38
+ type == :string || type == :text
39
+ end
40
+
41
+ # Returns +true+ if the column is either of type integer, float or decimal.
42
+ def number?
43
+ type == :integer || type == :float || type == :decimal
44
+ end
45
+
46
+ def has_default?
47
+ !default.nil?
48
+ end
49
+
50
+ # Returns the Ruby class that corresponds to the abstract data type.
51
+ def klass
52
+ case type
53
+ when :integer then Fixnum
54
+ when :float then Float
55
+ when :decimal then BigDecimal
56
+ when :datetime then Time
57
+ when :date then Date
58
+ when :timestamp then Time
59
+ when :time then Time
60
+ when :text, :string then String
61
+ when :binary then String
62
+ when :boolean then Object
63
+ end
64
+ end
65
+
66
+ # Casts value (which is a String) to an appropriate instance.
67
+ def type_cast(value)
68
+ return nil if value.nil?
69
+ case type
70
+ when :string then value
71
+ when :text then value
72
+ when :integer then value.to_i rescue value ? 1 : 0
73
+ when :float then value.to_f
74
+ when :decimal then self.class.value_to_decimal(value)
75
+ when :datetime then self.class.string_to_time(value)
76
+ when :timestamp then self.class.string_to_time(value)
77
+ when :time then self.class.string_to_dummy_time(value)
78
+ when :date then self.class.string_to_date(value)
79
+ when :binary then self.class.binary_to_string(value)
80
+ when :boolean then self.class.value_to_boolean(value)
81
+ else value
82
+ end
83
+ end
84
+
85
+ def type_cast_code(var_name)
86
+ case type
87
+ when :string then nil
88
+ when :text then nil
89
+ when :integer then "(#{var_name}.to_i rescue #{var_name} ? 1 : 0)"
90
+ when :float then "#{var_name}.to_f"
91
+ when :decimal then "#{self.class.name}.value_to_decimal(#{var_name})"
92
+ when :datetime then "#{self.class.name}.string_to_time(#{var_name})"
93
+ when :timestamp then "#{self.class.name}.string_to_time(#{var_name})"
94
+ when :time then "#{self.class.name}.string_to_dummy_time(#{var_name})"
95
+ when :date then "#{self.class.name}.string_to_date(#{var_name})"
96
+ when :binary then "#{self.class.name}.binary_to_string(#{var_name})"
97
+ when :boolean then "#{self.class.name}.value_to_boolean(#{var_name})"
98
+ else nil
99
+ end
100
+ end
101
+
102
+ # Returns the human name of the column name.
103
+ #
104
+ # ===== Examples
105
+ # Column.new('sales_stage', ...).human_name # => 'Sales stage'
106
+ def human_name
107
+ Base.human_attribute_name(@name)
108
+ end
109
+
110
+ def extract_default(default)
111
+ type_cast(default)
112
+ end
113
+
114
+ class << self
115
+ # Used to convert from Strings to BLOBs
116
+ def string_to_binary(value)
117
+ value
118
+ end
119
+
120
+ # Used to convert from BLOBs to Strings
121
+ def binary_to_string(value)
122
+ value
123
+ end
124
+
125
+ def string_to_date(string)
126
+ return string unless string.is_a?(String)
127
+ return nil if string.empty?
128
+
129
+ fast_string_to_date(string) || fallback_string_to_date(string)
130
+ end
131
+
132
+ def string_to_time(string)
133
+ return string unless string.is_a?(String)
134
+ return nil if string.empty?
135
+
136
+ fast_string_to_time(string) || fallback_string_to_time(string)
137
+ end
138
+
139
+ def string_to_dummy_time(string)
140
+ return string unless string.is_a?(String)
141
+ return nil if string.empty?
142
+
143
+ string_to_time "2000-01-01 #{string}"
144
+ end
145
+
146
+ # convert something to a boolean
147
+ def value_to_boolean(value)
148
+ if value.is_a?(String) && value.blank?
149
+ nil
150
+ else
151
+ TRUE_VALUES.include?(value)
152
+ end
153
+ end
154
+
155
+ # convert something to a BigDecimal
156
+ def value_to_decimal(value)
157
+ # Using .class is faster than .is_a? and
158
+ # subclasses of BigDecimal will be handled
159
+ # in the else clause
160
+ if value.class == BigDecimal
161
+ value
162
+ elsif value.respond_to?(:to_d)
163
+ value.to_d
164
+ else
165
+ value.to_s.to_d
166
+ end
167
+ end
168
+
169
+ protected
170
+ # '0.123456' -> 123456
171
+ # '1.123456' -> 123456
172
+ def microseconds(time)
173
+ ((time[:sec_fraction].to_f % 1) * 1_000_000).to_i
174
+ end
175
+
176
+ def new_date(year, mon, mday)
177
+ if year && year != 0
178
+ Date.new(year, mon, mday) rescue nil
179
+ end
180
+ end
181
+
182
+ def new_time(year, mon, mday, hour, min, sec, microsec)
183
+ # Treat 0000-00-00 00:00:00 as nil.
184
+ return nil if year.nil? || year == 0
185
+
186
+ Time.time_with_datetime_fallback(Base.default_timezone, year, mon, mday, hour, min, sec, microsec) rescue nil
187
+ end
188
+
189
+ def fast_string_to_date(string)
190
+ if string =~ Format::ISO_DATE
191
+ new_date $1.to_i, $2.to_i, $3.to_i
192
+ end
193
+ end
194
+
195
+ # Doesn't handle time zones.
196
+ def fast_string_to_time(string)
197
+ if string =~ Format::ISO_DATETIME
198
+ microsec = ($7.to_f * 1_000_000).to_i
199
+ new_time $1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, microsec
200
+ end
201
+ end
202
+
203
+ def fallback_string_to_date(string)
204
+ new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
205
+ end
206
+
207
+ def fallback_string_to_time(string)
208
+ time_hash = Date._parse(string)
209
+ time_hash[:sec_fraction] = microseconds(time_hash)
210
+
211
+ new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction))
212
+ end
213
+ end
214
+
215
+ private
216
+ def extract_limit(sql_type)
217
+ $1.to_i if sql_type =~ /\((.*)\)/
218
+ end
219
+
220
+ def extract_precision(sql_type)
221
+ $2.to_i if sql_type =~ /^(numeric|decimal|number)\((\d+)(,\d+)?\)/i
222
+ end
223
+
224
+ def extract_scale(sql_type)
225
+ case sql_type
226
+ when /^(numeric|decimal|number)\((\d+)\)/i then 0
227
+ when /^(numeric|decimal|number)\((\d+)(,(\d+))\)/i then $4.to_i
228
+ end
229
+ end
230
+
231
+ def simplified_type(field_type)
232
+ case field_type
233
+ when /int/i
234
+ :integer
235
+ when /float|double/i
236
+ :float
237
+ when /decimal|numeric|number/i
238
+ extract_scale(field_type) == 0 ? :integer : :decimal
239
+ when /datetime/i
240
+ :datetime
241
+ when /timestamp/i
242
+ :timestamp
243
+ when /time/i
244
+ :time
245
+ when /date/i
246
+ :date
247
+ when /clob/i, /text/i
248
+ :text
249
+ when /blob/i, /binary/i
250
+ :binary
251
+ when /char/i, /string/i
252
+ :string
253
+ when /boolean/i
254
+ :boolean
255
+ end
256
+ end
257
+ end
258
+
259
+ class IndexDefinition < Struct.new(:table, :name, :unique, :columns) #:nodoc:
260
+ end
261
+
262
+ # Abstract representation of a column definition. Instances of this type
263
+ # are typically created by methods in TableDefinition, and added to the
264
+ # +columns+ attribute of said TableDefinition object, in order to be used
265
+ # for generating a number of table creation or table changing SQL statements.
266
+ class ColumnDefinition < Struct.new(:base, :name, :type, :limit, :precision, :scale, :default, :null) #:nodoc:
267
+
268
+ def sql_type
269
+ base.type_to_sql(type.to_sym, limit, precision, scale) rescue type
270
+ end
271
+
272
+ def to_sql
273
+ column_sql = "#{base.quote_column_name(name)} #{sql_type}"
274
+ column_options = {}
275
+ column_options[:null] = null unless null.nil?
276
+ column_options[:default] = default unless default.nil?
277
+ add_column_options!(column_sql, column_options) unless type.to_sym == :primary_key
278
+ column_sql
279
+ end
280
+
281
+ private
282
+
283
+ def add_column_options!(sql, options)
284
+ base.add_column_options!(sql, options.merge(:column => self))
285
+ end
286
+ end
287
+
288
+ # Represents the schema of an SQL table in an abstract way. This class
289
+ # provides methods for manipulating the schema representation.
290
+ #
291
+ # Inside migration files, the +t+ object in +create_table+ and
292
+ # +change_table+ is actually of this type:
293
+ #
294
+ # class SomeMigration < ActiveRecord::Migration
295
+ # def self.up
296
+ # create_table :foo do |t|
297
+ # puts t.class # => "ActiveRecord::ConnectionAdapters::TableDefinition"
298
+ # end
299
+ # end
300
+ #
301
+ # def self.down
302
+ # ...
303
+ # end
304
+ # end
305
+ #
306
+ # The table definitions
307
+ # The Columns are stored as a ColumnDefinition in the +columns+ attribute.
308
+ class TableDefinition
309
+ # An array of ColumnDefinition objects, representing the column changes
310
+ # that have been defined.
311
+ attr_accessor :columns
312
+
313
+ def initialize(base)
314
+ @columns = []
315
+ @base = base
316
+ end
317
+
318
+ #Handles non supported datatypes - e.g. XML
319
+ def method_missing(symbol, *args)
320
+ if symbol.to_s == 'xml'
321
+ xml_column_fallback(args)
322
+ end
323
+ end
324
+
325
+ def xml_column_fallback(*args)
326
+ case @base.adapter_name.downcase
327
+ when 'sqlite', 'mysql'
328
+ options = args.extract_options!
329
+ column(args[0], :text, options)
330
+ end
331
+ end
332
+ # Appends a primary key definition to the table definition.
333
+ # Can be called multiple times, but this is probably not a good idea.
334
+ def primary_key(name)
335
+ column(name, :primary_key)
336
+ end
337
+
338
+ # Returns a ColumnDefinition for the column with name +name+.
339
+ def [](name)
340
+ @columns.find {|column| column.name.to_s == name.to_s}
341
+ end
342
+
343
+ # Instantiates a new column for the table.
344
+ # The +type+ parameter is normally one of the migrations native types,
345
+ # which is one of the following:
346
+ # <tt>:primary_key</tt>, <tt>:string</tt>, <tt>:text</tt>,
347
+ # <tt>:integer</tt>, <tt>:float</tt>, <tt>:decimal</tt>,
348
+ # <tt>:datetime</tt>, <tt>:timestamp</tt>, <tt>:time</tt>,
349
+ # <tt>:date</tt>, <tt>:binary</tt>, <tt>:boolean</tt>.
350
+ #
351
+ # You may use a type not in this list as long as it is supported by your
352
+ # database (for example, "polygon" in MySQL), but this will not be database
353
+ # agnostic and should usually be avoided.
354
+ #
355
+ # Available options are (none of these exists by default):
356
+ # * <tt>:limit</tt> -
357
+ # Requests a maximum column length. This is number of characters for <tt>:string</tt> and <tt>:text</tt> columns and number of bytes for :binary and :integer columns.
358
+ # * <tt>:default</tt> -
359
+ # The column's default value. Use nil for NULL.
360
+ # * <tt>:null</tt> -
361
+ # Allows or disallows +NULL+ values in the column. This option could
362
+ # have been named <tt>:null_allowed</tt>.
363
+ # * <tt>:precision</tt> -
364
+ # Specifies the precision for a <tt>:decimal</tt> column.
365
+ # * <tt>:scale</tt> -
366
+ # Specifies the scale for a <tt>:decimal</tt> column.
367
+ #
368
+ # For clarity's sake: the precision is the number of significant digits,
369
+ # while the scale is the number of digits that can be stored following
370
+ # the decimal point. For example, the number 123.45 has a precision of 5
371
+ # and a scale of 2. A decimal with a precision of 5 and a scale of 2 can
372
+ # range from -999.99 to 999.99.
373
+ #
374
+ # Please be aware of different RDBMS implementations behavior with
375
+ # <tt>:decimal</tt> columns:
376
+ # * The SQL standard says the default scale should be 0, <tt>:scale</tt> <=
377
+ # <tt>:precision</tt>, and makes no comments about the requirements of
378
+ # <tt>:precision</tt>.
379
+ # * MySQL: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..30].
380
+ # Default is (10,0).
381
+ # * PostgreSQL: <tt>:precision</tt> [1..infinity],
382
+ # <tt>:scale</tt> [0..infinity]. No default.
383
+ # * SQLite2: Any <tt>:precision</tt> and <tt>:scale</tt> may be used.
384
+ # Internal storage as strings. No default.
385
+ # * SQLite3: No restrictions on <tt>:precision</tt> and <tt>:scale</tt>,
386
+ # but the maximum supported <tt>:precision</tt> is 16. No default.
387
+ # * Oracle: <tt>:precision</tt> [1..38], <tt>:scale</tt> [-84..127].
388
+ # Default is (38,0).
389
+ # * DB2: <tt>:precision</tt> [1..63], <tt>:scale</tt> [0..62].
390
+ # Default unknown.
391
+ # * Firebird: <tt>:precision</tt> [1..18], <tt>:scale</tt> [0..18].
392
+ # Default (9,0). Internal types NUMERIC and DECIMAL have different
393
+ # storage rules, decimal being better.
394
+ # * FrontBase?: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
395
+ # Default (38,0). WARNING Max <tt>:precision</tt>/<tt>:scale</tt> for
396
+ # NUMERIC is 19, and DECIMAL is 38.
397
+ # * SqlServer?: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
398
+ # Default (38,0).
399
+ # * Sybase: <tt>:precision</tt> [1..38], <tt>:scale</tt> [0..38].
400
+ # Default (38,0).
401
+ # * OpenBase?: Documentation unclear. Claims storage in <tt>double</tt>.
402
+ #
403
+ # This method returns <tt>self</tt>.
404
+ #
405
+ # == Examples
406
+ # # Assuming td is an instance of TableDefinition
407
+ # td.column(:granted, :boolean)
408
+ # # granted BOOLEAN
409
+ #
410
+ # td.column(:picture, :binary, :limit => 2.megabytes)
411
+ # # => picture BLOB(2097152)
412
+ #
413
+ # td.column(:sales_stage, :string, :limit => 20, :default => 'new', :null => false)
414
+ # # => sales_stage VARCHAR(20) DEFAULT 'new' NOT NULL
415
+ #
416
+ # td.column(:bill_gates_money, :decimal, :precision => 15, :scale => 2)
417
+ # # => bill_gates_money DECIMAL(15,2)
418
+ #
419
+ # td.column(:sensor_reading, :decimal, :precision => 30, :scale => 20)
420
+ # # => sensor_reading DECIMAL(30,20)
421
+ #
422
+ # # While <tt>:scale</tt> defaults to zero on most databases, it
423
+ # # probably wouldn't hurt to include it.
424
+ # td.column(:huge_integer, :decimal, :precision => 30)
425
+ # # => huge_integer DECIMAL(30)
426
+ #
427
+ # # Defines a column with a database-specific type.
428
+ # td.column(:foo, 'polygon')
429
+ # # => foo polygon
430
+ #
431
+ # == Short-hand examples
432
+ #
433
+ # Instead of calling +column+ directly, you can also work with the short-hand definitions for the default types.
434
+ # They use the type as the method name instead of as a parameter and allow for multiple columns to be defined
435
+ # in a single statement.
436
+ #
437
+ # What can be written like this with the regular calls to column:
438
+ #
439
+ # create_table "products", :force => true do |t|
440
+ # t.column "shop_id", :integer
441
+ # t.column "creator_id", :integer
442
+ # t.column "name", :string, :default => "Untitled"
443
+ # t.column "value", :string, :default => "Untitled"
444
+ # t.column "created_at", :datetime
445
+ # t.column "updated_at", :datetime
446
+ # end
447
+ #
448
+ # Can also be written as follows using the short-hand:
449
+ #
450
+ # create_table :products do |t|
451
+ # t.integer :shop_id, :creator_id
452
+ # t.string :name, :value, :default => "Untitled"
453
+ # t.timestamps
454
+ # end
455
+ #
456
+ # There's a short-hand method for each of the type values declared at the top. And then there's
457
+ # TableDefinition#timestamps that'll add created_at and +updated_at+ as datetimes.
458
+ #
459
+ # TableDefinition#references will add an appropriately-named _id column, plus a corresponding _type
460
+ # column if the <tt>:polymorphic</tt> option is supplied. If <tt>:polymorphic</tt> is a hash of options, these will be
461
+ # used when creating the <tt>_type</tt> column. So what can be written like this:
462
+ #
463
+ # create_table :taggings do |t|
464
+ # t.integer :tag_id, :tagger_id, :taggable_id
465
+ # t.string :tagger_type
466
+ # t.string :taggable_type, :default => 'Photo'
467
+ # end
468
+ #
469
+ # Can also be written as follows using references:
470
+ #
471
+ # create_table :taggings do |t|
472
+ # t.references :tag
473
+ # t.references :tagger, :polymorphic => true
474
+ # t.references :taggable, :polymorphic => { :default => 'Photo' }
475
+ # end
476
+ def column(name, type, options = {})
477
+ column = self[name] || ColumnDefinition.new(@base, name, type)
478
+ if options[:limit]
479
+ column.limit = options[:limit]
480
+ elsif native[type.to_sym].is_a?(Hash)
481
+ column.limit = native[type.to_sym][:limit]
482
+ end
483
+ column.precision = options[:precision]
484
+ column.scale = options[:scale]
485
+ column.default = options[:default]
486
+ column.null = options[:null]
487
+ @columns << column unless @columns.include? column
488
+ self
489
+ end
490
+
491
+ %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type|
492
+ class_eval <<-EOV
493
+ def #{column_type}(*args) # def string(*args)
494
+ options = args.extract_options! # options = args.extract_options!
495
+ column_names = args # column_names = args
496
+ #
497
+ column_names.each { |name| column(name, '#{column_type}', options) } # column_names.each { |name| column(name, 'string', options) }
498
+ end # end
499
+ EOV
500
+ end
501
+
502
+ # Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
503
+ # <tt>:updated_at</tt> to the table.
504
+ def timestamps(*args)
505
+ options = args.extract_options!
506
+ column(:created_at, :datetime, options)
507
+ column(:updated_at, :datetime, options)
508
+ end
509
+
510
+ def references(*args)
511
+ options = args.extract_options!
512
+ polymorphic = options.delete(:polymorphic)
513
+ args.each do |col|
514
+ column("#{col}_id", :integer, options)
515
+ column("#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) unless polymorphic.nil?
516
+ end
517
+ end
518
+ alias :belongs_to :references
519
+
520
+ # Returns a String whose contents are the column definitions
521
+ # concatenated together. This string can then be prepended and appended to
522
+ # to generate the final SQL to create the table.
523
+ def to_sql
524
+ @columns.map(&:to_sql) * ', '
525
+ end
526
+
527
+ private
528
+ def native
529
+ @base.native_database_types
530
+ end
531
+ end
532
+
533
+ # Represents a SQL table in an abstract way for updating a table.
534
+ # Also see TableDefinition and SchemaStatements#create_table
535
+ #
536
+ # Available transformations are:
537
+ #
538
+ # change_table :table do |t|
539
+ # t.column
540
+ # t.index
541
+ # t.timestamps
542
+ # t.change
543
+ # t.change_default
544
+ # t.rename
545
+ # t.references
546
+ # t.belongs_to
547
+ # t.string
548
+ # t.text
549
+ # t.integer
550
+ # t.float
551
+ # t.decimal
552
+ # t.datetime
553
+ # t.timestamp
554
+ # t.time
555
+ # t.date
556
+ # t.binary
557
+ # t.boolean
558
+ # t.remove
559
+ # t.remove_references
560
+ # t.remove_belongs_to
561
+ # t.remove_index
562
+ # t.remove_timestamps
563
+ # end
564
+ #
565
+ class Table
566
+ def initialize(table_name, base)
567
+ @table_name = table_name
568
+ @base = base
569
+ end
570
+
571
+ # Adds a new column to the named table.
572
+ # See TableDefinition#column for details of the options you can use.
573
+ # ===== Example
574
+ # ====== Creating a simple column
575
+ # t.column(:name, :string)
576
+ def column(column_name, type, options = {})
577
+ @base.add_column(@table_name, column_name, type, options)
578
+ end
579
+
580
+ # Adds a new index to the table. +column_name+ can be a single Symbol, or
581
+ # an Array of Symbols. See SchemaStatements#add_index
582
+ #
583
+ # ===== Examples
584
+ # ====== Creating a simple index
585
+ # t.index(:name)
586
+ # ====== Creating a unique index
587
+ # t.index([:branch_id, :party_id], :unique => true)
588
+ # ====== Creating a named index
589
+ # t.index([:branch_id, :party_id], :unique => true, :name => 'by_branch_party')
590
+ def index(column_name, options = {})
591
+ @base.add_index(@table_name, column_name, options)
592
+ end
593
+
594
+ # Adds timestamps (created_at and updated_at) columns to the table. See SchemaStatements#add_timestamps
595
+ # ===== Example
596
+ # t.timestamps
597
+ def timestamps
598
+ @base.add_timestamps(@table_name)
599
+ end
600
+
601
+ # Changes the column's definition according to the new options.
602
+ # See TableDefinition#column for details of the options you can use.
603
+ # ===== Examples
604
+ # t.change(:name, :string, :limit => 80)
605
+ # t.change(:description, :text)
606
+ def change(column_name, type, options = {})
607
+ @base.change_column(@table_name, column_name, type, options)
608
+ end
609
+
610
+ # Sets a new default value for a column. See SchemaStatements#change_column_default
611
+ # ===== Examples
612
+ # t.change_default(:qualification, 'new')
613
+ # t.change_default(:authorized, 1)
614
+ def change_default(column_name, default)
615
+ @base.change_column_default(@table_name, column_name, default)
616
+ end
617
+
618
+ # Removes the column(s) from the table definition.
619
+ # ===== Examples
620
+ # t.remove(:qualification)
621
+ # t.remove(:qualification, :experience)
622
+ def remove(*column_names)
623
+ @base.remove_column(@table_name, column_names)
624
+ end
625
+
626
+ # Removes the given index from the table.
627
+ #
628
+ # ===== Examples
629
+ # ====== Remove the suppliers_name_index in the suppliers table
630
+ # t.remove_index :name
631
+ # ====== Remove the index named accounts_branch_id_index in the accounts table
632
+ # t.remove_index :column => :branch_id
633
+ # ====== Remove the index named accounts_branch_id_party_id_index in the accounts table
634
+ # t.remove_index :column => [:branch_id, :party_id]
635
+ # ====== Remove the index named by_branch_party in the accounts table
636
+ # t.remove_index :name => :by_branch_party
637
+ def remove_index(options = {})
638
+ @base.remove_index(@table_name, options)
639
+ end
640
+
641
+ # Removes the timestamp columns (created_at and updated_at) from the table.
642
+ # ===== Example
643
+ # t.remove_timestamps
644
+ def remove_timestamps
645
+ @base.remove_timestamps(@table_name)
646
+ end
647
+
648
+ # Renames a column.
649
+ # ===== Example
650
+ # t.rename(:description, :name)
651
+ def rename(column_name, new_column_name)
652
+ @base.rename_column(@table_name, column_name, new_column_name)
653
+ end
654
+
655
+ # Adds a reference. Optionally adds a +type+ column.
656
+ # <tt>references</tt> and <tt>belongs_to</tt> are acceptable.
657
+ # ===== Examples
658
+ # t.references(:goat)
659
+ # t.references(:goat, :polymorphic => true)
660
+ # t.belongs_to(:goat)
661
+ def references(*args)
662
+ options = args.extract_options!
663
+ polymorphic = options.delete(:polymorphic)
664
+ args.each do |col|
665
+ @base.add_column(@table_name, "#{col}_id", :integer, options)
666
+ @base.add_column(@table_name, "#{col}_type", :string, polymorphic.is_a?(Hash) ? polymorphic : options) unless polymorphic.nil?
667
+ end
668
+ end
669
+ alias :belongs_to :references
670
+
671
+ # Removes a reference. Optionally removes a +type+ column.
672
+ # <tt>remove_references</tt> and <tt>remove_belongs_to</tt> are acceptable.
673
+ # ===== Examples
674
+ # t.remove_references(:goat)
675
+ # t.remove_references(:goat, :polymorphic => true)
676
+ # t.remove_belongs_to(:goat)
677
+ def remove_references(*args)
678
+ options = args.extract_options!
679
+ polymorphic = options.delete(:polymorphic)
680
+ args.each do |col|
681
+ @base.remove_column(@table_name, "#{col}_id")
682
+ @base.remove_column(@table_name, "#{col}_type") unless polymorphic.nil?
683
+ end
684
+ end
685
+ alias :remove_belongs_to :remove_references
686
+
687
+ # Adds a column or columns of a specified type
688
+ # ===== Examples
689
+ # t.string(:goat)
690
+ # t.string(:goat, :sheep)
691
+ %w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type|
692
+ class_eval <<-EOV
693
+ def #{column_type}(*args) # def string(*args)
694
+ options = args.extract_options! # options = args.extract_options!
695
+ column_names = args # column_names = args
696
+ #
697
+ column_names.each do |name| # column_names.each do |name|
698
+ column = ColumnDefinition.new(@base, name, '#{column_type}') # column = ColumnDefinition.new(@base, name, 'string')
699
+ if options[:limit] # if options[:limit]
700
+ column.limit = options[:limit] # column.limit = options[:limit]
701
+ elsif native['#{column_type}'.to_sym].is_a?(Hash) # elsif native['string'.to_sym].is_a?(Hash)
702
+ column.limit = native['#{column_type}'.to_sym][:limit] # column.limit = native['string'.to_sym][:limit]
703
+ end # end
704
+ column.precision = options[:precision] # column.precision = options[:precision]
705
+ column.scale = options[:scale] # column.scale = options[:scale]
706
+ column.default = options[:default] # column.default = options[:default]
707
+ column.null = options[:null] # column.null = options[:null]
708
+ @base.add_column(@table_name, name, column.sql_type, options) # @base.add_column(@table_name, name, column.sql_type, options)
709
+ end # end
710
+ end # end
711
+ EOV
712
+ end
713
+
714
+ private
715
+ def native
716
+ @base.native_database_types
717
+ end
718
+ end
719
+
720
+ end
721
+ end
722
+