... | ... |
@@ -3,81 +3,79 @@ use Object::Simple; |
3 | 3 |
use DBI; |
4 | 4 |
use SQL::Abstract; |
5 | 5 |
|
6 |
+# Model |
|
7 |
+sub model : ClassAttr { auto_build => \&_inherit_model } |
|
8 |
+ |
|
9 |
+# Inherit super class model |
|
10 |
+sub _inherit_model { |
|
11 |
+ $class = shict; |
|
12 |
+ my $super = do { |
|
13 |
+ no strict 'refs'; |
|
14 |
+ ${"${class}::ISA"}[0]; |
|
15 |
+ }; |
|
16 |
+ my $model = eval{$super->can('model')} |
|
17 |
+ ? $super->model->clone |
|
18 |
+ : $class->Object::Simple::new; |
|
19 |
+ |
|
20 |
+ $class->model($model); |
|
21 |
+} |
|
22 |
+ |
|
23 |
+# New |
|
6 | 24 |
sub new { |
7 | 25 |
my $self = shift->Object::Simple::new(@_); |
8 | 26 |
my $class = ref $self; |
9 |
- return bless {%{$class->model}, %{$self}}, $class; |
|
27 |
+ return bless {%{$class->model->clone}, %{$self}}, $class; |
|
10 | 28 |
} |
11 | 29 |
|
12 |
-sub create_model {shift->Object::Simple::new(@_); |
|
13 |
- |
|
30 |
+# Initialize modle |
|
14 | 31 |
sub initialize_model { |
15 | 32 |
my ($class, $callback) = @_; |
16 | 33 |
|
17 |
- my $model = $class->create_model; |
|
18 |
- |
|
19 |
- $callback->($model); |
|
20 |
- |
|
21 |
- $class->model($model); |
|
22 |
-} |
|
23 |
- |
|
24 |
-# Class attribute |
|
25 |
-sub connect_info : Attr { type => 'hash' } |
|
26 |
-sub table_infos : Attr { type => 'hash' } |
|
27 |
-sub dbh : Attr {} |
|
28 |
-sub sql_abstract : Attr { auto_build => sub { shift->sql_abstract(SQL::Abstract->new) }} |
|
29 |
- |
|
30 |
-sub column_info { |
|
31 |
- my ($self, $table, $column_name, $column_info) = @_; |
|
32 |
- |
|
33 |
- if (@_ > 3) { |
|
34 |
- $self->table_infos->{$table}{column}{$column_name} = $column_info; |
|
35 |
- return $self; |
|
36 |
- } |
|
37 |
- return $self->table_infos->{$table}{column}{$column_name}; |
|
34 |
+ # Callback to initialize model |
|
35 |
+ $callback->($class->model); |
|
38 | 36 |
} |
39 | 37 |
|
40 |
-sub columns { |
|
41 |
- my ($self, $table) = @_; |
|
42 |
- |
|
43 |
- return sort { |
|
44 |
- $self->table_infos->{$table}{column}{$a}{pos} |
|
45 |
- <=> |
|
46 |
- $self->table_infos->{$table}{column}{$b}{pos} |
|
47 |
- } keys %{$self->table_info->{$table}{column}} |
|
48 |
-} |
|
49 |
- |
|
50 |
-sub tables { |
|
38 |
+# Clone |
|
39 |
+sub clone { |
|
51 | 40 |
my $self = shift; |
52 |
- return keys %{$self->table_info}; |
|
53 |
-} |
|
54 |
- |
|
55 |
-sub create_table { |
|
56 |
- my ($self, $table, @row_infos) = @_; |
|
41 |
+ my $new = $self->Object::Simple::new; |
|
42 |
+ $new->connect_infos(%{$self->connect_infos || {}}); |
|
43 |
+ $new->filters(%{$self->filters || {}}); |
|
57 | 44 |
|
58 |
- $self->table_infos->{$table} = {}; |
|
45 |
+ $new->global_bind_rules(@{$self->global_bind_rules || []}); |
|
46 |
+ $new->global_fetch_rules(@{$self->global_fetch_rules || []}); |
|
59 | 47 |
|
60 |
- for (my $i = 0; $i < @columns; i++) { |
|
61 |
- my $column = $columns[$i]; |
|
62 |
- |
|
63 |
- my $column_name = shift @$column; |
|
64 |
- my $column_type = shift @$column; |
|
65 |
- my %column_options = @$column; |
|
66 |
- |
|
67 |
- my $column_info = {}; |
|
68 |
- |
|
69 |
- $column_info->{pos} = $i; |
|
70 |
- $column_info->{type} = $column_type; |
|
71 |
- $column_info->{options} = \%column_options; |
|
72 |
- |
|
73 |
- $self->column_info($table, $column_name, $column_info); |
|
48 |
+ foreach my $method (qw/bind_rules fetch_rules/) { |
|
49 |
+ my $new_rules = []; |
|
50 |
+ foreach my $rule (@{$self->method}) { |
|
51 |
+ my $new_rule = {}; |
|
52 |
+ foreach my $key ($rule) { |
|
53 |
+ if ($key eq 'filter') { |
|
54 |
+ my $new_filters = []; |
|
55 |
+ foreach my $filter (@{$rule->{$key} || []}) { |
|
56 |
+ push @$new_filters, $filter |
|
57 |
+ } |
|
58 |
+ $new_rule->{$key} = $new_filters; |
|
59 |
+ } |
|
60 |
+ else { |
|
61 |
+ $new_rule->{$key} = $rule->{$key}; |
|
62 |
+ } |
|
63 |
+ } |
|
64 |
+ push @$new_rules, $new_rule; |
|
65 |
+ } |
|
66 |
+ $self->$method($new_rules); |
|
74 | 67 |
} |
75 | 68 |
} |
76 | 69 |
|
77 |
-sub load_table_definitions { |
|
78 |
- my $self = shift; |
|
79 |
- my $dsn = $self->connect_info->{dsn}; |
|
80 |
-} |
|
70 |
+# Attribute |
|
71 |
+sub connect_info : Attr { type => 'hash', auto_build => sub { shift->connect_info({}) } } |
|
72 |
+sub global_bind_rules : Attr { type => 'array', auto_build => sub { shift->global_bind_rules([]) } } |
|
73 |
+sub global_fetch_rules : Attr { type => 'array', auto_build => sub { shift->global_fetch_rules([]) } } |
|
74 |
+sub bind_rules : Attr { type => 'hash', auto_build => sub { shift->bind_rules({}) } |
|
75 |
+sub fetch_rules : Attr { type => 'hash', auto_build => sub { shift->fetch_rules({}) } |
|
76 |
+ |
|
77 |
+sub dbh : Attr { auto_build => sub { shift->connect } } |
|
78 |
+sub sql_abstract : Attr { auto_build => sub { shift->sql_abstract(SQL::Abstract->new) }} |
|
81 | 79 |
|
82 | 80 |
sub connect { |
83 | 81 |
my $self = shift; |