BingoX

 view release on metacpan or  search on metacpan

lib/BingoX/Carbon.pm  view on Meta::CPAN

			if (%tmpparams) {			# %tmpparams remaining are parameters not in $order list
				unshift @$order, '(';
				push @$order, (')', 'AND', split (' ', join(' AND ', keys %tmpparams)));
			}
		} else {						# order list empty!
			$order = [ split (' ', join(' AND ', keys %$params)) ];
		}
	} elsif (ref $params eq 'HASH') {
		$order = [ split (' ', join(' AND ', keys %$params)) ];
	} else {							# make sure we have params
		return undef;
	}

	## parse each field and add to SQL statement ##
	my ($WHERE, @query, @bindings);
	foreach my $field (@$order) {
		if (($field eq 'AND') || ($field eq 'OR') || ($field eq '(') || $field eq ')') {
			next if (($field =~ /^(?:AND|OR)$/o) && (!@query || ($query[$#query] =~ /^(?:AND|OR)$/o)));
			next if (($field =~ /^(?:\(|\))$/o) && ($query[$#query] =~ /^(?:\(|\))$/o));
			push @query, $field;
			next;
		}
		## make sure field is in params ##
		unless (defined $class->deffields->{$field}) {
			pop @query;
			next;
		}
		## enforce precedence ##
		my $sql = '(';					# ) loathe BBEdit

		my @valuelist = $params->{$field};
		next unless (defined $valuelist[0]);

		## add relation prefix if $r_flag ##
		$field = "${alias}.${field}" if $alias;
		for (my $x = 0; $x <= $#valuelist; $x++) {
			my $value = $valuelist[$x];
			if (ref($value) eq 'ARRAY') {				# IN, BETWEEN, or multiple comparisons
				my ( $type, @values )	= @{ $value };
				if (substr(lc($type), -2) eq 'in') {	# 'IN' or 'NOT IN'
					return $self->error_handler("no bindings passed to format_conditions for type ($type)")
						unless (@values);
					my (@IN_bindings, @IN_sql);
					while (my $value = shift(@values)) {
						if (lc(substr($value, 0, 6)) eq 'select') {
							push (@IN_sql, $value);
							push (@IN_bindings, splice(@values, 0, $#values + 1));	# $/
						} else {
							push (@IN_sql, '?');
							push (@IN_bindings, $value);
						}
					}
					$sql .= "$field " . uc($type) . ' (' . join(', ', @IN_sql) . ')';
					push(@bindings, @IN_bindings);
				} elsif (substr(lc($type), -7) eq 'between') {	# 'BETWEEN' or 'NOT BETWEEN'
					return $self->error_handler("no bindings passed to format_conditions for type ($type)")
						unless (@values);
					$sql .= "$field " . uc($type) . ' ? AND ?';
					push(@bindings, @values[0,1]);
				} else {										# LIST of conditions
					splice (@valuelist, $x+1, 0, @$value);		# appending will push to next iterations
				}
			} elsif ($value =~ /^\/(.+?)\/$/) {					# regex
				$sql .= "$field ~ ?";
				push(@bindings, $1);
			} elsif ($value =~ /^(\d+?)-(\d+?)$/) {				# date or numeric range
				$sql .= "($field > ? AND $field < ?)";
				push(@bindings, $1, $2);
			} elsif ($value eq '&&') {							# AND
				$sql .= ' AND ';
			} elsif ($value eq '||') {							# OR
				$sql .= ' OR ';
																# BEGIN	BBEdit loathing 
			} elsif ($value eq '(')								# Open paren	) loathe BBedit
			{ # loathe BBedit here, too!
				$sql .= '(';									# ) loathe BBedit
			} # loathe BBedit here, too!						# ( loathe BBedit
			  elsif ($value eq ')') {							# Close paren	( loathe BBedit
				$sql .= ')';									# END	BBEdit loathing 
			} elsif (lc($value) =~ /^(?:like|not|is)\s|<|>/) {	# Allow LIKE,NOT,IS,<,>,<=,>= blindly
				if ($value =~ /##/) {
					while ($value =~ s/##(.+?)##/?/o) {
						push(@bindings, $1);
					}
				}
				$sql .= "$field $value";						# can use with embeded SELECT
		### Why do we need this code?  Uncomment if you change the else!
		#	} elsif ($value =~ /^-?(?:\d+?)\.?(?:\d*?)$/) {			# exact match number
		#		$sql .= "$field = ?";
		#		push(@bindings, $value);
		###
			} else {											# exact match lexical
				$sql .= "$field = ?";
				push(@bindings, $value);
			}
		} # END for (multiple values loop)
		## enforce precedence ( ##
		$sql .= ')';

		## add to array to be joined later ##
		push(@query, $sql) if ($sql ne '()');
	} # END foreach (fields loop)

	$WHERE	= 'WHERE ' . join(' ', @query) if (@query);
	warn "$class->format_conditions:\t\"$WHERE\" [@bindings]\n" if ($debug);
	return ($WHERE, @bindings);
} # END sub format_conditions


=head2 AUTOLOAD

=over 4

=item AUTOLOAD

AUTOLOAD method - returns requested field data from object. 
If that requested data has not been cached, it is retrieved from the 
database, cached, and returned.  If data is passed then field value is 
modified in the database and instance data, and value is returned.




( run in 0.623 second using v1.01-cache-2.11-cpan-71847e10f99 )