Database-Abstraction

 view release on metacpan or  search on metacpan

lib/Database/Abstraction.pm  view on Meta::CPAN


	# Ensure the 'query' parameter is provided
	Carp::croak(__PACKAGE__, ': Usage: execute(query => $query)')
		unless defined $args->{'query'};

	my $table = $self->_open_table($args);

	my $query = $args->{'query'};

	# Append "FROM <table>" if missing
	# \bFROM\b catches the keyword at any word boundary (space, tab, newline),
	# unlike the former \sFROM\s which missed forms like "col\tFROM" or leading FROM.
	$query .= " FROM $table" unless $query =~ /\bFROM\b/i;

	# Log the query if a logger is available
	$self->_debug("execute $query");

	# Prepare and execute the query
	my $sth = $self->{$table}->prepare_cached($query);
	# DBI->execute() takes a list; normalise args to an array whether it
	# was passed as an arrayref ([30]) or a bare scalar/list (30).
	if(exists($args->{'args'})) {
		my @bind = ref($args->{'args'}) eq 'ARRAY' ? @{$args->{'args'}} : ($args->{'args'});
		$sth->execute(@bind) or croak("$query: ", join(', ', @bind));
	} else {
		$sth->execute() or croak($query);
	}

	# Fetch the results
	my @results;
	while (my $row = $sth->fetchrow_hashref()) {
		unless(wantarray) {
			$sth->finish();
			return $row;
		}
		push @results, $row;
	}

	# Return all rows as an array in list context
	return @results;
}

=head2 updated

Returns the Unix timestamp of the last database update.

For file-based backends (CSV, XML, SQLite via C<directory>), this is the
mtime of the backing file, set at C<new()> time.

For SQLite DSN connections (C<dbi:SQLite:dbname=...>), the file path is
extracted from the DSN and C<stat()>-ed live on every call, so callers
get a current mtime suitable for cache-invalidation even when the database
was opened via a DSN rather than a C<directory>.

For all other DSN-based connections (PostgreSQL, MySQL, etc.) and for
URL-based backends, returns the Unix timestamp of the most recent
C<new()> call (connection time).

=cut

sub updated {
	my $self = shift;

	if(($self->{'_dialect'} // '') eq 'sqlite') {
		my $dsn = $self->{'dsn'};
		if(defined($dsn) && $dsn =~ /\Adbi:SQLite:(?:dbname=)?(.+)\z/i) {
			my $path = $1;
			my @st = stat($path);
			return $st[9] if @st;
		}
	}

	return $self->{'_updated'};
}

=head2 columns

Returns an array reference of column names for the current table.

    my $cols = $db->columns();    # e.g. ['entry', 'name', 'score', 'status']

Column names are always returned in alphabetical (lexicographic) order,
regardless of backend. This makes the result stable and portable when the
same logical table is backed by different engines (CSV => SQLite, etc.).

The source of column names varies by backend:

=over 4

=item * B<Slurp mode> - keys of the first row in memory.

=item * B<SQLite / other DBI> - a zero-row C<SELECT *> exposes the driver's
C<NAME> attribute.

=item * B<BerkeleyDB> - always returns C<['entry', 'value']>.

=back

The result is cached inside the object after the first call.

=head3 API SPECIFICATION

=head4 Arguments

None beyond the implicit invocant.  The result is cached in the
object after the first call.

=head4 Returns

    ArrayRef[Str]

A sorted (lexicographic, ascending) arrayref of column names.  The
sort order is identical across all backends, so switching from CSV
to SQLite does not change the returned order.

=cut

sub columns {
	my $self = shift;

	return $self->{'_columns'} if $self->{'_columns'};



( run in 0.322 second using v1.01-cache-2.11-cpan-7da0f45c409 )