I<documentation volunteers needed>
=cut
+use Carp;
use Moo;
has quote_chars => (is=>'ro', default=>sub { +[qw(" ")] } );
sub nullable { () }
-sub _ipk {
- my ($self, $field) = @_;
+sub field_autoinc {
+ my ($self,$field) = @_;
+ my $pk = $field->table->primary_key;
+ my @pk_fields = $pk ? $pk->fields : ();
+
+ if ( $field->is_auto_increment && scalar @pk_fields > 1 ){
+ croak sprintf
+ "SQLite doen't support auto increment with more then one primary key. Problem has occurred by table '%s' and column '%s'",
+ $field->table->name,
+ $field->name
+ ;
+ }
+
+ ( $_[1]->is_auto_increment ? 'AUTOINCREMENT' : () )
+}
- my $pk = $field->table->primary_key;
- my @pk_fields = $pk ? $pk->fields : ();
+sub primary_key_constraint {
+ my ($self,$table) = @_;
+ my $pk = $table->primary_key;
+ my @pk_fields = $pk ? $pk->fields : ();
+ return () if (scalar @pk_fields < 2);
- $field->is_primary_key && scalar @pk_fields == 1 &&
- ( $field->data_type =~ /int(eger)?$/i
- ||
- ( $field->data_type =~ /^number?$/i && $field->size !~ /,/ ) )
+ return 'PRIMARY KEY ('
+ . join(', ', map $self->quote($_), @pk_fields)
+ . ')';
}
+sub field_type_and_single_pk {
+ my ($self, $field) = @_;
+ my $pk = $field->table->primary_key;
+ my @pk_fields = $pk ? $pk->fields : ();
+ my $field_type = $self->field_type($field);
+
+ if ( $field->is_primary_key && scalar @pk_fields == 1){
+ # Convert int(xx), number, .. to INTEGER. This is important for backward
+ # compatibility and conversion from database to database.
+ if ( $field->data_type =~ /int(eger)?$/i
+ || ( $field->data_type =~ /^number?$/i && $field->size !~ /,/ )
+ ){
+ $field_type = 'INTEGER';
+ }
+
+ return $field_type . ' PRIMARY KEY';
+ }
+ return $field_type;
+}
+
+
sub field {
my ($self, $field) = @_;
return join ' ',
$self->field_comments($field),
$self->field_name($field),
- ( $self->_ipk($field)
- ? $field->is_auto_increment
- ? ( 'INTEGER PRIMARY KEY AUTOINCREMENT' )
- : ( 'INTEGER PRIMARY KEY' )
- : ( $self->field_type($field) )
- ),
+ $self->field_type_and_single_pk($field),
+ $self->field_autoinc($field),
$self->field_nullable($field),
$self->field_default($field, {
NULL => 1,
}
#
- # How many fields in PK?
- #
- my $pk = $table->primary_key;
- my @pk_fields = $pk ? $pk->fields : ();
-
- #
# Fields
#
- my ( @field_defs, $pk_set );
+ my ( @field_defs );
for my $field ( @fields ) {
push @field_defs, create_field($field);
}
- if (
- scalar @pk_fields > 1
- ||
- ( @pk_fields && !grep /INTEGER PRIMARY KEY/, @field_defs )
- ) {
- push @field_defs, 'PRIMARY KEY (' . join(', ', map _generator()->quote($_), @pk_fields ) . ')';
- }
-
+ push @field_defs, _generator()->primary_key_constraint($table);
+
#
# Indices
#
use strict;
use Test::More;
+use Test::Exception;
use Test::SQL::Translator qw(maybe_plan);
use SQL::Translator::Schema::View;
is_deeply($result, $expected, 'correctly built table without autoincrement on primary key');
}
+{
+ # Multi primary key test
+ my $table = SQL::Translator::Schema::Table->new(
+ name => 'multi_pk',
+ );
+ $table->add_field(
+ name => 'id',
+ data_type => 'integer',
+ is_nullable => 0,
+ is_auto_increment => 0,
+ );
+ $table->add_field(
+ name => 'id2',
+ data_type => 'integer',
+ is_nullable => 0,
+ is_auto_increment => 0,
+ );
+ $table->primary_key('id');
+ $table->primary_key('id2');
+ my $expected = [ qq<CREATE TABLE "multi_pk" (
+ "id" integer NOT NULL,
+ "id2" integer NOT NULL,
+ PRIMARY KEY ("id", "id2")
+)>];
+ my $result = [SQL::Translator::Producer::SQLite::create_table($table, { no_comments => 1 })];
+ is_deeply($result, $expected, 'correctly built table with more then one primary key');
+}
+
+{
+ # Multi primary key test
+ my $table = SQL::Translator::Schema::Table->new(
+ name => 'text_pk',
+ );
+ $table->add_field(
+ name => 'id',
+ data_type => 'text',
+ is_nullable => 0,
+ is_auto_increment => 0,
+ );
+ $table->primary_key('id');
+ my $expected = [ qq<CREATE TABLE "text_pk" (
+ "id" text PRIMARY KEY NOT NULL
+)>];
+ my $result = [SQL::Translator::Producer::SQLite::create_table($table, { no_comments => 1 })];
+ is_deeply($result, $expected, 'correctly built table with text primary key');
+}
+
+
+{
+ # Multi primary key test
+ my $table = SQL::Translator::Schema::Table->new(
+ name => 'multi_pk_with_autoinc',
+ );
+ $table->add_field(
+ name => 'id',
+ data_type => 'integer',
+ is_nullable => 0,
+ is_auto_increment => 1,
+ );
+ $table->add_field(
+ name => 'id2',
+ data_type => 'integer',
+ is_nullable => 0,
+ is_auto_increment => 0,
+ );
+ $table->primary_key('id');
+ $table->primary_key('id2');
+ my $expected = [ qq<CREATE TABLE "multi_pk" (
+ "id" integer NOT NULL,
+ "id2" integer NOT NULL,
+ PRIMARY KEY ("id", "id2")
+)>];
+
+ throws_ok {
+ SQL::Translator::Producer::SQLite::create_table(
+ $table, { no_comments => 1 }
+ )
+ } qr/SQLite doen't support auto increment with more then one primary key. Problem has occurred by table 'multi_pk_with_autoinc' and column 'id'/;
+
+}
+
+
done_testing;