File Coverage

blib/lib/DBIx/QuickORM/Schema.pm
Criterion Covered Total %
statement 70 74 94.5
branch 14 20 70.0
condition 15 30 50.0
subroutine 15 16 93.7
pod 6 7 85.7
total 120 147 81.6


line stmt bran cond sub pod time code
1             package DBIx::QuickORM::Schema;
2 24     24   201 use strict;
  24         58  
  24         1105  
3 24     24   131 use warnings;
  24         79  
  24         2475  
4              
5             our $VERSION = '0.000019';
6              
7 24     24   188 use Carp qw/confess croak/;
  24         53  
  24         1950  
8 24     24   165 use Scalar::Util qw/blessed/;
  24         87  
  24         1682  
9              
10 24     24   177 use DBIx::QuickORM::Util qw/merge_hash_of_objs column_key/;
  24         70  
  24         321  
11              
12 24     24   37553 use DBIx::QuickORM::Link;
  24         93  
  24         1308  
13              
14 24         142 use DBIx::QuickORM::Util::HashBase qw{
15             <name
16             +tables
17             <created
18             <compiled
19             <row_class
20             +_links
21 24     24   207 };
  24         84  
22              
23             sub init {
24 64     64 0 147 my $self = shift;
25              
26 64 100       361 delete $self->{+NAME} unless defined $self->{+NAME};
27              
28 64   100     434 $self->{+ROW_CLASS} //= 'DBIx::QuickORM::Row';
29              
30 64         313 $self->_resolve_links;
31              
32 64         332 for my $table ($self->tables) {
33 91 100       568 my $autofill = $table->row_class_autofill or next;
34 10         111 $autofill->define_autorow($table->row_class, $table);
35             }
36             }
37              
38 65     65 1 141508 sub tables { values %{$_[0]->{+TABLES}} }
  65         445  
39 61 50   61 1 455 sub table { $_[0]->{+TABLES}->{$_[1]} or croak "Table '$_[1]' is not defined" }
40 4   50 4 1 3256 sub maybe_table { return $_[0]->{+TABLES}->{$_[1]} // undef }
41 64     64   502 sub _links { delete $_[0]->{+_LINKS} }
42              
43             sub add_table {
44 0     0 1 0 my $self = shift;
45 0         0 my ($name, $table) = @_;
46              
47 0 0       0 croak "Table '$name' already defined" if $self->{+TABLES}->{$name};
48              
49 0         0 return $self->{+TABLES}->{$name} = $table;
50             }
51              
52             sub merge {
53 3     3 1 8 my $self = shift;
54 3         12 my ($other, %params) = @_;
55              
56 3   33     35 $params{+TABLES} //= merge_hash_of_objs($self->{+TABLES}, $other->{+TABLES});
57 3 50 0     15 $params{+NAME} //= $self->{+NAME} if $self->{+NAME};
58 3   33     23 $params{+ROW_CLASS} //= $other->{+ROW_CLASS};
59              
60 3         24 return ref($self)->new(%$self, %$other, %params);
61             }
62              
63             sub clone {
64 20     20 1 63 my $self = shift;
65 20         60 my %params = @_;
66              
67 20   50     186 $params{+TABLES} //= {map { $_ => $self->{+TABLES}->{$_}->clone } keys %{$self->{+TABLES}}};
  28         217  
  20         6132  
68 20 100 33     138 $params{+NAME} //= $self->{+NAME} if $self->{+NAME};
69              
70 20         148 return blessed($self)->new(%$self, %params);
71             }
72              
73             sub _resolve_links {
74 64     64   131 my $self = shift;
75              
76 64   100     132 my @links = @{$self->_links // []};
  64         240  
77 64   100     152 push @links => @{$_->_links // []} for values %{$self->{+TABLES}};
  64         261  
  91         382  
78              
79 64         174 for my $link (@links) {
80 12         36 my ($local_set, $other_set, $debug) = @$link;
81 12   100     58 $debug //= 'unknown';
82              
83 12         31 my ($local_tname, $local_cols, $local_alias) = @$local_set;
84 12         35 my ($other_tname, $other_cols, $other_alias) = @$other_set;
85              
86 12 50       46 my $local_table = $self->{+TABLES}->{$local_tname} or confess "Cannot find table '$local_tname' ($debug)";
87 12 50       55 my $other_table = $self->{+TABLES}->{$other_tname} or confess "Cannot find table '$other_tname' ($debug)";
88              
89 12 100 33     94 my $local_unique //= $other_table->unique->{column_key(@{$other_cols})} ? 1 : 0;
  12         45  
90 12 100 33     76 my $other_unique //= $local_table->unique->{column_key(@{$local_cols})} ? 1 : 0;
  12         39  
91              
92 12         55 push @{$local_table->links} => DBIx::QuickORM::Link->new(
93             local_table => $local_tname,
94             local_columns => $local_cols,
95             other_table => $other_tname,
96             other_columns => $other_cols,
97             unique => $local_unique,
98 12         39 aliases => [grep { $_ } $local_alias],
  12         93  
99             created => $debug,
100             );
101              
102 12         49 push @{$other_table->links} => DBIx::QuickORM::Link->new(
103             local_table => $other_tname,
104             local_columns => $other_cols,
105             other_table => $local_tname,
106             other_columns => $local_cols,
107             unique => $other_unique,
108 12         25 aliases => [grep { $_ } $other_alias],
  12         91  
109             created => $debug,
110             );
111             }
112              
113 64         3222 return;
114             }
115              
116             1;
117              
118             __END__
119              
120             =pod
121              
122             =encoding UTF-8
123              
124             =head1 NAME
125              
126             DBIx::QuickORM::Schema - Object representing a database schema.
127              
128             =head1 DESCRIPTION
129              
130             This object represents a single schema in the database. This includes tables,
131             indexes, columns, etc.
132              
133             =head1 SYNOPSIS
134              
135             In your custom ORM package:
136              
137             package My::ORM;
138             use strict;
139             use warnings;
140              
141             use DBIx::QuickORM;
142              
143             orm MyORM => sub {
144             schema MySchema => sub {
145             ...
146             };
147             ...
148             }
149              
150             In other code:
151              
152             use My::ORM qw/orm/;
153              
154             my $schema = orm('MyORM')->schema;
155              
156             =head1 METHODS
157              
158             =over 4
159              
160             =item $schema->add_table($table_name, $table_ref)
161              
162             Add a table to the schema. Requires a table name and an
163             L<DBIx::QuickORM::Schema::Table> instance.
164              
165             An exception will be thrown if a table of the given name already exists.
166              
167             =item $new_schema = $schema->clone(%overrides)
168              
169             Create a copy of the schema, with any attributes you wish to have changed in
170             the copy.
171              
172             =item $trace = $schema->compiled()
173              
174             May be undef. A string like C<'FILENAME line LINENUM'> in most cases. This
175             trace tells you where the schema object was compiled.
176              
177             =item $trace = $schema->created()
178              
179             May be undef. A string like C<'FILENAME line LINENUM'> in most cases. This
180             trace tells you where the schema object was initially defined.
181              
182             =item $schema3 = $schema->merge($schema2)
183              
184             Merge 2 schema objects into a single third one.
185              
186             =item $name = $schema->name()
187              
188             Get the name of the schema.
189              
190             =item $class = $schema->row_class()
191              
192             Get the row class used by default when fetching rows from this schema. This can
193             be overriden on a per-table basis.
194              
195             =item $table = $schema->table($name)
196              
197             Get the table of the specified name. An exception will be thrown if the table
198             is not defined.
199              
200             =item $table_or_undef = $schema->maybe_table($table_name)
201              
202             Get the table with the specified name. Return undef if the table is not
203             defined.
204              
205             =item @tables = $schema->tables()
206              
207             Get all table objects. Each item is an instance of
208             L<DBIx::QuickORM::Schema::Table>.
209              
210             =back
211              
212             =head1 SOURCE
213              
214             The source code repository for DBIx::QuickORM can be found at
215             L<https://https://github.com/exodist/DBIx-QuickORM>.
216              
217             =head1 MAINTAINERS
218              
219             =over 4
220              
221             =item Chad Granum E<lt>exodist@cpan.orgE<gt>
222              
223             =back
224              
225             =head1 AUTHORS
226              
227             =over 4
228              
229             =item Chad Granum E<lt>exodist@cpan.orgE<gt>
230              
231             =back
232              
233             =head1 COPYRIGHT
234              
235             Copyright Chad Granum E<lt>exodist7@gmail.comE<gt>.
236              
237             This program is free software; you can redistribute it and/or
238             modify it under the same terms as Perl itself.
239              
240             See L<https://dev.perl.org/licenses/>
241              
242             =cut