Browse Source

save, set and get

mpn
theMage 7 years ago
parent
commit
a6dcb0fdcc
2 changed files with 201 additions and 5 deletions
  1. 46 2
      Shard-MySQL/lib/Shard/MySQL.pm
  2. 155 3
      Shard-MySQL/lib/Shard/MySQL/SQL.pm

+ 46 - 2
Shard-MySQL/lib/Shard/MySQL.pm

@ -49,12 +49,16 @@ sub inserts {
49 49
50 50
	my $table = $opts->{table} || $class->table();
51 51
52
	my $id	= 0;
52 53
	my %redone = ();
53 54
	SHARD:
54 55
	for my $shard (keys %sharded) {
55 56
		my $dbh = $class->get_dbh_for($shard, 'rw');
56 57
		eval {
57
			$class->SUPER::inserts($fields, [@{ $sharded{$shard} }] , $upflds,
58
			$id = $class->SUPER::inserts(
59
					$fields,
60
					[@{ $sharded{$shard} }] ,
61
					$upflds,
58 62
					{ %$opts, table=>$table, dbh=>$dbh, shard => $shard }
59 63
				);
60 64
			1;
@ -73,12 +77,28 @@ sub inserts {
73 77
	}
74 78
75 79
	Shard::MySQL::Index->index($class, $fields, $recs);
80
81
	return $id;
76 82
}
77 83
78 84
sub retrieve {
79
	my ($class, $search, $opts) = @_;
85
	my $class = shift;
86
87
	return $class->SUPER::retrieve(@_)
88
		unless $class->can('sharded') and $class->sharded;
89
90
	my ($search, $opts);
91
	if (ref $_[0]) {
92
		($search, $opts) = @_;
93
	} else {
94
		if (ref $_[-1] and !($#_ % 2)) {
95
			$opts = pop @_;
96
			$search = {@_};
97
		}
98
	}
80 99
	$opts ||= {};
81 100
	
101
82 102
	croak "What do you want to retrieve??"
83 103
		unless ref $search and keys %$search;
84 104
@ -125,6 +145,30 @@ sub retrieve {
125 145
	}
126 146
}
127 147
148
sub save {
149
	my $self = shift;
150
151
	croak "Use save on objects, not classes" unless ref $self;
152
153
	return $self->SUPER::save(@_)
154
		unless $self->can('sharded') and $self->sharded;
155
156
	$self->{__saving_sharded} = 1;
157
	
158
	croak "Sharded save not done yet";
159
160
	$self->{__saving_sharded} = 0;
161
	$self->_save_done;
162
}
163
164
sub _save_done {
165
	my $self = shift;
166
167
	return if $self->{__saving_sharded};
168
169
	$self->SUPER::_save_done;
170
}
171
128 172
sub shard_data {
129 173
	my ($class, $fields, $recs) = @_;
130 174

+ 155 - 3
Shard-MySQL/lib/Shard/MySQL/SQL.pm

@ -9,6 +9,30 @@ use SQL::Abstract;
9 9
10 10
use Shard::MySQL::Sequence;
11 11
12
sub new {
13
	my $class = shift;
14
15
	my $self = {};
16
	if ($#_ == 0 and ref $_{0}) {
17
		%$self = %{$_[0]};
18
	} else {
19
		$self = { @_ };
20
	}
21
22
	bless $self, $class;
23
24
	$self->_init();
25
26
	return $self;
27
}
28
29
sub _init {
30
	my $self = shift;
31
32
	$self->init()
33
		if $self->can('init');
34
}
35
12 36
sub inserts {
13 37
	my ($class, $fields, $recs, $upflds, $opts) = @_;
14 38
@ -29,7 +53,8 @@ EoE
29 53
30 54
	$fields = join ',', @$fields if ref $fields eq 'ARRAY';
31 55
	my $preq = "INSERT ";
32
	$preq .= "IGNORE " if !ref $upflds and $upflds=~m{\s*ignore\s*}i;
56
	$preq .= "IGNORE " if $upflds
57
				and !ref $upflds and $upflds=~m{\s*ignore\s*}i;
33 58
	$preq .= "INTO $table ($fields) VALUES";
34 59
	
35 60
	my $posq = '';
@ -50,6 +75,7 @@ EoE
50 75
51 76
	my $vals = '';
52 77
	my $vcnt = 0;
78
	my $cnt = scalar @$recs;
53 79
	while (1) {
54 80
		my $rec;
55 81
		if (ref $recs eq 'ARRAY') {
@ -75,6 +101,7 @@ EoE
75 101
76 102
		if ( (!$rec and $vcnt) or ++$vcnt >= $atatime) {
77 103
			my $query = $preq.$vals.$posq;
104
			print STDERR "Query: $query\n\n";
78 105
			$dbh->do( $query );
79 106
			$vals = '';
80 107
			$vcnt	= 0;
@ -82,10 +109,28 @@ EoE
82 109
83 110
		last if !$rec;
84 111
	}
112
113
	my $id = $dbh->last_insert_id(undef,undef, undef, undef);
114
115
	print STDERR "id: $id\n";
116
117
	return $id;
118
# 		if $cnt and defined wantarray;
85 119
}
86 120
87 121
sub retrieve {
88
	my ($class, $search, $opts) = @_;
122
	my $class = shift;
123
124
	my ($search, $opts);
125
	if (ref $_[0]) {
126
		($search, $opts) = @_;
127
	} else {
128
		if (ref $_[-1] and !($#_ % 2)) {
129
			$opts = pop @_;
130
			$search = {@_};
131
		}
132
	}
133
	$opts ||= {};
89 134
90 135
	my $table = $opts->{table};
91 136
	my $dbh		= $opts->{dbh};
@ -112,11 +157,20 @@ EoE
112 157
	my ($stmt,@bind) = $sql->select($table, \@fields, $search);
113 158
	$stmt .= ' LIMIT 1';
114 159
160
	print STDERR "query: $stmt\n\n";
161
115 162
	my $rec = $dbh->selectrow_hashref( $stmt, {}, @bind );
116
	
163
	$rec->{__loaded} = 1;
164
165
	bless $rec, $class if $rec;
166
117 167
	return $rec;
118 168
}
119 169
170
sub full_retrieve {
171
	croak "TODO: Full retrieve not implemented yet!";
172
}
173
120 174
sub add_sequences {
121 175
	my $class = shift;
122 176
	my ($fields,$recs) = @_;
@ -175,6 +229,104 @@ sub execute {
175 229
	return;
176 230
}
177 231
232
my %control = map { $_ => 1 } qw(
233
		__fully_loaded
234
		__loaded
235
		__new_rec
236
		__new_saved
237
		__set
238
	);
239
sub set {
240
	my $self = shift;
241
	croak "Use set on objects, not classes" unless ref $self;
242
243
	my %sets = @_;
244
245
	for my $k (keys %sets) {
246
		next if $control{$k}; # we never set control members externally
247
		if ( $k!~m{^_} and !exists $self->{$k} and !$self->{__fully_loaded}) {
248
			$self->full_retrieve;
249
		}
250
		$self->{$k} = $sets{$k};
251
		$self->{__set}->{$k} = 1
252
			unless $k=~m{^_};
253
			#we don't keep track of _fields - they are temporary
254
	}
255
	return;
256
}
257
258
sub get {
259
	my $self = shift;
260
	croak "Use get on objects, not classes" unless ref $self;
261
262
	return $self->{ $_[0] } if $#_ == 0;
263
264
	my %res = ();
265
	for my $k (@_) {
266
		$res{ $k } = $self->{$k};
267
	}
268
269
	return wantarray ? %res : { %res };
270
}
271
272
sub save {
273
	my ($self,$opts) = @_;
274
275
	croak "Use save on objects, not classes" unless ref $self;
276
277
	croak <<EoE if $self->{__new_saved};
278
You need to recreate this object
279
	save of new objects only allowed once at this time
280
EoE
281
282
	unless ($self->{__loaded}) { # rec created with new - needs inserted
283
		my @fields = grep { exists $self->{ $_ } } $self->fields;
284
		my @vals = map { $self->{ $_ } } @fields;
285
		$self->inserts( \@fields, [\@vals] );
286
		$self->{__new_saved} = 1;
287
		return;
288
	}
289
290
	my $table = $opts->{table};
291
	my $dbh		= $opts->{dbh};
292
	unless ($table and $dbh) {
293
		croak <<EoE if $self->can('sharded') and $self->sharded();
294
Your sharded class should descend of Shard::MySQL, not Shard::MySQL::SQL.
295
I don't know how to insert records on sharded tables.
296
EoE
297
298
		$table 	= $self->table unless $table;
299
		$dbh		= $self->get_dbh('rw') unless $dbh;
300
	}
301
	
302
	my %sets = map {
303
			$_ => $self->{$_}
304
		} keys %{$self->{__set} || {}};
305
306
	my %where = map {
307
			$_ => $self->{$_}
308
		} $self->primary;
309
310
	my $sql = SQL::Abstract->new;
311
	my ($stmt, @bind) = $sql->update($table, \%sets, \%where);
312
313
	if (my $sth = $dbh->prepare($stmt)) {
314
		$sth->execute(@bind);
315
	}
316
317
	$self->_save_done;
318
}
319
320
sub _save_done {
321
	my $self = shift;
322
	$self->{__set} = {};
323
324
	$self->save_done
325
		if $self->can('save_done');
326
327
	return;
328
}
329
178 330
1;
179 331
180 332
__END__