Move the AST walking code out into seperate class
[dbsrgits/SQL-Abstract-2.0-ish.git] / lib / SQL / Abstract.pm
1 use MooseX::Declare;
2
3
4 class SQL::Abstract {
5
6   use Carp qw/croak/;
7   use Data::Dump qw/pp/;
8
9   use Moose::Util::TypeConstraints;
10   use MooseX::Types -declare => [qw/NameSeparator/];
11   use MooseX::Types::Moose qw/ArrayRef Str Int/;
12   use MooseX::AttributeHelpers;
13
14   clean;
15
16   subtype NameSeparator,
17     as ArrayRef[Str];
18     #where { @$_ == 1 ||| @$_ == 2 },
19     #message { "Name separator must be one or two elements" };
20
21   coerce NameSeparator, from Str, via { [ $_ ] };
22
23   our $VERSION = '2.000000';
24
25   our $AST_VERSION = '1';
26
27   # Operator precedence for bracketing
28   our %PRIO = (
29     and => 10,
30     or  => 50
31   );
32
33   our %OP_MAP = (
34     '>' => '>',
35     '<' => '<',
36     '==' => '=',
37     '!=' => '!=',
38   );
39
40   has ast_version => (
41     is => 'ro',
42     isa => Int,
43     required => 1
44   );
45
46   has name_separator => ( 
47     is => 'rw', 
48     isa => NameSeparator,
49     default => sub { ['.'] },
50     coerece => 1,
51     required => 1,
52   );
53
54   has list_separator => ( 
55     is => 'rw', 
56     isa => Str,
57     default => ', ',
58     required => 1,
59   );
60
61   has binds => (
62     isa => ArrayRef,
63     is => 'ro',
64     default => sub { [ ] },
65     metaclass => 'Collection::Array',
66     provides => {
67       push => 'add_bind',
68       clear => '_clear_binds',
69     }
70   );
71
72   # TODO: once MXMS supports %args, use that here
73   method create(ClassName $class: Int $ver) {
74     croak "AST version $ver is greater than supported version of $AST_VERSION"
75       if $ver > $AST_VERSION;
76
77     my $name = "${class}::AST::v$ver";
78     Class::MOP::load_class($name);
79
80     return $name->new(ast_version => $ver);
81   }
82
83   # Main entry point
84   method generate(ClassName $class: ArrayRef $ast) {
85     croak "SQL::Abstract AST version not specified"
86       unless ($ast->[0] eq '-ast_version');
87
88     my (undef, $ver) = splice(@$ast, 0, 2);
89
90     # TODO: once MXMS supports %args, use that here
91     my $self = $class->create($ver);
92
93     return ($self->dispatch($ast), $self->binds);
94   }
95
96
97 };