Author: spadkins
Date: Wed Mar 4 21:08:58 2009
New Revision: 12569
Modified:
p5ee/trunk/App-Repository/lib/App/Repository.pm
p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm
p5ee/trunk/App-Repository/lib/App/Repository/MySQL.pm
p5ee/trunk/App-Repository/t/DBI-insert-ora.t
p5ee/trunk/App-Repository/t/DBI-insert.t
p5ee/trunk/App-Repository/t/RepositoryTestUtils.pm
p5ee/trunk/App-Repository/t/files/DBI-import.01.dat
Log:
fix the insert/update for Oracle
Modified: p5ee/trunk/App-Repository/lib/App/Repository.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/Repository.pm (original)
+++ p5ee/trunk/App-Repository/lib/App/Repository.pm Wed Mar 4 21:08:58 2009
@@ -29,44 +29,31 @@
$repository = $context->service("Repository"); # or ...
$repository = $context->repository();
- $rep = Repository::Base->new(); # looks for %ENV, then config file
- $rep = Repository::Base->new("sysdb"); # looks for %ENV, then config file
using "sysdb"
- $rep2 = $rep->new(); # copies attributes of
existing $rep
- $rep = Repository::Base->new(@positional_args); # undefined for
Repository::Base
- $config = {
- 'repository' => {
- 'db' => {
- 'arg1' => 'value1',
- 'arg2' => 'value2',
- },
- 'rep2' => {
- 'arg1' => 'value1',
- 'arg2' => 'value2',
- },
- },
- };
- $rep = Repository::Base->new($config);
- $rep = Repository::Base->new("rep2",$config);
-
###################################################################
- # The following methods are needed for SQL support
+ # Connection State
###################################################################
$errmsg = $rep->error(); # returns the error string for prev op (""
if no error)
$numrows = $rep->numrows(); # returns the number of rows affected by
prev op
print $rep->error(), "\n";
+ ###################################################################
# DATA TYPE HELPER METHODS
+ ###################################################################
$repdate = $rep->format_repdate($date_string); # free-form date string
as entered by a person
+ ###################################################################
# META-DATA: (about the tables)
- $rep->_load_rep_metadata();
- $rep->_load_table_metadata($tablename);
+ ###################################################################
+ $rep->_load_rep_metadata(); # called
automatically, loads metadata
+ $rep->_load_table_metadata($tablename); # called
automatically, loads metadata
+
$typenames = $rep->get_type_names(); # print
"@$typenames\n";
$typelabels = $rep->get_type_labels(); # print
"%$typelabels\n";
$typedef = $rep->get_type_def($typename); # print
"%$type\n";
$tablenames = $rep->get_table_names(); # print
"@$tablenames\n";
$tablelabels = $rep->get_table_labels(); # print
"%$tablelabels\n";
+
$table_def = $rep->get_table_def($tablename); # print
"%$table\n";
$columnnames = $rep->get_column_names($tablename); # print
"@$columnnames\n";
$columnlabels = $rep->get_column_labels($tablename); # print
"%$columnlabels\n";
@@ -89,7 +76,7 @@
# OBJECT-ORIENTED
$class = $table;
- $obj = $rep->object($class, $key);
+ $obj = $rep->get_object($class, $key);
# OBJECT-ORIENTED (on RepositoryObject)
$relation_names = $obj->get_relation_names();
@@ -101,8 +88,14 @@
# TECHNICAL
#################################################
+ $rep->begin_work();
$rep->commit();
$rep->rollback();
+
+ #################################################
+ # DATA IMPORT/EXPORT
+ #################################################
+
$rep->import_rows($table, $columns, $file, $options);
$rep->export_rows($table, $columns, $file, $options);
@@ -114,17 +107,15 @@
retrieved from somewhere without
knowing what underlying technology is storing the data.
-A Repository is the central persistence concept within the App.
-A Repository does not present a uniquely object-oriented view of
-its data. Rather it presents a "logical relational" data model.
+A Repository is the central persistence concept within the App-Context
framework.
+A Repository does not present a uniquely object-oriented view of its data.
+Rather it presents a "logical relational" data model.
It does not return objects, but rows of data.
The "logical data model" means that a developer can program to
the data model which usually comes out of system requirements analysis,
-closely modelling the business. All of the changes to this
-logical data model that are
-incorporated during physical database design are abstracted
-away, such as:
+closely modelling the business. All of the changes to this logical data model
that are
+incorporated during physical database design are abstracted away, such as:
* physical table naming,
* physical column naming,
Modified: p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm (original)
+++ p5ee/trunk/App-Repository/lib/App/Repository/DBI.pm Wed Mar 4 21:08:58 2009
@@ -1974,7 +1974,7 @@
$self->{error} = "";
my $dbh = $self->{dbh};
- my $retval = 0;
+ my $nrows = 0;
my ($hashcols, $hashrow, $ref);
$ref = ref($cols);
@@ -2060,10 +2060,10 @@
#print STDERR "insert_sth->bind_param_inout(", $#$cols+2, ",
\$last_inserted_id, 20, $sqltype) [$last_inserted_id_column] AFTER\n";
}
#print STDERR "BEFORE execute: last_inserted_id=[$last_inserted_id]\n";
- $retval = $insert_sth->execute;
+ $nrows = $insert_sth->execute;
#print STDERR "AFTER execute: last_inserted_id=[$last_inserted_id]\n";
- $retval = 0 if ($retval == 0); # turn "0E0" into plain old "0"
- if ($is_last_inserted_id_returned_from_insert && $retval) {
+ $nrows = 0 if ($nrows == 0); # turn "0E0" into plain old "0"
+ if ($is_last_inserted_id_returned_from_insert && $nrows) {
$self->{last_inserted_id} = $last_inserted_id;
}
};
@@ -2079,8 +2079,8 @@
else {
$key_idx = $self->_key_idx($table, $cols);
}
- $retval = $self->_update($table, $key_idx, $cols, $row);
- if (!$retval) {
+ $nrows = $self->_update($table, $key_idx, $cols, $row);
+ if (!$nrows) {
$loglevel = 3;
$bind_values = join("|", map { defined $_ ? $_ :
"undef" } @$row);
$self->{context}->log({level=>$loglevel},
"App-Repository Exception in _insert_row(): update failed to find row after
failed insert\nBIND VALUES: [$bind_values]\nSQL: $sql");
@@ -2096,14 +2096,15 @@
}
}
}
+ $nrows = 1 if ($nrows);
if ($debug_sql) {
$elapsed_time = $self->_read_timer($timer);
- print $App::DEBUG_FILE "DEBUG_SQL: retval [$retval] ($elapsed_time
sec) $DBI::errstr\n";
+ print $App::DEBUG_FILE "DEBUG_SQL: nrows [$nrows] ($elapsed_time sec)
$DBI::errstr\n";
print $App::DEBUG_FILE "\n";
}
- &App::sub_exit($retval) if ($App::trace);
- $retval;
+ &App::sub_exit($nrows) if ($App::trace);
+ $nrows;
}
# $nrows = $rep->_insert_rows ($table, \...@cols, \...@rows);
@@ -3193,41 +3194,56 @@
# $pk_idx = $rep->_key_idx($table, \...@cols, \...@key_cols);
sub _key_idx {
&App::sub_entry if ($App::trace);
- my $self = shift;
- my ($table, $cols, $key_cols) = @_;
+ my ($self, $table, $cols, $key_cols) = @_;
+ my $table_def = $self->get_table_def($table);
- if (!$key_cols) {
- $key_cols = $self->{table}{$table}{primary_key} || [];
- my $alternate_key = $self->{table}{$table}{alternate_key};
- if ($alternate_key && $#$alternate_key > -1) {
- foreach my $ak (@$alternate_key) {
- push(@$key_cols, @$ak);
- }
- }
+ my (@possible_keys);
+ if ($key_cols) {
+ @possible_keys = ( $key_cols );
}
-
- my $key_idx = [];
- if ($#$key_cols == 0) {
- my $key_column = $key_cols->[0];
- for (my $i = 0; $i <= $#$cols; $i++) {
- if ($cols->[$i] eq $key_column) {
- $key_idx = [ $i ];
- last;
+ else {
+ my $primary_key = $table_def->{primary_key};
+ my $alternate_key = $table_def->{alternate_key};
+ push(@possible_keys, $primary_key) if ($primary_key);
+ push(@possible_keys, @$alternate_key) if ($alternate_key);
+ }
+ my ($key_idx, $colidx);
+ foreach $key_cols (@possible_keys) {
+ my (@key_idx);
+ if ($#$key_cols == 0) {
+ my $key_column = $key_cols->[0];
+ for (my $i = 0; $i <= $#$cols; $i++) {
+ if ($cols->[$i] eq $key_column) {
+ $key_idx = [ $i ];
+ last;
+ }
}
}
- }
- else {
- my (%colidx, $key_column);
- for (my $i = 0; $i <= $#$cols; $i++) {
- $colidx{$cols->[$i]} = $i;
- }
- for (my $i = 0; $i <= $#$key_cols; $i++) {
- $key_column = $key_cols->[$i];
- if (defined $colidx{$key_column}) {
- push(@$key_idx, $i);
+ else {
+ my ($key_column);
+ if (!$colidx) {
+ $colidx = {};
+ for (my $i = 0; $i <= $#$cols; $i++) {
+ $colidx->{$cols->[$i]} = $i;
+ }
+ }
+ for (my $i = 0; $i <= $#$key_cols; $i++) {
+ $key_column = $key_cols->[$i];
+ if (defined $colidx->{$key_column}) {
+ push(@key_idx, $colidx->{$key_column});
+ }
+ else {
+ last;
+ }
+ }
+ if ($#$key_cols == $#key_idx) {
+ $key_idx = \...@key_idx;
}
}
+ last if ($key_idx);
}
+ die "unique key not found (primary or alternate) on $table for the
requested columns [...@$cols]" if (!$key_idx);
+
&App::sub_exit($key_idx) if ($App::trace);
return($key_idx);
}
Modified: p5ee/trunk/App-Repository/lib/App/Repository/MySQL.pm
==============================================================================
--- p5ee/trunk/App-Repository/lib/App/Repository/MySQL.pm (original)
+++ p5ee/trunk/App-Repository/lib/App/Repository/MySQL.pm Wed Mar 4
21:08:58 2009
@@ -764,7 +764,7 @@
sub is_duplicate_key_error {
my ($self, $e) = @_;
- return($e =~ /duplicate/i);
+ return($e =~ /duplicate entry/i);
}
sub _get_tables_from_source {
Modified: p5ee/trunk/App-Repository/t/DBI-insert-ora.t
==============================================================================
--- p5ee/trunk/App-Repository/t/DBI-insert-ora.t (original)
+++ p5ee/trunk/App-Repository/t/DBI-insert-ora.t Wed Mar 4 21:08:58 2009
@@ -123,7 +123,7 @@
$db->insert_row("test_person", {
person_id => 8,
age => 35,
- first_name => "alex",
+ first_name => "alex2",
gender => "M",
state => "GA",
});
@@ -132,7 +132,7 @@
ok($db->insert("test_person", undef, {
# person_id => 9,
age => 35,
- first_name => "alex",
+ first_name => "alex3",
gender => "M",
state => "GA",
}),
@@ -140,7 +140,7 @@
ok($db->insert("test_person", ["age","first_name","gender","state"], {
# person_id => 10,
age => 35,
- first_name => "alex",
+ first_name => "alex4",
gender => "M",
state => "GA",
}),
@@ -176,13 +176,13 @@
{ age=>39, first_name=>"keith", gender=>"M", state=>"GA",
foo=>"bar"},];
my $new_rows =
- [[39,"stephen", "M","GA"],
- [37,"susan", "F","GA"],
- [6,"maryalice", "F","GA"],
- [3,"paul", "M","GA"],
- [1,"christine", "F","GA"],
- [45,"tim", "M","GA"],
- [39,"keith", "M","GA"],];
+ [[39,"stephen", "M","CA"],
+ [37,"susan", "F","CA"],
+ [6,"maryalice", "F","CA"],
+ [3,"paul", "M","CA"],
+ [1,"christine", "F","CA"],
+ [45,"tim", "M","CA"],
+ [39,"keith", "M","CA"],];
my $dup_rows =
[[1, 39,"stephen", "M","GA"],
Modified: p5ee/trunk/App-Repository/t/DBI-insert.t
==============================================================================
--- p5ee/trunk/App-Repository/t/DBI-insert.t (original)
+++ p5ee/trunk/App-Repository/t/DBI-insert.t Wed Mar 4 21:08:58 2009
@@ -44,6 +44,7 @@
table => {
test_person => {
primary_key => ["person_id"],
+ alternate_key => [["first_name", "gender", "state"]],
},
},
},
@@ -131,7 +132,7 @@
$db->insert_row("test_person", {
person_id => 8,
age => 35,
- first_name => "alex",
+ first_name => "alex2",
gender => "M",
state => "GA",
});
@@ -140,7 +141,7 @@
ok($db->insert("test_person", undef, {
person_id => 9,
age => 35,
- first_name => "alex",
+ first_name => "alex3",
gender => "M",
state => "GA",
}),
@@ -148,7 +149,7 @@
ok($db->insert("test_person", ["age","first_name","gender","state"], {
person_id => 9,
age => 35,
- first_name => "alex",
+ first_name => "alex4",
gender => "M",
state => "GA",
}),
@@ -157,7 +158,7 @@
$db->insert_row("test_person", undef, {
person_id => 9,
age => 35,
- first_name => "alex",
+ first_name => "alex5",
gender => "M",
state => "GA",
});
@@ -185,13 +186,13 @@
{ age=>39, first_name=>"keith", gender=>"M", state=>"GA",
foo=>"bar"},];
my $new_rows =
- [[39,"stephen", "M","GA"],
- [37,"susan", "F","GA"],
- [6,"maryalice", "F","GA"],
- [3,"paul", "M","GA"],
- [1,"christine", "F","GA"],
- [45,"tim", "M","GA"],
- [39,"keith", "M","GA"],];
+ [[39,"stephen", "M","CA"],
+ [37,"susan", "F","CA"],
+ [6,"maryalice", "F","CA"],
+ [3,"paul", "M","CA"],
+ [1,"christine", "F","CA"],
+ [45,"tim", "M","CA"],
+ [39,"keith", "M","CA"],];
my $dup_rows =
[[1, 39,"stephen", "M","GA"],
@@ -206,16 +207,17 @@
insert into test_person
(age, first_name, gender, state)
values
- (39, 'stephen', 'M', 'GA'),
- (37, 'susan', 'F', 'GA'),
- (6, 'maryalice', 'F', 'GA'),
- (3, 'paul', 'M', 'GA'),
- (1, 'christine', 'F', 'GA'),
- (45, 'tim', 'M', 'GA'),
- (39, 'keith', 'M', 'GA')
+ (39, 'stephen', 'M', 'CA'),
+ (37, 'susan', 'F', 'CA'),
+ (6, 'maryalice', 'F', 'CA'),
+ (3, 'paul', 'M', 'CA'),
+ (1, 'christine', 'F', 'CA'),
+ (45, 'tim', 'M', 'CA'),
+ (39, 'keith', 'M', 'CA')
EOF
$sql = $db->_mk_insert_rows_sql("test_person",
["age","first_name","gender","state"], $new_rows);
is($sql, $expect_sql, "_mk_insert_rows_sql(): 7 rows, bulk insert");
+ $expect_sql =~ s/CA/GA/g;
$sql = $db->_mk_insert_rows_sql("test_person",
["age","first_name","gender","state"], $new_hashes);
is($sql, $expect_sql, "_mk_insert_rows_sql(): 7 rows, bulk insert (from
hashes)");
@@ -223,18 +225,18 @@
replace into test_person
(age, first_name, gender, state)
values
- (39, 'stephen', 'M', 'GA'),
- (37, 'susan', 'F', 'GA'),
- (6, 'maryalice', 'F', 'GA'),
- (3, 'paul', 'M', 'GA'),
- (1, 'christine', 'F', 'GA'),
- (45, 'tim', 'M', 'GA'),
- (39, 'keith', 'M', 'GA')
+ (39, 'stephen', 'M', 'CA'),
+ (37, 'susan', 'F', 'CA'),
+ (6, 'maryalice', 'F', 'CA'),
+ (3, 'paul', 'M', 'CA'),
+ (1, 'christine', 'F', 'CA'),
+ (45, 'tim', 'M', 'CA'),
+ (39, 'keith', 'M', 'CA')
EOF
- $sql = $db->_mk_insert_rows_sql("test_person",
["age","first_name","gender","state"], $new_rows, { replace => 1 });
- is($sql, $expect_sql, "_mk_insert_rows_sql(): 7 rows, bulk replace");
+ $sql = $db->_mk_insert_rows_sql("test_person",
["age","first_name","gender","state"], $new_rows, { replace => 1 });
+ is($sql, $expect_sql, "_mk_insert_rows_sql(): 7 rows, bulk replace");
- $expect_sql = <<EOF;
+ $expect_sql = <<EOF;
insert into test_person
(person_id, age, first_name, gender, state)
values
@@ -252,19 +254,43 @@
gender = values(gender),
state = values(state)
EOF
- $sql = $db->_mk_insert_rows_sql("test_person", ["person_id",
"age","first_name","gender","state"], $dup_rows, { update => 1 });
- is($sql, $expect_sql, "_mk_insert_rows_sql(): 7 rows, bulk insert/update");
- $nrows = $db->insert_rows("test_person",
["age","first_name","gender","state"], $new_rows);
- is($nrows, 7, "insert_rows(): 7 rows, bulk insert");
- $nrows = $db->insert_rows("test_person",
["person_id","age","first_name","gender","state"], $dup_rows, { replace => 1 });
- is($nrows, 7, "insert_rows(): 7 rows, bulk replace");
- $nrows = $db->insert_rows("test_person", ["person_id",
"age","first_name","gender","state"], $dup_rows, { update => 1 });
- is($nrows, 7, "insert_rows(): 7 rows, bulk insert/update");
- $nrows = $db->insert_rows("test_person",
["person_id","age","first_name","gender","state"], $dup_rows, { replace => 1,
maxrows => 4 });
- is($nrows, 7, "insert_rows(): 7 rows, bulk replace (4 at a time)");
- $nrows = $db->insert_rows("test_person", ["person_id",
"age","first_name","gender","state"], $dup_rows, { update => 1, maxrows => 4 });
- is($nrows, 7, "insert_rows(): 7 rows, bulk insert/update (4 at a time)");
+ $sql = $db->_mk_insert_rows_sql("test_person", ["person_id",
"age","first_name","gender","state"], $dup_rows, { update => 1 });
+ is($sql, $expect_sql, "_mk_insert_rows_sql(): 7 rows, bulk
insert/update");
+ $nrows = $db->insert_rows("test_person",
["age","first_name","gender","state"], $new_rows);
+ is($nrows, 7, "insert_rows(): 7 rows, bulk insert");
+ $nrows = $db->insert_rows("test_person",
["person_id","age","first_name","gender","state"], $dup_rows, { replace => 1 });
+ is($nrows, 7, "insert_rows(): 7 rows, bulk replace");
+ $nrows = $db->insert_rows("test_person", ["person_id",
"age","first_name","gender","state"], $dup_rows, { update => 1 });
+ is($nrows, 7, "insert_rows(): 7 rows, bulk insert/update");
+ $nrows = $db->insert_rows("test_person",
["person_id","age","first_name","gender","state"], $dup_rows, { replace => 1,
maxrows => 4 });
+ is($nrows, 7, "insert_rows(): 7 rows, bulk replace (4 at a time)");
+ $nrows = $db->insert_rows("test_person", ["person_id",
"age","first_name","gender","state"], $dup_rows, { update => 1, maxrows => 4 });
+ is($nrows, 7, "insert_rows(): 7 rows, bulk insert/update (4 at a
time)");
}
+
+ my ($key_idx, $columns, $row, $nrows);
+
+ $columns = [ "age", "person_id", "last_name", "first_name", "gender" ];
+ $row = [ 40, 1, "adkins", "stephen", "M" ];
+ $key_idx = $db->_key_idx("test_person", $columns);
+ is(ref($key_idx), "ARRAY", "key_idx is ARRAY");
+ is($key_idx->[0], 1, "key_idx is [1] for [...@$columns]");
+ $nrows = $db->insert_row("test_person",$columns,$row,{update => 1});
+ is($nrows, 1, "insert with {update} option on primary key");
+ is($db->get("test_person",1,"age"), 40, "updated age to 40 successful");
+
+ $columns = [ "age", "last_name", "first_name", "state", "gender" ];
+ $row = [ 41, "zadkins", "stephen", "GA", "M" ];
+ $key_idx = $db->_key_idx("test_person", $columns);
+ is(ref($key_idx), "ARRAY", "key_idx is ARRAY");
+ is($#$key_idx, 2, "key_idx is 3 elements [...@$key_idx]");
+ is($key_idx->[0], 2, "key_idx[0] is 2 for [...@$columns]");
+ is($key_idx->[1], 4, "key_idx[1] is 4 for [...@$columns]");
+ is($key_idx->[2], 3, "key_idx[2] is 3 for [...@$columns]");
+ $nrows = $db->insert_row("test_person",$columns,$row,{update => {age => 1,
last_name => 1}});
+ is($nrows, 1, "insert with {update} option on alternate key");
+ is($db->get("test_person",1,"age"), 41, "updated age to 41 successful");
+ is($db->get("test_person",1,"last_name"), "zadkins", "updated last_name to
zadkins successful");
}
exit 0;
Modified: p5ee/trunk/App-Repository/t/RepositoryTestUtils.pm
==============================================================================
--- p5ee/trunk/App-Repository/t/RepositoryTestUtils.pm (original)
+++ p5ee/trunk/App-Repository/t/RepositoryTestUtils.pm Wed Mar 4 21:08:58 2009
@@ -77,7 +77,13 @@
print "DEBUG:\n$ddl\n" if ($App::options{debug_sql});
$rc = $dbh->do($ddl);
print "DEBUG: rc=[$rc] errstr=[$DBI::errstr]\n" if
($App::options{debug_sql});
- $ddl = "create index person_ie1 on test_person (last_name, first_name)";
+
+ $ddl = "create unique index test_person_ak1 on test_person (first_name,
state, gender)";
+ print "DEBUG:\n$ddl\n" if ($App::options{debug_sql});
+ $rc = $dbh->do($ddl);
+ print "DEBUG: rc=[$rc] errstr=[$DBI::errstr]\n" if
($App::options{debug_sql});
+
+ $ddl = "create index test_person_ie1 on test_person (last_name,
first_name)";
$dbh->do($ddl);
if ($dbtype eq "oracle") {
$ddl = <<EOF;
@@ -226,6 +232,7 @@
)SUFFIX
EOF
$table_index{test_person} = [
+ "create unique index test_person_ak1 on test_person (first_name, state,
gender)",
"create index test_person_ie1 on test_person (last_name, first_name)",
];
$table_autoid_column{test_person} = "person_id";
@@ -242,7 +249,7 @@
$table_schema{test_country} = <<EOF;
create table test_country (
country_id integer not null AUTOINCREMENT,
- country char(2) not null,
+ country char(2) not null,
country_nm varchar(64) not null,
primary key (country_id)
)SUFFIX
Modified: p5ee/trunk/App-Repository/t/files/DBI-import.01.dat
==============================================================================
--- p5ee/trunk/App-Repository/t/files/DBI-import.01.dat (original)
+++ p5ee/trunk/App-Repository/t/files/DBI-import.01.dat Wed Mar 4 21:08:58 2009
@@ -2,119 +2,119 @@
37|mary|F|GA
49|maxwell|M|GA
47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
-39|mike|M|GA
-37|mary|F|GA
-49|maxwell|M|GA
-47|myrtle|F|GA
+39|mike2|M|GA
+37|mary2|F|GA
+49|maxwell2|M|GA
+47|myrtle2|F|GA
+39|mike3|M|GA
+37|mary3|F|GA
+49|maxwell3|M|GA
+47|myrtle3|F|GA
+39|mike4|M|GA
+37|mary4|F|GA
+49|maxwell4|M|GA
+47|myrtle4|F|GA
+39|mike5|M|GA
+37|mary5|F|GA
+49|maxwell5|M|GA
+47|myrtle5|F|GA
+39|mike6|M|GA
+37|mary6|F|GA
+49|maxwell6|M|GA
+47|myrtle6|F|GA
+39|mike7|M|GA
+37|mary7|F|GA
+49|maxwell7|M|GA
+47|myrtle7|F|GA
+39|mike8|M|GA
+37|mary8|F|GA
+49|maxwell8|M|GA
+47|myrtle8|F|GA
+39|mike9|M|GA
+37|mary9|F|GA
+49|maxwell9|M|GA
+47|myrtle9|F|GA
+39|mike10|M|GA
+37|mary10|F|GA
+49|maxwell10|M|GA
+47|myrtle10|F|GA
+39|mike11|M|GA
+37|mary11|F|GA
+49|maxwell11|M|GA
+47|myrtle11|F|GA
+39|mike12|M|GA
+37|mary12|F|GA
+49|maxwell12|M|GA
+47|myrtle12|F|GA
+39|mike13|M|GA
+37|mary13|F|GA
+49|maxwell13|M|GA
+47|myrtle13|F|GA
+39|mike14|M|GA
+37|mary14|F|GA
+49|maxwell14|M|GA
+47|myrtle14|F|GA
+39|mike15|M|GA
+37|mary15|F|GA
+49|maxwell15|M|GA
+47|myrtle15|F|GA
+39|mike16|M|GA
+37|mary16|F|GA
+49|maxwell16|M|GA
+47|myrtle16|F|GA
+39|mike17|M|GA
+37|mary17|F|GA
+49|maxwell17|M|GA
+47|myrtle17|F|GA
+39|mike18|M|GA
+37|mary18|F|GA
+49|maxwell18|M|GA
+47|myrtle18|F|GA
+39|mike19|M|GA
+37|mary19|F|GA
+49|maxwell19|M|GA
+47|myrtle19|F|GA
+39|mike20|M|GA
+37|mary20|F|GA
+49|maxwell20|M|GA
+47|myrtle20|F|GA
+39|mike21|M|GA
+37|mary21|F|GA
+49|maxwell21|M|GA
+47|myrtle21|F|GA
+39|mike22|M|GA
+37|mary22|F|GA
+49|maxwell22|M|GA
+47|myrtle22|F|GA
+39|mike23|M|GA
+37|mary23|F|GA
+49|maxwell23|M|GA
+47|myrtle23|F|GA
+39|mike24|M|GA
+37|mary24|F|GA
+49|maxwell24|M|GA
+47|myrtle24|F|GA
+39|mike25|M|GA
+37|mary25|F|GA
+49|maxwell25|M|GA
+47|myrtle25|F|GA
+39|mike26|M|GA
+37|mary26|F|GA
+49|maxwell26|M|GA
+47|myrtle26|F|GA
+39|mike27|M|GA
+37|mary27|F|GA
+49|maxwell27|M|GA
+47|myrtle27|F|GA
+39|mike28|M|GA
+37|mary28|F|GA
+49|maxwell28|M|GA
+47|myrtle28|F|GA
+39|mike29|M|GA
+37|mary29|F|GA
+49|maxwell29|M|GA
+47|myrtle29|F|GA
+39|mike30|M|GA
+37|mary30|F|GA
+49|maxwell30|M|GA
+47|myrtle30|F|GA