Commit | Line | Data |
65b76960 |
1 | package DBIx::Data::Collection::Set; |
2 | |
3 | use Moose; |
4 | use Method::Signatures::Simple; |
5 | use Data::Perl::Stream::Array; |
6 | |
7 | has _store => (is => 'ro', required => 1, init_arg => 'store'); |
8 | |
65b76960 |
9 | has _class => (is => 'ro', predicate => '_has_class'); |
10 | |
3a2e7c1c |
11 | has _set_over => (is => 'ro', required => 1, init_arg => 'set_over'); |
12 | |
13 | ## member cache (all members) |
14 | |
15 | has _member_cache => ( |
16 | is => 'rw', lazy_build => 1, |
17 | predicate => '_member_cache_built', |
18 | ); |
65b76960 |
19 | |
20 | method _build__member_cache { |
21 | my $stream = $self->_new_raw_stream; |
22 | my @cache; |
23 | while (my ($raw) = $stream->next) { |
3a2e7c1c |
24 | my $obj = do { |
25 | if (my ($obj) = $self->_key_cache_get_raw($raw)) { |
26 | $self->_merge($obj, $raw) |
27 | } else { |
de9534fa |
28 | $self->_add_to_key_cache($self->_inflate($raw)) |
3a2e7c1c |
29 | } |
30 | }; |
31 | push @cache, $obj; |
65b76960 |
32 | } |
de9534fa |
33 | \@cache |
65b76960 |
34 | } |
35 | |
3a2e7c1c |
36 | method _add_to_member_cache ($to_add) { |
37 | return unless $self->_member_cache_built; |
38 | push @{$self->_member_cache}, $to_add; |
de9534fa |
39 | $to_add |
3a2e7c1c |
40 | } |
41 | |
42 | ## key cache - by primary/unique key |
43 | |
44 | has _key_cache => (is => 'ro', default => sub { {} }); |
45 | |
46 | method _add_to_key_cache ($to_add) { |
47 | $self->_key_cache->{$self->_object_to_id($to_add)} = $to_add; |
de9534fa |
48 | $to_add |
3a2e7c1c |
49 | } |
50 | |
51 | method _key_cache_has_raw ($raw) { |
52 | exists $self->_key_cache->{$self->_raw_to_id($raw)} |
53 | } |
54 | |
55 | method _key_cache_has_object ($obj) { |
56 | exists $self->_key_cache->{$self->_object_to_id($obj)} |
57 | } |
58 | |
59 | method _key_cache_get_raw ($raw) { |
60 | my $id = $self->_raw_to_id($raw); |
61 | exists $self->_key_cache->{$id} |
62 | ? ($self->_key_cache->{$id}) |
63 | : () |
64 | } |
65 | |
66 | method _key_cache_get_object ($obj) { |
67 | $self->_key_cache_get_raw($self->_deflate($obj)) |
68 | } |
69 | |
70 | ## loading data |
71 | |
65b76960 |
72 | method _new_raw_stream { |
73 | $self->_store->new_select_command([])->execute; |
74 | } |
75 | |
3a2e7c1c |
76 | ## thunking between the store representation and the set representation |
77 | # |
78 | # _inflate is raw data -> final repr |
79 | # _deflate is final repr -> raw data |
80 | # _merge takes final repr + raw data and updates the repr |
81 | # (this is used for pk-generated values and later lazy loading) |
82 | |
65b76960 |
83 | method _inflate ($raw) { |
3347c67e |
84 | bless($raw, $self->_class) if $self->_has_class; |
85 | $raw; |
65b76960 |
86 | } |
87 | |
3a2e7c1c |
88 | method _deflate ($obj) { |
89 | +{ %$obj } |
90 | } |
91 | |
92 | method _merge ($obj, $raw) { |
93 | @{$obj}{keys %$raw} = values %$raw; |
94 | $obj; |
95 | } |
96 | |
97 | ## methods to get ids |
98 | |
99 | method _raw_to_id ($raw) { |
100 | # XXX must escape this. or do something else. |
101 | join ';', map $raw->{$_}, @{$self->_set_over} |
102 | } |
103 | |
104 | method _object_to_id ($obj) { |
105 | $self->_raw_to_id($self->_deflate($obj)); |
106 | } |
107 | |
65b76960 |
108 | method flatten { |
109 | @{$self->_member_cache}; |
110 | } |
111 | |
112 | method as_stream { |
113 | Data::Perl::Stream::Array->new(array => $self->_member_cache); |
114 | } |
115 | |
3a2e7c1c |
116 | method add ($new) { |
117 | $self->_add_to_store($new); |
118 | $self->_add_to_caches($new); |
119 | $new; |
120 | } |
121 | |
122 | method _add_to_store ($new) { |
123 | my $new_raw = $self->_deflate($new); |
124 | $self->_merge($new, $self->_store->new_insert_command($new_raw)->execute); |
de9534fa |
125 | $new; |
3a2e7c1c |
126 | } |
127 | |
128 | method _add_to_caches ($new) { |
129 | $self->_add_to_member_cache($new); |
130 | $self->_add_to_key_cache($new); |
de9534fa |
131 | $new |
3a2e7c1c |
132 | } |
133 | |
65b76960 |
134 | 1; |