put former S::T::Utils method parse_mysql_version into Translator.pm as engine_version
[dbsrgits/SQL-Translator-2.0-ish.git] / lib / SQL / Translator.pm
1 use MooseX::Declare;
2 class SQL::Translator {
3     use TryCatch;
4     use MooseX::Types::Moose qw(Bool HashRef Str);
5     use SQL::Translator::Types qw(DBIHandle Parser Producer Schema);
6     use SQL::Translator::Object::Schema;
7
8     has 'parser' => (
9         isa => Str,
10         is => 'rw',
11         init_arg => 'from',
12     );
13     
14     has 'producer' => (
15         isa => Str,
16         is => 'rw',
17         init_arg => 'to',
18     );
19     
20     has '_parser' => (
21         isa => Parser,
22         is => 'rw',
23         lazy_build => 1,
24         handles => [ qw(parse) ],
25     );
26     
27     has '_producer' => (
28         isa => Producer,
29         is => 'rw',
30         lazy_build => 1,
31         handles => [ qw(produce) ],
32     );
33     
34     has 'dbh' => (
35         isa => DBIHandle,
36         is => 'ro',
37         predicate => 'has_dbh',
38     );
39
40     has 'schema' => (
41         isa => Schema,
42         is => 'rw',
43         lazy => 1,
44         default => sub { SQL::Translator::Object::Schema->new },
45     );
46
47     has 'parser_args' => (
48         isa => HashRef,
49         is => 'rw',
50         predicate => 'has_parser_args',
51     );
52
53     has 'producer_args' => (
54         isa => HashRef,
55         is => 'rw',
56         predicate => 'has_producer_args',
57     );
58     
59     has 'add_drop_table' => (isa => Bool, is => 'rw', default => 0);
60     has 'no_comments' => (isa => Bool, is => 'rw', default => 0);
61     has 'show_warnings' => (isa => Bool, is => 'rw', default => 1);
62     has 'trace' => (isa => Bool, is => 'rw', default => 0);
63     has 'quote_table_names' => (isa => Bool, is => 'rw', default => 0);
64     has 'quote_field_names' => (isa => Bool, is => 'rw', default => 0);
65     has 'version' => (isa => Str, is => 'rw');
66     has 'filename' => (isa => Str, is => 'rw');
67
68     method _build__parser {
69         my $class = 'SQL::Translator::Parser';
70     
71         Class::MOP::load_class($class);
72     
73         my $parser;
74         if ($self->has_dbh) {
75             $parser = $class->new({ translator => $self, dbh => $self->dbh });
76         } else {
77             $parser = $class->new({ translator => $self, type => $self->parser || '' });
78         }
79     
80         return $parser;
81     }
82     
83     method _build__producer {
84         my $class = 'SQL::Translator::Producer';
85         my $role = $class . '::' . $self->producer;
86
87         Class::MOP::load_class($class);
88         try {
89             Class::MOP::load_class($role)
90         } catch ($e) {
91             $role = $class . '::SQL::' . $self->producer;
92             Class::MOP::load_class($role)
93         }
94     
95         my $producer = $class->new({ translator => $self });
96         $role->meta->apply($producer);
97     
98         return $producer;
99     }
100
101     method translate(:$data, :$producer?, :$producer_args?, :$parser?, :$parser_args?) {
102         if ($parser) {
103             $self->_clear_parser;
104             $self->parser($parser);
105             $self->parse($data);
106             $self->schema;
107         } elsif ($producer) {
108             $self->_clear_producer;
109             $self->parse($data) if $data;
110             $self->producer($producer);
111             $self->produce;
112         }
113     }
114
115     method parser_type { return $self->parser }
116     method producer_type { return $self->producer }
117
118     method engine_version(Int|Str $v, Str $target = 'perl') {
119         my @vers;
120
121         # X.Y.Z style 
122         if ( $v =~ / ^ (\d+) \. (\d{1,3}) (?: \. (\d{1,3}) )? $ /x ) {
123             push @vers, $1, $2, $3;
124         }
125
126         # XYYZZ (mysql) style 
127         elsif ( $v =~ / ^ (\d) (\d{2}) (\d{2}) $ /x ) {
128             push @vers, $1, $2, $3;
129         }
130
131         # XX.YYYZZZ (perl) style or simply X 
132         elsif ( $v =~ / ^ (\d+) (?: \. (\d{3}) (\d{3}) )? $ /x ) {
133             push @vers, $1, $2, $3;
134         }
135         else {
136             #how do I croak sanely here?
137             die "Unparseable MySQL version '$v'";
138         }
139
140         if ($target eq 'perl') {
141             return sprintf ('%d.%03d%03d', map { $_ || 0 } (@vers) );
142         }
143         elsif ($target eq 'mysql') {
144             return sprintf ('%d%02d%02d', map { $_ || 0 } (@vers) );
145         }
146         else {
147             #how do I croak sanely here?
148             die "Unknown version target '$target'";
149         }
150     }
151