NAME

App::Netdisco::DB::Upsert - bulk INSERT ... ON CONFLICT for every result set

DESCRIPTION

Internal. This interface may change between releases and is not for site-local plugins.

Table and column names come only from the result source, never from the caller, and every identifier is quoted. Every value is a bind parameter, with one exception: a scalar reference is inlined only when it matches one of the timestamp expressions netdisco itself builds. Any other reference to SQL dies.

METHODS

upsert( \@rows, \%options )

Writes each row with one INSERT ... ON CONFLICT (primary key) DO UPDATE, in batches that stay under the PostgreSQL bind parameter limit. Returns the number of rows inserted or updated, so a row already holding the same values counts as zero. Returns 0 and sends nothing for an empty list.

Each row is a hash reference of column to value. Every row must have the same keys, including every primary key column, and each key must appear once. Values are undef, a plain scalar, an array reference of plain scalars (for array columns), or an allowed timestamp literal.

Options:

insert_only

Columns written on insert and never changed by the update.

touch

Columns updated, but left out of the change test, so they change only when some other column does.

remove_unseen( \%scope, \@seen )

Deletes the rows in %scope whose primary key is not in @seen, with one plain DELETE and returns the number of rows deleted. It does no cascade, and it refuses the Node and DevicePortLog sources, whose rows are never deleted by this method.

Call it on a plain resultset('Source'). A result set carrying search conditions, such as $device->port_vlans, is refused, because only %scope restricts the DELETE.

%scope maps primary key columns to plain scalars and must be non-empty. When ip is one of the source's key columns, %scope must include it (for discover, { ip => $device->ip }). It must leave at least one key column out, or it would name a single row. @seen holds hash references with exactly the key columns not in %scope. An empty @seen deletes every row in the scope, which is right for a complete walk that found nothing.