Commit | Line | Data |
4f4fd192 |
1 | use MooseX::Declare; |
2 | role SQL::Translator::Parser::DDL::SQLite { |
3db4188f |
3 | use MooseX::Types::Moose qw(Str); |
4 | use MooseX::MultiMethods; |
96d4d861 |
5 | use Moose::Autobox; |
3db4188f |
6 | use SQL::Translator::Constants qw(:sqlt_types :sqlt_constants); |
7 | use SQL::Translator::Types qw(Schema); |
8 | use aliased 'SQL::Translator::Object::Column'; |
9 | use aliased 'SQL::Translator::Object::Constraint'; |
10 | use aliased 'SQL::Translator::Object::ForeignKey'; |
11 | use aliased 'SQL::Translator::Object::Index'; |
12 | use aliased 'SQL::Translator::Object::PrimaryKey'; |
3db4188f |
13 | use aliased 'SQL::Translator::Object::Table'; |
9b231fde |
14 | use aliased 'SQL::Translator::Object::Trigger'; |
15 | use aliased 'SQL::Translator::Object::View'; |
3db4188f |
16 | |
17 | around _build_data_type_mapping { |
18 | my $data_type_mapping = $self->$orig; |
19 | $data_type_mapping->{date} = SQL_DATE(); |
20 | |
21 | return $data_type_mapping; |
22 | }; |
23 | |
24 | multi method parse(Schema $data) { $data } |
25 | |
26 | multi method parse(Str $data) { |
3db4188f |
27 | my $translator = $self->translator; |
3db4188f |
28 | my $parser = Parse::RecDescent->new($self->grammar); |
29 | |
3db4188f |
30 | unless (defined $parser) { |
31 | return $translator->error("Error instantiating Parse::RecDescent ". |
1d064df4 |
32 | "instance: Bad grammar"); |
3db4188f |
33 | } |
34 | |
35 | my $result = $parser->startrule($data); |
36 | die "Parse failed" unless defined $result; |
3db4188f |
37 | |
38 | my $schema = $translator->schema; |
39 | my @tables = |
29628de6 |
40 | sort { $result->{tables}{$a}{order} <=> $result->{tables}{$b}{order} } |
41 | keys %{ $result->{tables} }; |
42 | |
3db4188f |
43 | for my $table_name ( @tables ) { |
29628de6 |
44 | my $tdata = $result->{tables}{ $table_name }; |
8d112909 |
45 | my $table = Table->new({ name => $tdata->{name}, schema => $schema }); |
29628de6 |
46 | $table->comments( $tdata->{comments}->flatten ) if $tdata->{comments}; |
9b231fde |
47 | $schema->add_table($table); |
3db4188f |
48 | |
29628de6 |
49 | for my $fdata ( @{ $tdata->{fields} } ) { |
9b231fde |
50 | my $field = Column->new({ |
29628de6 |
51 | name => $fdata->{name}, |
52 | data_type => $fdata->{data_type}, |
9b231fde |
53 | sql_data_type => $self->data_type_mapping->{$fdata->{data_type}} || -999999, |
29628de6 |
54 | size => $fdata->{size}, |
55 | default_value => $fdata->{default}, |
56 | is_auto_increment => $fdata->{is_auto_inc}, |
7f897a63 |
57 | is_nullable => $fdata->{is_primary_key} ? 0 : $fdata->{is_nullable}, |
29628de6 |
58 | comments => $fdata->{comments}, |
9b231fde |
59 | table => $table, |
60 | }); |
8d112909 |
61 | |
9b231fde |
62 | $table->add_column($field); |
29628de6 |
63 | $table->primary_key( $field->name ) if $fdata->{is_primary_key}; |
8d112909 |
64 | |
29628de6 |
65 | for my $cdata ( @{ $fdata->{constraints} } ) { |
66 | next unless $cdata->{type} eq 'foreign_key'; |
67 | $cdata->{fields} ||= [ $field->name ]; |
68 | push @{ $tdata->{constraints} }, $cdata; |
3db4188f |
69 | } |
70 | } |
71 | |
29628de6 |
72 | for my $idata ( @{ $tdata->{indices} || [] } ) { |
9b231fde |
73 | my @columns = delete $idata->{fields}; |
74 | my $index = Index->new({ |
29628de6 |
75 | name => $idata->{name}, |
76 | type => uc $idata->{type}, |
9b231fde |
77 | table => $table, |
78 | }); |
79 | $index->add_column($table->get_column(@$_[0])) for @columns; |
80 | $table->add_index($index); |
3db4188f |
81 | } |
82 | |
29628de6 |
83 | for my $cdata ( @{ $tdata->{constraints} || [] } ) { |
9b231fde |
84 | my $constraint; |
85 | if (uc $cdata->{type} eq 'PRIMARY_KEY') { |
86 | $constraint = PrimaryKey->new({ name => $cdata->{name} || 'primary_key', table => $table }); |
7f897a63 |
87 | |
88 | for my $field (@{$cdata->{fields}}) { |
89 | $table->get_column($field)->is_primary_key(1); |
90 | $table->get_column($field)->is_nullable(0); |
91 | $constraint->add_column($table->get_column($field)); |
92 | } |
9b231fde |
93 | } elsif (uc $cdata->{type} eq 'FOREIGN_KEY') { |
94 | $constraint = ForeignKey->new({ name => $cdata->{name} || 'foreign_key', |
95 | table => $table, |
96 | reference_table => $cdata->{reference_table}, |
859b70aa |
97 | reference_columns => ref $cdata->{reference_fields} ? $cdata->{reference_fields} : [ $cdata->{reference_fields} ], |
9b231fde |
98 | on_delete => $cdata->{on_delete} || $cdata->{on_delete_do}, |
99 | on_update => $cdata->{on_update} || $cdata->{on_update_do} }); |
7f897a63 |
100 | for my $field (@{$cdata->{fields}}) { |
101 | $table->get_column($field)->is_foreign_key(1); |
102 | $table->get_column($field)->foreign_key_reference($constraint); |
103 | $constraint->add_column($table->get_column($field)); |
104 | } |
9b231fde |
105 | } else { |
106 | $constraint = Constraint->new({ name => $cdata->{name} || 'constraint', type => uc $cdata->{type}, table => $table }); |
7f897a63 |
107 | if (uc $cdata->{type} eq 'UNIQUE') { |
108 | $table->get_column($_)->is_unique(1) for @{$cdata->{fields}}; |
109 | } |
9b231fde |
110 | $constraint->add_column($table->get_column($_)) for @{$cdata->{fields}}; |
111 | } |
7f897a63 |
112 | |
9b231fde |
113 | $table->add_constraint($constraint); |
3db4188f |
114 | } |
115 | } |
116 | |
29628de6 |
117 | for my $def ( @{ $result->{views} || [] } ) { |
9b231fde |
118 | my $view = View->new({ |
29628de6 |
119 | name => $def->{name}, |
120 | fields => $def->{fields}, |
121 | sql => $def->{sql}, |
9b231fde |
122 | }); |
123 | $schema->add_view($view); |
3db4188f |
124 | } |
125 | |
29628de6 |
126 | for my $def ( @{ $result->{triggers} || [] } ) { |
9b231fde |
127 | my $trigger = Trigger->new({ |
29628de6 |
128 | name => $def->{name}, |
129 | perform_action_when => $def->{when}, |
130 | database_events => $def->{db_events}, |
131 | action => $def->{action}, |
132 | on_table => $def->{on_table}, |
9b231fde |
133 | }); |
134 | $schema->add_trigger($trigger); |
3db4188f |
135 | } |
3db4188f |
136 | return 1; |
137 | } |
4f4fd192 |
138 | } |