7c896154b99b95c569356927833ef2b2489de32c
[dbsrgits/SQL-Abstract-2.0-ish.git] / lib / SQL / Abstract.pm
1 use MooseX::Declare;
2 use MooseX::Method::Signatures;
3
4
5 class SQL::Abstract {
6
7   use Carp qw/croak/;
8   use Data::Dump qw/pp/;
9
10   use Moose::Util::TypeConstraints;
11   use MooseX::Types -declare => ['NameSeparator'];
12   use MooseX::Types::Moose qw/ArrayRef Str/;
13   use MooseX::AttributeHelpers;
14
15   use namespace::clean -except => ['meta'];
16
17   subtype NameSeparator,
18     as ArrayRef[Str];
19     #where { @$_ == 1 ||| @$_ == 2 },
20     #message { "Name separator must be one or two elements" };
21
22   coerce NameSeparator, from Str, via { [ $_ ] };
23
24   our $VERSION = '2.000000';
25
26   our $AST_VERSION = '1';
27
28   has name_separator => ( 
29     is => 'rw', 
30     isa => NameSeparator,
31     default => sub { ['.'] },
32     coerece => 1,
33     required => 1,
34   );
35
36   has list_separator => ( 
37     is => 'rw', 
38     isa => Str,
39     default => ', ',
40     required => 1,
41   );
42
43   has binds => (
44     isa => ArrayRef,
45     default => sub { [ ] },
46     metaclass => 'Collection::Array',
47     provides => {
48       push => 'add_bind',
49       get => 'binds'
50     }
51   );
52
53   method generate (ArrayRef $ast) {
54     $self = new $self unless blessed($self);
55
56     local $_ = $ast->[0];
57     s/^-/_/ or croak "Unknown type tag '$_'";
58     my $meth = $self->can($_) || \&_generic_func;
59     return $meth->($self, $ast);
60   }
61
62   method _select(ArrayRef $ast) {
63     
64   }
65
66   method _name(ArrayRef $ast) {
67     my (undef, @names) = @$ast;
68
69     my $sep = $self->name_separator;
70
71     return $sep->[0] . 
72            join( $sep->[1] . $sep->[0], @names ) . 
73            $sep->[1]
74               if (@$sep > 1);
75
76     return join($sep->[0], @names);
77   }
78
79   method _list(ArrayRef $ast) {
80     my (undef, @items) = @$ast;
81
82     return join(
83       $self->list_separator,
84       map { $self->generate($_) } @items);
85   }
86
87   method _alias(ArrayRef $ast) {
88     my (undef, $alias, $as) = @$ast;
89
90     return $self->generate($alias) . " AS $as";
91
92   }
93
94   method _value(ArrayRef $ast) {
95     my ($undef, $value) = @$ast;
96
97     $self->add_bind($value);
98     return "?";
99   }
100
101   method _where(ArrayRef $ast) {
102     my (undef, @clauses) = @$ast;
103
104     my @output;
105
106     foreach (@clauses) {
107       my $op = $_->[0];
108
109       unless (substr($op, 0, 1) eq '-') {
110         # A simple comparison op (==, >, etc.)
111         croak "Binary operator $op expects 2 children, got " . $#$_
112           if @{$_} > 3;
113
114         push @output, $self->generate($_->[1]), 
115                       $op,
116                       $self->generate($_->[2]);
117       }
118     }
119
120     return join(' ', 'WHERE', @output);
121   }
122
123   method _generic_func(ArrayRef $ast) {
124   }
125
126
127 };