datamapper 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,194 +1,45 @@
1
- require 'data_mapper/adapters/sql_adapter'
2
- require 'data_mapper/support/connection_pool'
3
-
1
+ require 'data_mapper/adapters/data_object_adapter'
4
2
  begin
5
- require 'mysql'
6
- rescue LoadError
7
- STDERR.puts <<-EOS.gsub(/^(\s+)/, '')
8
- This adapter currently depends on the \"mysql\" gem.
9
- If some kind soul would like to make it work with
10
- a pure-ruby version that'd be super spiffy.
11
- EOS
12
-
13
- raise
3
+ require 'do_mysql'
4
+ rescue
5
+ STDERR.puts <<-EOS
6
+ You must install the DataObjects::Mysql driver.
7
+ rake dm:install:mysql
8
+ EOS
9
+ exit
14
10
  end
15
11
 
16
12
  module DataMapper
17
13
  module Adapters
18
14
 
19
- class MysqlAdapter < SqlAdapter
20
-
21
- def initialize(configuration)
22
- super
23
-
24
- create_connection = lambda do
25
- Mysql.new(configuration.host, configuration.username, configuration.password, configuration.database)
26
- end
27
-
28
- # Initialize the connection pool.
29
- if single_threaded?
30
- @connection_factory = create_connection
31
- @active_connection = create_connection[]
32
- else
33
- @connections = Support::ConnectionPool.new(&create_connection)
34
- end
35
- end
36
-
37
- # Yields an available connection. Flushes the connection-pool if
38
- # the connection returns an error.
39
- def connection
40
-
41
- if single_threaded?
42
- begin
43
- # BUG: Single_threaded mode totally breaks shit right now. No real idea why just from
44
- # eyeballing this. Probably should move this into the SqlAdapter anyways and just
45
- # force derived adapters to implement a #create_connection() and #close_connection(conn) methods.
46
- yield(@active_connection)
47
- rescue Mysql::Error => me
48
- @configuration.log.fatal(me)
49
-
50
- begin
51
- @active_connection.close
52
- rescue => se
53
- @configuration.log.error(se)
54
- end
55
-
56
- @active_connection = @connection_factory[]
57
- end
58
- else
59
- begin
60
- @connections.hold { |dbh| yield(dbh) }
61
- rescue Mysql::Error => me
62
-
63
- @configuration.log.fatal(me)
64
-
65
- @connections.available_connections.each do |sock|
66
- begin
67
- sock.close
68
- rescue => se
69
- @configuration.log.error(se)
70
- end
71
- end
72
-
73
- @connections.available_connections.clear
74
- raise me
75
- end
76
- end
77
- end
78
-
79
- def execute(*args)
80
- connection do |db|
81
- reader = db.query(escape_sql(*args))
82
- result = yield(reader, reader.fetch_fields.map { |field| field.name })
83
- reader.free
84
- result
85
- end
86
- end
87
-
88
- def query(*args)
89
-
90
- execute(*args) do |reader, fields|
91
- struct = Support::Struct::define(fields)
92
-
93
- results = []
94
-
95
- reader.each do |row|
96
- results << struct.new(row)
97
- end
98
- results
99
-
100
- end
15
+ class MysqlAdapter < DataObjectAdapter
16
+ def create_connection
17
+
18
+ connection_string = ""
19
+ builder = lambda { |k,v| connection_string << "#{k}=#{@configuration.send(v)} " unless @configuration.send(v).blank? }
20
+
21
+ builder['host', :host]
22
+ builder['user', :username]
23
+ builder['password', :password]
24
+ builder['dbname', :database]
25
+ builder['socket', :socket]
26
+
27
+ conn = DataObject::Mysql::Connection.new(connection_string.strip)
28
+ conn.open
29
+ cmd = conn.create_command("SET NAMES UTF8")
30
+ cmd.execute_non_query
31
+ return conn
101
32
  end
102
33
 
103
- TABLE_QUOTING_CHARACTER = '`'.freeze
104
- COLUMN_QUOTING_CHARACTER = '`'.freeze
105
-
106
- TRUE_ALIASES.unshift('1'.freeze)
107
- FALSE_ALIASES.unshift('0'.freeze)
108
-
109
- module Commands
110
-
111
- class TableExistsCommand
112
- def call
113
- sql = to_sql
114
- @adapter.log.debug(sql)
115
- reader = @adapter.connection { |db| db.query(sql) }
116
- result = reader.num_rows > 0
117
- reader.free
118
- result
119
- end
120
- end
121
-
122
- class DeleteCommand
123
-
124
- def execute(sql)
125
- @adapter.connection do |db|
126
- @adapter.log.debug(sql)
127
- db.query(sql)
128
- db.affected_rows > 0
129
- end
130
- end
131
-
132
- def execute_drop(sql)
133
- @adapter.log.debug(sql)
134
- @adapter.connection { |db| db.query(sql) }
135
- true
136
- end
137
-
138
- end
139
-
140
- class SaveCommand
141
-
142
- def execute_insert(sql)
143
- @adapter.connection do |db|
144
- @adapter.log.debug(sql)
145
- db.query(sql)
146
- db.insert_id
147
- end
148
- end
149
-
150
- def execute_update(sql)
151
- @adapter.connection do |db|
152
- @adapter.log.debug(sql)
153
- db.query(sql)
154
- db.affected_rows > 0
155
- end
156
- end
157
-
158
- def execute_create_table(sql)
159
- @adapter.log.debug(sql)
160
- @adapter.connection { |db| db.query(sql) }
161
- true
162
- end
163
-
164
- end
34
+ module Mappings
165
35
 
166
- class LoadCommand
167
- def eof?(reader)
168
- reader.num_rows == 0
169
- end
170
-
171
- def close_reader(reader)
172
- reader.free
36
+ def to_create_table_sql
37
+ @to_create_table_sql || @to_create_table_sql = begin
38
+ "CREATE TABLE #{to_sql} (#{columns.map { |c| c.to_long_form }.join(', ')}) Type=MyISAM CHARACTER SET utf8"
173
39
  end
174
-
175
- def execute(sql)
176
- @adapter.log.debug(sql)
177
- @adapter.connection { |db| db.query(to_sql) }
178
- end
179
-
180
- def fetch_one(reader)
181
- fetch_all(reader).first
182
- end
183
-
184
- def fetch_all(reader)
185
- load_instances(reader.fetch_fields.map { |field| field.name }, reader)
186
- end
187
-
188
40
  end
189
41
 
190
- end
191
-
42
+ end # module Mappings
192
43
  end # class MysqlAdapter
193
44
 
194
45
  end # module Adapters
@@ -1,242 +1,133 @@
1
- require 'data_mapper/adapters/sql_adapter'
2
- require 'data_mapper/support/connection_pool'
3
-
1
+ require 'data_mapper/adapters/data_object_adapter'
4
2
  begin
5
- require 'postgres'
6
- rescue LoadError
7
- STDERR.puts <<-EOS.gsub(/^(\s+)/, '')
8
- This adapter currently depends on the \"postgres\" gem.
9
- If some kind soul would like to make it work with
10
- a pure-ruby version that'd be super spiffy.
11
- EOS
12
-
13
- raise
3
+ require 'do_postgres'
4
+ rescue
5
+ STDERR.puts <<-EOS
6
+ You must install the DataObjects::PostgreSQL driver.
7
+ rake dm:install:postgresql
8
+ EOS
9
+ exit
14
10
  end
15
11
 
16
12
  module DataMapper
17
13
  module Adapters
18
14
 
19
- class PostgresqlAdapter < SqlAdapter
15
+ class PostgresqlAdapter < DataObjectAdapter
20
16
 
21
- def initialize(configuration)
22
- super
23
- # Initialize the connection pool.
24
- @connections = Support::ConnectionPool.new do
25
- # add port parameter to configuration
26
- pg_conn = PGconn.connect(configuration.host, 5432, "", "", configuration.database, configuration.username, configuration.password)
27
- end
28
- end
29
-
30
-
31
- # Returns an available connection. Flushes the connection-pool if
32
- # the connection returns an error.
33
- def connection
34
- raise ArgumentError.new('PostgresqlAdapter#connection requires a block-parameter') unless block_given?
35
- begin
36
- @connections.hold { |connection| yield connection }
37
- rescue PGError => me
38
-
39
- @configuration.log.fatal(me)
40
-
41
- @connections.available_connections.each do |sock|
42
- begin
43
- sock.close
44
- rescue => se
45
- @configuration.log.error(se)
46
- end
17
+ def schema_search_path
18
+ @schema_search_path || @schema_search_path = begin
19
+ if @configuration.schema_search_path
20
+ @configuration.schema_search_path.split(',').map do |part|
21
+ part.blank? ? nil : part.strip.ensure_wrapped_with("'")
22
+ end.compact
23
+ else
24
+ []
47
25
  end
48
-
49
- @connections.available_connections.clear
50
- raise me
51
26
  end
52
27
  end
53
28
 
54
- def query(*args)
55
- pg_result = connection { |db| db.exec(escape_sql(*args)) }
56
-
57
- struct = Struct.new(*pg_result.fields.map { |field| Inflector.underscore(field).to_sym })
58
- results = []
59
-
60
- pg_result.each do |row|
61
- results << struct.new(*row)
29
+ def create_connection
30
+ conn = DataObject::Postgres::Connection.new("dbname=#{@configuration.database}")
31
+ conn.open
32
+ return conn
33
+
34
+ unless schema_search_path.empty?
35
+ execute("SET search_path TO #{schema_search_path}")
62
36
  end
63
37
 
64
- pg_result.clear
65
- return results
38
+ return connection
66
39
  end
67
-
40
+
68
41
  TABLE_QUOTING_CHARACTER = '"'.freeze
69
42
  COLUMN_QUOTING_CHARACTER = '"'.freeze
70
-
71
- def type_cast_boolean(value)
72
- case value
73
- when TrueClass, FalseClass then value
74
- when "t", "true", "TRUE" then true
75
- when "f", nil then false
76
- else "Can't type-cast #{value.inspect} to a boolean"
77
- end
78
- end
79
-
80
- def type_cast_datetime(value)
81
- case value
82
- when DateTime then value
83
- when Date then DateTime.new(value)
84
- when String then DateTime::parse(value)
85
- else "Can't type-cast #{value.inspect} to a datetime"
86
- end
87
- end
88
-
89
- def sequence_name(table)
90
- quote_table_name(table.to_sql.gsub('"', '') + "_id_seq")
91
- end
92
43
 
93
44
  TYPES.merge!({
94
45
  :integer => 'integer'.freeze,
95
- :string => 'varchar'.freeze,
96
- :text => 'text'.freeze,
97
- :class => 'varchar'.freeze,
98
46
  :datetime => 'timestamp with time zone'.freeze
99
47
  })
100
-
101
- module Commands
102
48
 
103
- class TableExistsCommand
104
- def to_sql
105
- # TODO cache this somewhere
106
- schema_list = @adapter.connection { |db| db.exec('SHOW search_path').result[0][0].split(',').collect { |s| "'#{s}'" }.join(',') }
107
- "SELECT tablename FROM pg_tables WHERE schemaname IN (#{schema_list}) AND tablename = #{table_name}"
49
+ module Mappings
50
+ class Table
51
+ def sequence_sql
52
+ @sequence_sql ||= quote_table("_id_seq").freeze
108
53
  end
109
54
 
110
- def call
111
- sql = to_sql
112
- @adapter.log.debug(sql)
113
- reader = @adapter.connection { |db| db.exec(sql) }
114
- result = reader.entries.size > 0
115
- reader.clear
116
- result
117
- end
118
- end
119
-
120
- class DeleteCommand
121
-
122
- def execute(sql)
123
- @adapter.connection do |db|
124
- @adapter.log.debug(sql)
125
- db.exec(sql).status == PGresult::COMMAND_OK
126
- end
127
- end
128
-
129
- def to_truncate_sql
130
- table = @adapter[@klass_or_instance]
131
- sequence = @adapter.sequence_name(table)
132
- # truncate the table and reset the sequence value
133
- "DELETE FROM " << table.to_sql << "; SELECT setval('#{sequence}', (SELECT COALESCE(MAX(id)+(SELECT increment_by FROM #{sequence}), (SELECT min_value FROM #{sequence})) FROM #{table.to_sql}), false)"
134
- end
135
-
136
- def execute_drop(sql)
137
- @adapter.log.debug(sql)
138
- @adapter.connection { |db| db.exec(sql) }
139
- true
140
- end
141
-
142
- end
143
-
144
- class SaveCommand
145
-
146
- def execute_insert(sql)
147
- @adapter.connection do |db|
148
- @adapter.log.debug(sql)
149
- db.exec(sql)
150
- # Current id or latest value read from sequence in this session
151
- # See: http://www.postgresql.org/docs/8.1/interactive/functions-sequence.html
152
- @instance.key || db.exec("SELECT last_value from #{@adapter.sequence_name(@adapter[@instance.class])}")[0][0]
153
- end
154
- end
55
+ def to_create_table_sql
56
+ schema_name = name.index('.') ? name.split('.').first : nil
57
+ schema_list = @adapter.query('SELECT nspname FROM pg_namespace').join(',')
155
58
 
156
- def execute_update(sql)
157
- @adapter.connection do |db|
158
- @adapter.log.debug(sql)
159
- db.exec(sql).cmdstatus.split(' ').last.to_i > 0
59
+ sql = if schema_name and !schema_list.include?(schema_name)
60
+ "CREATE SCHEMA #{@adapter.quote_table_name(schema_name)}; "
61
+ else
62
+ ''
160
63
  end
161
- end
162
-
163
- def execute_create_table(sql)
164
- @adapter.log.debug(sql)
165
- @adapter.connection { |db| db.exec(sql) }
166
- true
167
- end
64
+
65
+ sql << "CREATE TABLE " << to_sql
168
66
 
169
- def to_create_table_sql
170
- table = @adapter[@instance]
171
-
172
- sql = "CREATE TABLE " << table.to_sql
173
-
174
- sql << " (" << table.columns.map do |column|
175
- column_long_form(column)
67
+ sql << " (" << columns.map do |column|
68
+ column.to_long_form
176
69
  end.join(', ') << ")"
177
-
178
- return sql
179
- end
180
-
181
- def column_long_form(column)
182
-
183
- long_form = if column.key?
184
- "#{column.to_sql} serial primary key"
185
- else
186
- "#{column.to_sql} #{@adapter.class::TYPES[column.type] || column.type}"
187
- end
188
- long_form << " NOT NULL" unless column.nullable?
189
- long_form << " default #{column.options[:default]}" if column.options.has_key?(:default)
190
-
191
- return long_form
192
- end
193
- end
194
-
195
- class LoadCommand
196
- def eof?(pg_result)
197
- pg_result.result.entries.empty?
198
- end
199
70
 
200
- def close_reader(pg_result)
201
- pg_result.clear
71
+ return sql
202
72
  end
203
73
 
204
- def execute(sql)
205
- @adapter.log.debug(sql)
206
- @adapter.connection { |db| db.exec(to_sql) }
74
+ def to_exists_sql
75
+ @to_exists_sql || @to_exists_sql = <<-EOS.compress_lines
76
+ SELECT TABLE_NAME
77
+ FROM INFORMATION_SCHEMA.TABLES
78
+ WHERE TABLE_NAME = #{@adapter.quote_value(name)}
79
+ AND TABLE_CATALOG = #{@adapter.quote_value(@adapter.schema.name)}
80
+ EOS
207
81
  end
208
82
 
209
- def fetch_one(pg_result)
210
- load(process_row(columns(pg_result), pg_result.result[0]))
211
- end
83
+ private
212
84
 
213
- def fetch_all(pg_result)
214
- load_instances(pg_result.fields, pg_result)
85
+ def quote_table(table_suffix = nil)
86
+ parts = name.split('.')
87
+ parts.last << table_suffix if table_suffix
88
+ parts.map { |part|
89
+ @adapter.quote_table_name(part) }.join('.')
215
90
  end
91
+ end # class Table
92
+
93
+ class Column
94
+ def serial_declaration
95
+ "SERIAL"
96
+ end
97
+
98
+ def to_long_form
99
+ @to_long_form || begin
100
+ @to_long_form = "#{to_sql}"
101
+
102
+ if serial? && !serial_declaration.blank?
103
+ @to_long_form << " #{serial_declaration}"
104
+ else
105
+ @to_long_form << " #{type_declaration}"
106
+
107
+ unless nullable? || not_null_declaration.blank?
108
+ @to_long_form << " #{not_null_declaration}"
109
+ end
110
+
111
+ if key? && !primary_key_declaration.blank?
112
+ @to_long_form << " #{primary_key_declaration}"
113
+ end
216
114
 
217
- private
218
-
219
- def columns(pg_result)
220
- columns = {}
221
- pg_result.fields.each_with_index do |name, index|
222
- columns[name] = index
223
- end
224
- columns
225
- end
226
-
227
- def process_row(columns, row)
228
- hash = {}
229
- columns.each_pair do |name,index|
230
- hash[name] = row[index]
115
+ if default && !default_declaration.blank?
116
+ @to_long_form << " #{default_declaration}"
117
+ end
118
+ end
119
+
120
+ @to_long_form
231
121
  end
232
- hash
233
122
  end
234
123
 
235
- end
236
-
237
- end
124
+ def size
125
+ nil
126
+ end
127
+ end # class Column
128
+ end # module Mappings
238
129
 
239
130
  end # class PostgresqlAdapter
240
131
 
241
132
  end # module Adapters
242
- end # module DataMapper
133
+ end # module DataMapper