my ($self, @cols) = @_;
$self->_ordered_columns( \@cols )
if !$self->_ordered_columns;
- push @{ $self->_ordered_columns }, @cols;
+ my @added;
+ my $columns = $self->_columns;
while (my $col = shift @cols) {
- my $column_info = ref $cols[0] ? shift : {};
+ my $column_info = ref $cols[0] ? shift(@cols) : {};
# If next entry is { ... } use that for the column info, if not
# use an empty hashref
- $self->_columns->{$col} = $column_info;
+ push(@added, $col) unless exists $columns->{$col};
+
+ $columns->{$col} = $column_info;
}
+ push @{ $self->_ordered_columns }, @added;
+ return $self;
}
*add_column = \&add_columns;
return $self->resultset_class->new($self);
}
-=head2 has_column
-
+=head2 has_column
+
if ($obj->has_column($col)) { ... }
Returns 1 if the source has a column of this name, 0 otherwise.
=head2 columns
- my @column_names = $obj->columns;
+ my @column_names = $obj->columns;
+
+Returns all column names in the order they were declared to add_columns
=cut
sub columns {
croak "columns() is a read-only accessor, did you mean add_columns()?" if (@_ > 1);
- return keys %{shift->_columns};
-}
-
-=head2 ordered_columns
-
- my @column_names = $obj->ordered_columns;
-
-Like columns(), but returns column names using the order in which they were
-originally supplied to add_columns().
-
-=cut
-
-sub ordered_columns {
return @{shift->{_ordered_columns}||[]};
}
=head2 primary_columns
Read-only accessor which returns the list of primary keys.
-
+
=cut
sub primary_columns {
sub add_relationship {
my ($self, $rel, $f_source_name, $cond, $attrs) = @_;
- die "Can't create relationship without join condition" unless $cond;
+ croak "Can't create relationship without join condition" unless $cond;
$attrs ||= {};
my %rels = %{ $self->_relationships };
attrs => $attrs };
$self->_relationships(\%rels);
- return 1;
+ return $self;
# XXX disabled. doesn't work properly currently. skip in tests.
if ($@) { # If the resolve failed, back out and re-throw the error
delete $rels{$rel}; #
$self->_relationships(\%rels);
- die "Error creating relationship $rel: $@";
+ croak "Error creating relationship $rel: $@";
}
1;
}
$self->related_source($_)->resolve_join($join->{$_}, $_) }
keys %$join;
} elsif (ref $join) {
- die("No idea how to resolve join reftype ".ref $join);
+ croak ("No idea how to resolve join reftype ".ref $join);
} else {
- die("No such relationship ${join}") unless $self->has_relationship($join);
- my $type = $self->relationship_info($join)->{attrs}{join_type} || '';
+ my $rel_info = $self->relationship_info($join);
+ croak("No such relationship ${join}") unless $rel_info;
+ my $type = $rel_info->{attrs}{join_type} || '';
return [ { $join => $self->related_source($join)->from,
-join_type => $type },
- $self->resolve_condition($join, $alias) ];
+ $self->resolve_condition($rel_info->{cond}, $join, $alias) ];
}
}
-=head2 resolve_condition($rel, $alias|$object)
+=head2 resolve_condition($cond, $rel, $alias|$object)
-Returns the conditional for the specified relationship. If given an alias,
+Resolves the passed condition to a concrete query fragment. If given an alias,
returns a join condition; if given an object, inverts that object to produce
a related conditional from that object.
=cut
sub resolve_condition {
- my ($self, $rel, $for) = @_;
- my $cond = $self->relationship_info($rel)->{cond};
+ my ($self, $cond, $rel, $for) = @_;
#warn %$cond;
if (ref $cond eq 'HASH') {
my %ret;
while (my ($k, $v) = each %{$cond}) {
# XXX should probably check these are valid columns
- $k =~ s/^foreign\./${rel}./ || die "Invalid rel cond key ${k}";
+ $k =~ s/^foreign\.// || croak "Invalid rel cond key ${k}";
+ $v =~ s/^self\.// || croak "Invalid rel cond val ${v}";
if (ref $for) { # Object
- die "Invalid ref cond val ${v}" unless $v =~ m/^self\.(.*)$/;
- $ret{$k} = $for->$1;
+ #warn "$self $k $for $v";
+ $ret{$k} = $for->get_column($v);
+ #warn %ret;
} else {
- $v =~ s/^self\./${for}./ || die "Invalid rel cond val ${v}";
+ $ret{"${rel}.${k}"} = "${for}.${v}";
}
- $ret{$k} = $v;
}
return \%ret;
+ } elsif (ref $cond eq 'ARRAY') {
+ return [ map { $self->resolve_condition($_, $rel, $for) } @$cond ];
} else {
die("Can't handle this yet :(");
}