Hi,

I'm working on converting the test suite over to AR::Schema.
I'm finding there are a lot of barriers to doing this due to somewhat
limited customization support in AR::Schema.

Here are some ideas (some implemented already) to extend AR::Schema, but
still keep it (relatively) true to its original design.

Foreign Key Support (MySQL in this instance):

create_table(:accounts) do |t|
  t.column :company_id, :integer, :null => false, :foreign_key_table =>
:companies
end

=> 

create table accounts (
  id int(11) not null auto_increment primary key,
  company_id int(11) not null foreign key (`company_id`) references
`companies`(`id`)
)

I've got this working great for all adapters already. Though not shown here,
you can also pass :foreign_key_column for non-standard primary key column
names.


Since there are times where it doesn't make sense for AR::Schema to support
a specific column type/definition, what are your ideas on this (from the
postgres.sql):

CREATE TABLE geometrics (
  id serial primary key,
  a_point point,
  a_line_segment lseg,
  ...
);

Can be generated as such:

create_table(:geometrics) do |t|
  t.column :a_point, :custom, :type => "point default (1,3)",
  t.column :a_line_segment, :custom, :type => "lseg",
  ...
end

The keywords ":custom and :type" aren't important here, the concept is.
":describe and :description", ":define and :definition" are alternatives.
I think this would be a nice addition, but it depends on how pure you want
to be, personally I lost all my pureness from years of PHP programming.

Wait, there's more...

Most adapters create an auto incrementing column differently. Some are built
into the primary key column definition (MySQL, SQL Server), others use
explicit sequences, others use functions etc.. combine this with the
ability/desire to set the starting sequence number and it gets all messed up
(which most of the AR unit tests schemas do).
While there are no elegant solutions, I do believe its possible to support
all adapters, by adding an empty create_sequence method in `module
SchemaStatements` and have the adapters create their own if needed. To
handle setting the start value, here's one idea:

create_sequence(:accounts, :name => 'public.account_id_seq', :start => 100)
create_table(:accounts) do |t|
...
end


Which adds whatever method the adaptor needs to implement the auto-increment
column and set the start value. Some do it on the primary key column
definition (SQL Server), some call a separate function (PGSQL), MySQL adds
it as a table option after the closing ) etc. Option B for this one would be
to change all the AR unit tests to not require the non-standard start
sequence.

And more...

Primary Keys. While the convention is certainly to have an auto_incrementing
integer primary key column, even the AR unit tests have table definitions
with string based primary keys and some db_definitions have multi-column PKs
defined. AR::Schema already has the ability to turn off auto generation of
the primary key, I also propose a method to add an explicit PRIMARY KEY
(column), for example, from an existing test fixture:

create_table :subscribers do |t|
  t.column :nick, :string, :limit => 100, :null => false
  t.column :name, :string, :limit => 100
  t.add_primary_key :nick
end

=>

CREATE TABLE `subscribers` (
  `nick` varchar(100) NOT NULL,
  `name` varchar(100) default NULL,
  PRIMARY KEY (`nick`)
) TYPE=InnoDB;

t.add_primary_key(:categories, :posts) would generate a multi-column pk

While there are a ton more issues to deal with, I'll save those for later to
not cloud these issues since these are the bigger ones I/we would need to
tackle to achieve moving the unit tests to AR::Schema.

I await your ideas/comments.

Thanks,

Bob Silva
http://www.railtie.net/



_______________________________________________
Rails-core mailing list
Rails-core@lists.rubyonrails.org
http://lists.rubyonrails.org/mailman/listinfo/rails-core

Reply via email to