File Coverage

blib/lib/Muldis/DB/Engine/Example/PhysType.pm
Criterion Covered Total %
statement 114 530 21.5
branch 0 78 0.0
condition 0 9 0.0
subroutine 38 150 25.3
pod 0 15 0.0
total 152 782 19.4


line stmt bran cond sub pod time code
1 1     1   6466 use 5.008001;
  1         4  
  1         51  
2 1     1   6 use utf8;
  1         3  
  1         9  
3 1     1   33 use strict;
  1         3  
  1         46  
4 1     1   7 use warnings FATAL => 'all';
  1         2  
  1         138  
5              
6             ###########################################################################
7             ###########################################################################
8              
9             my $BOOL_FALSE = (1 == 0);
10             my $BOOL_TRUE = (1 == 1);
11              
12             my $ORDER_INCREASE = (1 <=> 2);
13             my $ORDER_SAME = (1 <=> 1);
14             my $ORDER_DECREASE = (2 <=> 1);
15              
16             my $EMPTY_STR = q{};
17              
18             ###########################################################################
19             ###########################################################################
20              
21             { package Muldis::DB::Engine::Example::PhysType; # module
22             our $VERSION = 0.004000;
23             # Note: This given version applies to all of this file's packages.
24              
25 1     1   6 use base 'Exporter';
  1         3  
  1         1289  
26             our @EXPORT_OK = qw(
27             ptBool ptOrder ptInt ptBlob ptText
28             ptTuple ptQuasiTuple
29             ptRelation ptQuasiRelation
30             ptTypeInvo ptQuasiTypeInvo
31             ptTypeDict ptQuasiTypeDict
32             ptValueDict ptQuasiTypeDict
33             );
34              
35             ###########################################################################
36              
37             sub ptBool {
38 0     0 0   my ($args) = @_;
39 0           my ($v) = @{$args}{'v'};
  0            
40 0           return Muldis::DB::Engine::Example::PhysType::Bool->new({ 'v' => $v });
41             }
42              
43             sub ptOrder {
44 0     0 0   my ($args) = @_;
45 0           my ($v) = @{$args}{'v'};
  0            
46 0           return Muldis::DB::Engine::Example::PhysType::Order->new({ 'v' => $v });
47             }
48              
49             sub ptInt {
50 0     0 0   my ($args) = @_;
51 0           my ($v) = @{$args}{'v'};
  0            
52 0           return Muldis::DB::Engine::Example::PhysType::Int->new({ 'v' => $v });
53             }
54              
55             sub ptBlob {
56 0     0 0   my ($args) = @_;
57 0           my ($v) = @{$args}{'v'};
  0            
58 0           return Muldis::DB::Engine::Example::PhysType::Blob->new({ 'v' => $v });
59             }
60              
61             sub ptText {
62 0     0 0   my ($args) = @_;
63 0           my ($v) = @{$args}{'v'};
  0            
64 0           return Muldis::DB::Engine::Example::PhysType::Text->new({ 'v' => $v });
65             }
66              
67             sub ptTuple {
68 0     0 0   my ($args) = @_;
69 0           my ($heading, $body) = @{$args}{'heading', 'body'};
  0            
70 0           return Muldis::DB::Engine::Example::PhysType::Tuple->new({
71             'heading' => $heading, 'body' => $body });
72             }
73              
74             sub ptQuasiTuple {
75 0     0 0   my ($args) = @_;
76 0           my ($heading, $body) = @{$args}{'heading', 'body'};
  0            
77 0           return Muldis::DB::Engine::Example::PhysType::QuasiTuple->new({
78             'heading' => $heading, 'body' => $body });
79             }
80              
81             sub ptRelation {
82 0     0 0   my ($args) = @_;
83 0           my ($heading, $body) = @{$args}{'heading', 'body'};
  0            
84 0           return Muldis::DB::Engine::Example::PhysType::Relation->new({
85             'heading' => $heading, 'body' => $body });
86             }
87              
88             sub ptQuasiRelation {
89 0     0 0   my ($args) = @_;
90 0           my ($heading, $body) = @{$args}{'heading', 'body'};
  0            
91 0           return Muldis::DB::Engine::Example::PhysType::QuasiRelation->new({
92             'heading' => $heading, 'body' => $body });
93             }
94              
95             sub ptTypeInvo {
96 0     0 0   my ($args) = @_;
97 0           my ($kind, $spec) = @{$args}{'kind', 'spec'};
  0            
98 0           return Muldis::DB::Engine::Example::PhysType::TypeInvo->new({
99             'kind' => $kind, 'spec' => $spec });
100             }
101              
102             sub ptQuasiTypeInvo {
103 0     0 0   my ($args) = @_;
104 0           my ($kind, $spec) = @{$args}{'kind', 'spec'};
  0            
105 0           return Muldis::DB::Engine::Example::PhysType::QuasiTypeInvo->new({
106             'kind' => $kind, 'spec' => $spec });
107             }
108              
109             sub ptTypeDict {
110 0     0 0   my ($args) = @_;
111 0           my ($map) = @{$args}{'map'};
  0            
112 0           return Muldis::DB::Engine::Example::PhysType::TypeDict->new({
113             'map' => $map });
114             }
115              
116             sub ptQuasiTypeDict {
117 0     0 0   my ($args) = @_;
118 0           my ($map) = @{$args}{'map'};
  0            
119 0           return Muldis::DB::Engine::Example::PhysType::QuasiTypeDict->new({
120             'map' => $map });
121             }
122              
123             sub ptValueDict {
124 0     0 0   my ($args) = @_;
125 0           my ($map) = @{$args}{'map'};
  0            
126 0           return Muldis::DB::Engine::Example::PhysType::ValueDict->new({
127             'map' => $map });
128             }
129              
130             sub ptQuasiValueDict {
131 0     0 0   my ($args) = @_;
132 0           my ($map) = @{$args}{'map'};
  0            
133 0           return Muldis::DB::Engine::Example::PhysType::QuasiValueDict->new({
134             'map' => $map });
135             }
136              
137             ###########################################################################
138              
139             } # module Muldis::DB::Engine::Example::PhysType
140              
141             ###########################################################################
142             ###########################################################################
143              
144             { package Muldis::DB::Engine::Example::PhysType::Value; # role
145              
146 1     1   8 use Carp;
  1         2  
  1         99  
147 1     1   31 use Scalar::Util qw(blessed);
  1         2  
  1         595  
148              
149             # my $ATTR_ROOT_TYPE = 'Value::root_type';
150             # Muldis::DB::Engine::Example::PhysType::Cat_EntityName.
151             # This is the fundamental Muldis D data type that this ::Value
152             # object's implementation sees it as a generic member of, and which
153             # generally determines what operators can be used with it.
154             # It is a supertype of the declared type.
155             # my $ATTR_DECL_TYPE = 'Value::decl_type';
156             # Muldis::DB::Engine::Example::PhysType::Cat_EntityName.
157             # This is the Muldis D data type that the ::Value was declared to
158             # be a member of when the ::Value object was created.
159             # my $ATTR_LAST_KNOWN_MST = 'Value::last_known_mst';
160             # Muldis::DB::Engine::Example::PhysType::Cat_EntityName.
161             # This is the Muldis::DB data type that is the most specific type
162             # of this ::Value, as it was last determined.
163             # It is a subtype of the declared type.
164             # Since calculating a value's mst may be expensive, this object
165             # attribute may either be unset or be out of date with respect to
166             # the current type system, that is, not be automatically updated at
167             # the same time that a new subtype of its old mst is declared.
168              
169             # my $ATTR_WHICH = 'Value::which';
170             # Str.
171             # This is a unique identifier for the value that this object
172             # represents that should compare correctly with the corresponding
173             # identifiers of all ::Value-doing objects.
174             # It is a text string of format " " where:
175             # 1. is the value's root type name (fully qualified)
176             # 2. is the character-length of
177             # 3. is the (class-determined) stringified value itself
178             # 4. is the character-length of
179             # This identifier is mainly used when a ::Value needs to be used as
180             # a key to index the ::Value with, not necessarily when comparing
181             # 2 values for equality.
182             # This identifier can be expensive to calculate, so it will be done
183             # only when actually required; eg, by the which() method.
184              
185             ###########################################################################
186              
187             sub new {
188 0     0     my ($class, $args) = @_;
189 0           my $self = bless {}, $class;
190 0           $self->_build( $args );
191 0           return $self;
192             }
193              
194             sub _build {
195 0     0     return; # default for any classes having no attributes
196             }
197              
198             ###########################################################################
199              
200             sub root_type {
201 0     0     my ($self) = @_;
202 0           confess q{not implemented by subclass } . (blessed $self);
203             }
204              
205             sub declared_type {
206 0     0     my ($self) = @_;
207 0           confess q{not implemented by subclass } . (blessed $self);
208             }
209              
210             sub most_specific_type {
211 0     0     my ($self) = @_;
212 0           confess q{not implemented by subclass } . (blessed $self);
213             }
214              
215             sub which {
216 0     0     my ($self) = @_;
217 0           confess q{not implemented by subclass } . (blessed $self);
218             }
219              
220             ###########################################################################
221              
222             sub as_ast {
223 0     0     my ($self) = @_;
224 0           confess q{not implemented by subclass } . (blessed $self);
225             }
226              
227             ###########################################################################
228              
229             sub equal {
230 0     0     my ($self, $args) = @_;
231 0           my ($other) = @{$args}{'other'};
  0            
232 0 0         return $BOOL_FALSE
233             if blessed $other ne blessed $self;
234 0           return $self->_equal( $other );
235             }
236              
237             sub _equal {
238 0     0     my ($self) = @_;
239 0           confess q{not implemented by subclass } . (blessed $self);
240             }
241              
242             ###########################################################################
243              
244             } # role Muldis::DB::Engine::Example::PhysType::Value
245              
246             ###########################################################################
247             ###########################################################################
248              
249             { package Muldis::DB::Engine::Example::PhysType::Bool; # class
250 1     1   5 use base 'Muldis::DB::Engine::Example::PhysType::Value';
  1         2  
  1         893  
251              
252             my $ATTR_V = 'v';
253             # A p5 Scalar that equals $BOOL_FALSE|$BOOL_TRUE.
254              
255             my $ATTR_WHICH = 'which';
256              
257             ###########################################################################
258              
259             sub _build {
260 0     0     my ($self, $args) = @_;
261 0           my ($v) = @{$args}{'v'};
  0            
262 0           $self->{$ATTR_V} = $v;
263 0           return;
264             }
265              
266             ###########################################################################
267              
268             sub root_type {
269 0     0     return 'sys.Core.Bool.Bool';
270             }
271              
272             sub which {
273 0     0     my ($self) = @_;
274 0 0         if (!defined $self->{$ATTR_WHICH}) {
275 0           my $s = ''.$self->{$ATTR_V};
276 0           my $len_s = length $s;
277 0           $self->{$ATTR_WHICH} = "18 sys.Core.Bool.Bool $len_s $s";
278             }
279 0           return $self->{$ATTR_WHICH};
280             }
281              
282             ###########################################################################
283              
284             sub as_ast {
285 0     0     my ($self) = @_;
286 0           return Muldis::DB::LOSE::Bool->new({ 'v' => $self->{$ATTR_V} });
287             }
288              
289             ###########################################################################
290              
291             sub _equal {
292 0     0     my ($self, $other) = @_;
293 0           return $other->{$ATTR_V} eq $self->{$ATTR_V};
294             }
295              
296             ###########################################################################
297              
298             sub v {
299 0     0     my ($self) = @_;
300 0           return $self->{$ATTR_V};
301             }
302              
303             ###########################################################################
304              
305             } # class Muldis::DB::Engine::Example::PhysType::Bool
306              
307             ###########################################################################
308             ###########################################################################
309              
310             { package Muldis::DB::Engine::Example::PhysType::Order; # class
311 1     1   7 use base 'Muldis::DB::Engine::Example::PhysType::Value';
  1         1  
  1         838  
312              
313             my $ATTR_V = 'v';
314             # A p5 Scalar that equals $ORDER_(INCREASE|SAME|DECREASE).
315              
316             my $ATTR_WHICH = 'which';
317              
318             ###########################################################################
319              
320             sub _build {
321 0     0     my ($self, $args) = @_;
322 0           my ($v) = @{$args}{'v'};
  0            
323 0           $self->{$ATTR_V} = $v;
324 0           return;
325             }
326              
327             ###########################################################################
328              
329             sub root_type {
330 0     0     return 'sys.Core.Order.Order';
331             }
332              
333             sub which {
334 0     0     my ($self) = @_;
335 0 0         if (!defined $self->{$ATTR_WHICH}) {
336 0           my $s = ''.$self->{$ATTR_V};
337 0           my $len_s = length $s;
338 0           $self->{$ATTR_WHICH} = "20 sys.Core.Order.Order $len_s $s";
339             }
340 0           return $self->{$ATTR_WHICH};
341             }
342              
343             ###########################################################################
344              
345             sub as_ast {
346 0     0     my ($self) = @_;
347 0           return Muldis::DB::LOSE::Order->new({ 'v' => $self->{$ATTR_V} });
348             }
349              
350             ###########################################################################
351              
352             sub _equal {
353 0     0     my ($self, $other) = @_;
354 0           return $other->{$ATTR_V} eq $self->{$ATTR_V};
355             }
356              
357             ###########################################################################
358              
359             sub v {
360 0     0     my ($self) = @_;
361 0           return $self->{$ATTR_V};
362             }
363              
364             ###########################################################################
365              
366             } # class Muldis::DB::Engine::Example::PhysType::Order
367              
368             ###########################################################################
369             ###########################################################################
370              
371             { package Muldis::DB::Engine::Example::PhysType::Int; # class
372 1     1   17 use base 'Muldis::DB::Engine::Example::PhysType::Value';
  1         2  
  1         453  
373              
374 1     1   2423 use bigint; # this is experimental
  1         5035  
  1         6  
375              
376             my $ATTR_V = 'v';
377             # A p5 Scalar that is a Perl integer or BigInt or canonical string.
378              
379             my $ATTR_WHICH = 'which';
380              
381             ###########################################################################
382              
383             sub _build {
384 0     0     my ($self, $args) = @_;
385 0           my ($v) = @{$args}{'v'};
  0            
386 0           $self->{$ATTR_V} = $v;
387 0           return;
388             }
389              
390             ###########################################################################
391              
392             sub root_type {
393 0     0     return 'sys.Core.Int.Int';
394             }
395              
396             sub which {
397 0     0     my ($self) = @_;
398 0 0         if (!defined $self->{$ATTR_WHICH}) {
399 0           my $s = ''.$self->{$ATTR_V};
400 0           my $len_s = length $s;
401 0           $self->{$ATTR_WHICH} = "16 sys.Core.Int.Int $len_s $s";
402             }
403 0           return $self->{$ATTR_WHICH};
404             }
405              
406             ###########################################################################
407              
408             sub as_ast {
409 0     0     my ($self) = @_;
410 0           return Muldis::DB::LOSE::Int->new({ 'v' => $self->{$ATTR_V} });
411             }
412              
413             ###########################################################################
414              
415             sub _equal {
416 0     0     my ($self, $other) = @_;
417 0           return $other->{$ATTR_V} == $self->{$ATTR_V};
418             }
419              
420             ###########################################################################
421              
422             sub v {
423 0     0     my ($self) = @_;
424 0           return $self->{$ATTR_V};
425             }
426              
427             ###########################################################################
428              
429             } # class Muldis::DB::Engine::Example::PhysType::Int
430              
431             ###########################################################################
432             ###########################################################################
433              
434             { package Muldis::DB::Engine::Example::PhysType::Blob; # class
435 1     1   54945 use base 'Muldis::DB::Engine::Example::PhysType::Value';
  1         3  
  1         1187  
436              
437             my $ATTR_V = 'v';
438             # A p5 Scalar that is a byte-mode string; it has false utf8 flag.
439              
440             my $ATTR_WHICH = 'which';
441              
442             ###########################################################################
443              
444             sub _build {
445 0     0     my ($self, $args) = @_;
446 0           my ($v) = @{$args}{'v'};
  0            
447 0           $self->{$ATTR_V} = $v;
448 0           return;
449             }
450              
451             ###########################################################################
452              
453             sub root_type {
454 0     0     return 'sys.Core.Blob.Blob';
455             }
456              
457             sub which {
458 0     0     my ($self) = @_;
459 0 0         if (!defined $self->{$ATTR_WHICH}) {
460 0           my $s = $self->{$ATTR_V};
461 0           my $len_s = length $s;
462 0           $self->{$ATTR_WHICH} = "18 sys.Core.Blob.Blob $len_s $s";
463             }
464 0           return $self->{$ATTR_WHICH};
465             }
466              
467             ###########################################################################
468              
469             sub as_ast {
470 0     0     my ($self) = @_;
471 0           return Muldis::DB::LOSE::Blob->new({ 'v' => $self->{$ATTR_V} });
472             }
473              
474             ###########################################################################
475              
476             sub _equal {
477 0     0     my ($self, $other) = @_;
478 0           return $other->{$ATTR_V} eq $self->{$ATTR_V};
479             }
480              
481             ###########################################################################
482              
483             sub v {
484 0     0     my ($self) = @_;
485 0           return $self->{$ATTR_V};
486             }
487              
488             ###########################################################################
489              
490             } # class Muldis::DB::Engine::Example::PhysType::Blob
491              
492             ###########################################################################
493             ###########################################################################
494              
495             { package Muldis::DB::Engine::Example::PhysType::Text; # class
496 1     1   8 use base 'Muldis::DB::Engine::Example::PhysType::Value';
  1         2  
  1         885  
497              
498             my $ATTR_V = 'v';
499             # A p5 Scalar that is a text-mode string;
500             # it either has true utf8 flag or is only 7-bit bytes.
501              
502             my $ATTR_WHICH = 'which';
503              
504             ###########################################################################
505              
506             sub _build {
507 0     0     my ($self, $args) = @_;
508 0           my ($v) = @{$args}{'v'};
  0            
509 0           $self->{$ATTR_V} = $v;
510 0           return;
511             }
512              
513             ###########################################################################
514              
515             sub root_type {
516 0     0     return 'sys.Core.Text.Text';
517             }
518              
519             sub which {
520 0     0     my ($self) = @_;
521 0 0         if (!defined $self->{$ATTR_WHICH}) {
522 0           my $s = $self->{$ATTR_V};
523 0           my $len_s = length $s;
524 0           $self->{$ATTR_WHICH} = "18 sys.Core.Text.Text $len_s $s";
525             }
526 0           return $self->{$ATTR_WHICH};
527             }
528              
529             ###########################################################################
530              
531             sub as_ast {
532 0     0     my ($self) = @_;
533 0           return Muldis::DB::LOSE::Text->new({ 'v' => $self->{$ATTR_V} });
534             }
535              
536             ###########################################################################
537              
538             sub _equal {
539 0     0     my ($self, $other) = @_;
540 0           return $other->{$ATTR_V} eq $self->{$ATTR_V};
541             }
542              
543             ###########################################################################
544              
545             sub v {
546 0     0     my ($self) = @_;
547 0           return $self->{$ATTR_V};
548             }
549              
550             ###########################################################################
551              
552             } # class Muldis::DB::Engine::Example::PhysType::Text
553              
554             ###########################################################################
555             ###########################################################################
556              
557             { package Muldis::DB::Engine::Example::PhysType::_Tuple; # role
558 1     1   5 use base 'Muldis::DB::Engine::Example::PhysType::Value';
  1         2  
  1         366  
559              
560 1     1   5 use Carp;
  1         1  
  1         71  
561 1     1   6 use Scalar::Util qw(blessed);
  1         2  
  1         883  
562              
563             my $ATTR_HEADING = 'heading';
564             my $ATTR_BODY = 'body';
565              
566             my $ATTR_WHICH = 'which';
567              
568             ###########################################################################
569              
570             sub _build {
571 0     0     my ($self, $args) = @_;
572 0           my ($heading, $body) = @{$args}{'heading', 'body'};
  0            
573 0           $self->{$ATTR_HEADING} = $heading;
574 0           $self->{$ATTR_BODY} = $body;
575 0           return;
576             }
577              
578             ###########################################################################
579              
580             sub root_type {
581 0     0     my ($self) = @_;
582 0 0         my $unqltp = ($self->_allows_quasi() ? 'Quasi' : '') . 'Tuple';
583 0           return "sys.Core.$unqltp.$unqltp";
584             }
585              
586             sub which {
587 0     0     my ($self) = @_;
588 0 0         if (!defined $self->{$ATTR_WHICH}) {
589 0 0         my $unqltp = ($self->_allows_quasi() ? 'Quasi' : '') . 'Tuple';
590 0           my $root_type = "sys.Core.$unqltp.$unqltp";
591 0           my $tpwl = (length $root_type) . q{ } . $root_type;
592 0           my $s = 'H ' . $self->{$ATTR_HEADING}->which()
593             . ' B ' . $self->{$ATTR_BODY}->which();
594 0           my $len_s = length $s;
595 0           $self->{$ATTR_WHICH} = "$tpwl $len_s $s";
596             }
597 0           return $self->{$ATTR_WHICH};
598             }
599              
600             ###########################################################################
601              
602             sub as_ast {
603 0     0     my ($self) = @_;
604 0           my $call_args = { 'heading' => $self->{$ATTR_HEADING}->as_ast(),
605             'body' => $self->{$ATTR_BODY}->as_ast() };
606 0 0         return $self->_allows_quasi()
607             ? Muldis::DB::LOSE::QuasiTuple->new( $call_args ) : Muldis::DB::LOSE::Tuple->new( $call_args );
608             }
609              
610             ###########################################################################
611              
612             sub _equal {
613 0     0     my ($self, $other) = @_;
614 0   0       return ($self->{$ATTR_HEADING}->equal({
615             'other' => $other->{$ATTR_HEADING} })
616             and $self->{$ATTR_BODY}->equal({
617             'other' => $other->{$ATTR_BODY} }));
618             }
619              
620             ###########################################################################
621              
622             sub heading {
623 0     0     my ($self) = @_;
624 0           return $self->{$ATTR_HEADING};
625             }
626              
627             sub body {
628 0     0     my ($self) = @_;
629 0           return $self->{$ATTR_BODY};
630             }
631              
632             ###########################################################################
633              
634             sub attr_count {
635 0     0     my ($self) = @_;
636 0           return $self->{$ATTR_HEADING}->elem_count();
637             }
638              
639             sub attr_exists {
640 0     0     my ($self, $args) = @_;
641 0           my ($attr_name) = @{$args}{'attr_name'};
  0            
642 0           return $self->{$ATTR_HEADING}->elem_exists({
643             'elem_name' => $attr_name });
644             }
645              
646             sub attr_type {
647 0     0     my ($self, $args) = @_;
648 0           my ($attr_name) = @{$args}{'attr_name'};
  0            
649 0           return $self->{$ATTR_HEADING}->elem_value({
650             'elem_name' => $attr_name });
651             }
652              
653             sub attr_value {
654 0     0     my ($self, $args) = @_;
655 0           my ($attr_name) = @{$args}{'attr_name'};
  0            
656 0           return $self->{$ATTR_BODY}->elem_value({ 'elem_name' => $attr_name });
657             }
658              
659             ###########################################################################
660              
661             } # class Muldis::DB::Engine::Example::PhysType::_Tuple
662              
663             ###########################################################################
664             ###########################################################################
665              
666             { package Muldis::DB::Engine::Example::PhysType::Tuple; # class
667 1     1   6 use base 'Muldis::DB::Engine::Example::PhysType::_Tuple';
  1         2  
  1         447  
668 0     0     sub _allows_quasi { return $BOOL_FALSE; }
669             } # class Muldis::DB::Engine::Example::PhysType::Tuple
670              
671             ###########################################################################
672             ###########################################################################
673              
674             { package Muldis::DB::Engine::Example::PhysType::QuasiTuple; # class
675 1     1   5 use base 'Muldis::DB::Engine::Example::PhysType::_Tuple';
  1         2  
  1         372  
676 0     0     sub _allows_quasi { return $BOOL_TRUE; }
677             } # class Muldis::DB::Engine::Example::PhysType::QuasiTuple
678              
679             ###########################################################################
680             ###########################################################################
681              
682             { package Muldis::DB::Engine::Example::PhysType::_Relation; # role
683 1     1   4 use base 'Muldis::DB::Engine::Example::PhysType::Value';
  1         2  
  1         404  
684              
685 1     1   4 use Carp;
  1         2  
  1         53  
686 1     1   4 use Scalar::Util qw(blessed);
  1         1  
  1         947  
687              
688             my $ATTR_HEADING = 'heading';
689             my $ATTR_BODY = 'body';
690             my $ATTR_KEY_OVER_ALL = 'key_over_all';
691              
692             my $ATTR_WHICH = 'which';
693              
694             ###########################################################################
695              
696             sub _build {
697 0     0     my ($self, $args) = @_;
698 0           my ($heading, $body) = @{$args}{'heading', 'body'};
  0            
699              
700 0           my $key_over_all = {map { $_->which() => $_ } @{$body}}; # elim dup tpl
  0            
  0            
701              
702 0           $self->{$ATTR_HEADING} = $heading;
703 0           $self->{$ATTR_BODY} = [values %{$key_over_all}]; # no dup in b
  0            
704 0           $self->{$ATTR_KEY_OVER_ALL} = $key_over_all;
705              
706 0           return;
707             }
708              
709             ###########################################################################
710              
711             sub root_type {
712 0     0     my ($self) = @_;
713 0 0         my $unqltp = ($self->_allows_quasi() ? 'Quasi' : '') . 'Relation';
714 0           return "sys.Core.$unqltp.$unqltp";
715             }
716              
717             sub which {
718 0     0     my ($self) = @_;
719 0 0         if (!defined $self->{$ATTR_WHICH}) {
720 0 0         my $unqltp = ($self->_allows_quasi() ? 'Quasi' : '') . 'Relation';
721 0           my $root_type = "sys.Core.$unqltp.$unqltp";
722 0           my $tpwl = (length $root_type) . q{ } . $root_type;
723 0           my $s = 'H ' . $self->{$ATTR_HEADING}->which()
724 0           . ' B ' . (join ' ', sort keys %{$self->{$ATTR_KEY_OVER_ALL}});
725 0           my $len_s = length $s;
726 0           $self->{$ATTR_WHICH} = "$tpwl $len_s $s";
727             }
728 0           return $self->{$ATTR_WHICH};
729             }
730              
731             ###########################################################################
732              
733             sub as_ast {
734 0     0     my ($self) = @_;
735 0           my $call_args = { 'heading' => $self->{$ATTR_HEADING}->as_ast(),
736 0           'body' => [map { $_->as_ast() } @{$self->{$ATTR_BODY}}] };
  0            
737 0 0         return $self->_allows_quasi()
738             ? Muldis::DB::LOSE::QuasiRelation->new( $call_args ) : Muldis::DB::LOSE::Relation->new( $call_args );
739             }
740              
741             ###########################################################################
742              
743             sub _equal {
744 0     0     my ($self, $other) = @_;
745 0 0         return $BOOL_FALSE
746             if !$self->{$ATTR_HEADING}->equal({
747             'other' => $other->{$ATTR_HEADING} });
748 0           return $BOOL_FALSE
749 0 0         if @{$other->{$ATTR_BODY}} != @{$self->{$ATTR_BODY}};
  0            
750 0           my $v1 = $self->{$ATTR_KEY_OVER_ALL};
751 0           my $v2 = $other->{$ATTR_KEY_OVER_ALL};
752 0           for my $ek (keys %{$v1}) {
  0            
753 0 0         return $BOOL_FALSE
754             if !exists $v2->{$ek};
755             }
756 0           return $BOOL_TRUE;
757             }
758              
759             ###########################################################################
760              
761             sub heading {
762 0     0     my ($self) = @_;
763 0           return $self->{$ATTR_HEADING};
764             }
765              
766             sub body {
767 0     0     my ($self) = @_;
768 0           return $self->{$ATTR_BODY};
769             }
770              
771             ###########################################################################
772              
773             sub tuple_count {
774 0     0     my ($self) = @_;
775 0           return 0 + @{$self->{$ATTR_BODY}};
  0            
776             }
777              
778             ###########################################################################
779              
780             sub attr_count {
781 0     0     my ($self) = @_;
782 0           return $self->{$ATTR_HEADING}->elem_count();
783             }
784              
785             sub attr_exists {
786 0     0     my ($self, $args) = @_;
787 0           my ($attr_name) = @{$args}{'attr_name'};
  0            
788 0           return $self->{$ATTR_HEADING}->elem_exists({
789             'elem_name' => $attr_name });
790             }
791              
792             sub attr_type {
793 0     0     my ($self, $args) = @_;
794 0           my ($attr_name) = @{$args}{'attr_name'};
  0            
795 0           return $self->{$ATTR_HEADING}->elem_value({
796             'elem_name' => $attr_name });
797             }
798              
799             sub attr_values {
800 0     0     my ($self, $args) = @_;
801 0           my ($attr_name) = @{$args}{'attr_name'};
  0            
802 0           return [map {
803 0           $_->elem_value({ 'elem_name' => $attr_name })
804 0           } @{$self->{$ATTR_BODY}}];
805             }
806              
807             ###########################################################################
808              
809             } # class Muldis::DB::Engine::Example::PhysType::_Relation
810              
811             ###########################################################################
812             ###########################################################################
813              
814             { package Muldis::DB::Engine::Example::PhysType::Relation; # class
815 1     1   6 use base 'Muldis::DB::Engine::Example::PhysType::_Relation';
  1         2  
  1         597  
816 0     0     sub _allows_quasi { return $BOOL_FALSE; }
817             } # class Muldis::DB::Engine::Example::PhysType::Relation
818              
819             ###########################################################################
820             ###########################################################################
821              
822             { package Muldis::DB::Engine::Example::PhysType::QuasiRelation; # class
823 1     1   6 use base 'Muldis::DB::Engine::Example::PhysType::_Relation';
  1         2  
  1         587  
824 0     0     sub _allows_quasi { return $BOOL_TRUE; }
825             } # class Muldis::DB::Engine::Example::PhysType::QuasiRelation
826              
827             ###########################################################################
828             ###########################################################################
829              
830             { package Muldis::DB::Engine::Example::PhysType::_TypeInvo; # role
831 1     1   6 use base 'Muldis::DB::Engine::Example::PhysType::Value';
  1         2  
  1         556  
832              
833 1     1   6 use Carp;
  1         2  
  1         65  
834 1     1   5 use Scalar::Util qw(blessed);
  1         2  
  1         885  
835              
836             my $ATTR_KIND = 'kind';
837             my $ATTR_SPEC = 'spec';
838              
839             my $ATTR_WHICH = 'which';
840              
841             ###########################################################################
842              
843             sub _build {
844 0     0     my ($self, $args) = @_;
845 0           my ($kind, $spec) = @{$args}{'kind', 'spec'};
  0            
846 0           $self->{$ATTR_KIND} = $kind;
847 0           $self->{$ATTR_SPEC} = $spec;
848 0           return;
849             }
850              
851             ###########################################################################
852              
853             sub root_type {
854 0     0     my ($self) = @_;
855 0 0         return 'sys.LOSE._TypeInvo' . ($self->_allows_quasi() ? 'AQ' : 'NQ');
856             }
857              
858             sub which {
859 0     0     my ($self) = @_;
860 0 0         if (!defined $self->{$ATTR_WHICH}) {
861 0 0         my $tpwl = '20 sys.LOSE._TypeInvo'
862             . ($self->_allows_quasi() ? 'AQ' : 'NQ');
863 0           my $kind = $self->{$ATTR_KIND};
864 0           my $spec = $self->{$ATTR_SPEC};
865 0           my $sk = (length $kind) . q{ } . $kind;
866 0 0 0       my $ss = ($kind eq 'Any' or $kind eq 'Scalar')
867             ? (length $spec) . q{ } . $spec : $spec->which();
868 0           my $s = "KIND $sk SPEC $ss";
869 0           my $len_s = length $s;
870 0           $self->{$ATTR_WHICH} = "$tpwl $len_s $s";
871             }
872 0           return $self->{$ATTR_WHICH};
873             }
874              
875             ###########################################################################
876              
877             sub as_ast {
878 0     0     my ($self) = @_;
879 0           my $kind = $self->{$ATTR_KIND};
880 0           my $spec = $self->{$ATTR_SPEC};
881 0 0         my $call_args = { 'kind' => $kind,
    0          
882             'spec' => ($kind eq 'Any' ? $spec
883             : $kind eq 'Scalar' ? Muldis::DB::LOSE::EntityName->new({ 'text' => $spec })
884             : $spec->as_ast()) };
885 0 0         return $self->_allows_quasi()
886             ? Muldis::DB::LOSE::QuasiTypeInvo->new( $call_args ) : Muldis::DB::LOSE::TypeInvo->new( $call_args );
887             }
888              
889             ###########################################################################
890              
891             sub _equal {
892 0     0     my ($self, $other) = @_;
893 0           my $kind = $self->{$ATTR_KIND};
894 0           my $spec = $self->{$ATTR_SPEC};
895 0 0         return $BOOL_FALSE
896             if $other->{$ATTR_KIND} ne $kind;
897 0 0 0       return ($kind eq 'Any' or $kind eq 'Scalar')
898             ? $other->{$ATTR_SPEC} eq $spec
899             : $spec->equal({ 'other' => $other->{$ATTR_SPEC} });
900             }
901              
902             ###########################################################################
903              
904             sub kind {
905 0     0     my ($self) = @_;
906 0           return $self->{$ATTR_KIND};
907             }
908              
909             sub spec {
910 0     0     my ($self) = @_;
911 0           return $self->{$ATTR_SPEC};
912             }
913              
914             ###########################################################################
915              
916             } # role Muldis::DB::Engine::Example::PhysType::_TypeInvo
917              
918             ###########################################################################
919             ###########################################################################
920              
921             { package Muldis::DB::Engine::Example::PhysType::TypeInvo; # class
922 1     1   7 use base 'Muldis::DB::Engine::Example::PhysType::_TypeInvo';
  1         3  
  1         831  
923 0     0     sub _allows_quasi { return $BOOL_FALSE; }
924             } # class Muldis::DB::Engine::Example::PhysType::TypeInvo
925              
926             ###########################################################################
927             ###########################################################################
928              
929             { package Muldis::DB::Engine::Example::PhysType::QuasiTypeInvo; # class
930 1     1   8 use base 'Muldis::DB::Engine::Example::PhysType::_TypeInvo';
  1         2  
  1         488  
931 0     0     sub _allows_quasi { return $BOOL_TRUE; }
932             } # class Muldis::DB::Engine::Example::PhysType::QuasiTypeInvo
933              
934             ###########################################################################
935             ###########################################################################
936              
937             { package Muldis::DB::Engine::Example::PhysType::_TypeDict; # role
938 1     1   14 use base 'Muldis::DB::Engine::Example::PhysType::Value';
  1         2  
  1         499  
939              
940 1     1   6 use Carp;
  1         2  
  1         68  
941 1     1   8 use Scalar::Util qw(blessed);
  1         1  
  1         929  
942              
943             my $ATTR_MAP = 'map';
944             # A p5 Hash with 0..N elements:
945             # Each Hash key is a p5 text-mode string; an attr name.
946             # Each Hash value is a TypeInvo; an attr declared type.
947              
948             my $ATTR_WHICH = 'which';
949              
950             ###########################################################################
951              
952             sub _build {
953 0     0     my ($self, $args) = @_;
954 0           my ($map) = @{$args}{'map'};
  0            
955 0           $self->{$ATTR_MAP} = $map;
956 0           return;
957             }
958              
959             ###########################################################################
960              
961             sub root_type {
962 0     0     my ($self) = @_;
963 0 0         return 'sys.LOSE._TypeDict' . ($self->_allows_quasi() ? 'AQ' : 'NQ');
964             }
965              
966             sub which {
967 0     0     my ($self) = @_;
968 0 0         if (!defined $self->{$ATTR_WHICH}) {
969 0 0         my $tpwl = '20 sys.LOSE._TypeDict'
970             . ($self->_allows_quasi() ? 'AQ' : 'NQ');
971 0           my $map = $self->{$ATTR_MAP};
972 0           my $s = join q{ }, map {
973 0           my $mk = (length $_) . q{ } . $_;
974 0           my $mv = $map->{$_}->which();
975 0           "K $mk V $mv";
976 0           } sort keys %{$map};
977 0           my $len_s = length $s;
978 0           $self->{$ATTR_WHICH} = "$tpwl $len_s $s";
979             }
980 0           return $self->{$ATTR_WHICH};
981             }
982              
983             ###########################################################################
984              
985             sub as_ast {
986 0     0     my ($self) = @_;
987 0           my $map = $self->{$ATTR_MAP};
988 0           my $call_args = { 'map' => [map {
989 0           [Muldis::DB::LOSE::EntityName->new({ 'text' => $_ }), $map->{$_}->as_ast()],
990 0           } keys %{$map}] };
991 0 0         return $self->_allows_quasi()
992             ? Muldis::DB::LOSE::QuasiTypeDict->new( $call_args ) : Muldis::DB::LOSE::TypeDict->new( $call_args );
993             }
994              
995             ###########################################################################
996              
997             sub _equal {
998 0     0     my ($self, $other) = @_;
999 0           my $v1 = $self->{$ATTR_MAP};
1000 0           my $v2 = $other->{$ATTR_MAP};
1001 0           return $BOOL_FALSE
1002 0 0         if keys %{$v2} != keys %{$v1};
  0            
1003 0           for my $ek (keys %{$v1}) {
  0            
1004 0 0         return $BOOL_FALSE
1005             if !exists $v2->{$ek};
1006 0 0         return $BOOL_FALSE
1007             if !$v1->{$ek}->equal({ 'other' => $v2->{$ek} });
1008             }
1009 0           return $BOOL_TRUE;
1010             }
1011              
1012             ###########################################################################
1013              
1014             sub map {
1015 0     0     my ($self) = @_;
1016 0           return $self->{$ATTR_MAP};
1017             }
1018              
1019             ###########################################################################
1020              
1021             sub elem_count {
1022 0     0     my ($self) = @_;
1023 0           return 0 + keys %{$self->{$ATTR_MAP}};
  0            
1024             }
1025              
1026             sub elem_exists {
1027 0     0     my ($self, $args) = @_;
1028 0           my ($elem_name) = @{$args}{'elem_name'};
  0            
1029 0           return exists $self->{$ATTR_MAP}->{$elem_name};
1030             }
1031              
1032             sub elem_value {
1033 0     0     my ($self, $args) = @_;
1034 0           my ($elem_name) = @{$args}{'elem_name'};
  0            
1035 0           return $self->{$ATTR_MAP}->{$elem_name};
1036             }
1037              
1038             ###########################################################################
1039              
1040             } # role Muldis::DB::Engine::Example::PhysType::_TypeDict
1041              
1042             ###########################################################################
1043             ###########################################################################
1044              
1045             { package Muldis::DB::Engine::Example::PhysType::TypeDict; # class
1046 1     1   7 use base 'Muldis::DB::Engine::Example::PhysType::_TypeDict';
  1         2  
  1         613  
1047 0     0     sub _allows_quasi { return $BOOL_FALSE; }
1048             } # class Muldis::DB::Engine::Example::PhysType::TypeDict
1049              
1050             ###########################################################################
1051             ###########################################################################
1052              
1053             { package Muldis::DB::Engine::Example::PhysType::QuasiTypeDict; # class
1054 1     1   6 use base 'Muldis::DB::Engine::Example::PhysType::_TypeDict';
  1         2  
  1         447  
1055 0     0     sub _allows_quasi { return $BOOL_TRUE; }
1056             } # class Muldis::DB::Engine::Example::PhysType::QuasiTypeDict
1057              
1058             ###########################################################################
1059             ###########################################################################
1060              
1061             { package Muldis::DB::Engine::Example::PhysType::_ValueDict; # role
1062 1     1   13 use base 'Muldis::DB::Engine::Example::PhysType::Value';
  1         3  
  1         438  
1063              
1064 1     1   5 use Carp;
  1         2  
  1         69  
1065 1     1   6 use Scalar::Util qw(blessed);
  1         2  
  1         1037  
1066              
1067             my $ATTR_MAP = 'map';
1068              
1069             my $ATTR_WHICH = 'which';
1070              
1071             ###########################################################################
1072              
1073             sub _build {
1074 0     0     my ($self, $args) = @_;
1075 0           my ($map) = @{$args}{'map'};
  0            
1076 0           $self->{$ATTR_MAP} = $map;
1077 0           return;
1078             }
1079              
1080             ###########################################################################
1081              
1082             sub root_type {
1083 0     0     my ($self) = @_;
1084 0 0         return 'sys.LOSE._ValueDict' . ($self->_allows_quasi() ? 'AQ' : 'NQ');
1085             }
1086              
1087             sub which {
1088 0     0     my ($self) = @_;
1089 0 0         if (!defined $self->{$ATTR_WHICH}) {
1090 0 0         my $tpwl = '20 sys.LOSE._ValueDict'
1091             . ($self->_allows_quasi() ? 'AQ' : 'NQ');
1092 0           my $map = $self->{$ATTR_MAP};
1093 0           my $s = join q{ }, map {
1094 0           my $mk = (length $_) . q{ } . $_;
1095 0           my $mv = $map->{$_}->which();
1096 0           "K $mk V $mv";
1097 0           } sort keys %{$map};
1098 0           my $len_s = length $s;
1099 0           $self->{$ATTR_WHICH} = "$tpwl $len_s $s";
1100             }
1101 0           return $self->{$ATTR_WHICH};
1102             }
1103              
1104             ###########################################################################
1105              
1106             sub as_ast {
1107 0     0     my ($self) = @_;
1108 0           my $map = $self->{$ATTR_MAP};
1109 0           return Muldis::DB::LOSE::_ExprDict->new({ 'map' => [map {
1110 0           [Muldis::DB::LOSE::EntityName->new({ 'text' => $_ }), $map->{$_}->as_ast()],
1111 0           } keys %{$map}] });
1112             }
1113              
1114             ###########################################################################
1115              
1116             sub _equal {
1117 0     0     my ($self, $other) = @_;
1118 0           my $v1 = $self->{$ATTR_MAP};
1119 0           my $v2 = $other->{$ATTR_MAP};
1120 0           return $BOOL_FALSE
1121 0 0         if keys %{$v2} != keys %{$v1};
  0            
1122 0           for my $ek (keys %{$v1}) {
  0            
1123 0 0         return $BOOL_FALSE
1124             if !exists $v2->{$ek};
1125 0 0         return $BOOL_FALSE
1126             if !$v1->{$ek}->equal({ 'other' => $v2->{$ek} });
1127             }
1128 0           return $BOOL_TRUE;
1129             }
1130              
1131             ###########################################################################
1132              
1133             sub map {
1134 0     0     my ($self) = @_;
1135 0           return $self->{$ATTR_MAP};
1136             }
1137              
1138             ###########################################################################
1139              
1140             sub elem_count {
1141 0     0     my ($self) = @_;
1142 0           return 0 + keys %{$self->{$ATTR_MAP}};
  0            
1143             }
1144              
1145             sub elem_exists {
1146 0     0     my ($self, $args) = @_;
1147 0           my ($elem_name) = @{$args}{'elem_name'};
  0            
1148 0           return exists $self->{$ATTR_MAP}->{$elem_name};
1149             }
1150              
1151             sub elem_value {
1152 0     0     my ($self, $args) = @_;
1153 0           my ($elem_name) = @{$args}{'elem_name'};
  0            
1154 0           return $self->{$ATTR_MAP}->{$elem_name};
1155             }
1156              
1157             ###########################################################################
1158              
1159             } # role Muldis::DB::Engine::Example::PhysType::_ValueDict
1160              
1161             ###########################################################################
1162             ###########################################################################
1163              
1164             { package Muldis::DB::Engine::Example::PhysType::ValueDict; # class
1165 1     1   7 use base 'Muldis::DB::Engine::Example::PhysType::_ValueDict';
  1         2  
  1         592  
1166 0     0     sub _allows_quasi { return $BOOL_FALSE; }
1167             } # class Muldis::DB::Engine::Example::PhysType::ValueDict
1168              
1169             ###########################################################################
1170             ###########################################################################
1171              
1172             { package Muldis::DB::Engine::Example::PhysType::QuasiValueDict; # class
1173 1     1   7 use base 'Muldis::DB::Engine::Example::PhysType::_ValueDict';
  1         2  
  1         464  
1174 0     0     sub _allows_quasi { return $BOOL_TRUE; }
1175             } # class Muldis::DB::Engine::Example::PhysType::QuasiValueDict
1176              
1177             ###########################################################################
1178             ###########################################################################
1179              
1180             1; # Magic true value required at end of a reusable file's code.
1181             __END__