view release on metacpan or search on metacpan
docs/adr/0021-constraint-name-optional-canonical-fk-key.md view on Meta::CPAN
`table_fk_info` untouched is simplicity-first: no generation-path code reads the
name, so adding it there would be an abstraction with no caller.
The decision belongs in core because it is a family-wide field-name contract, and
ADR 0018 already established that a family rule recorded in a single driver's repo
carries no authority over the others. Blessing the key here gives every driver â
and the Diff layer that spans them â one source for the rule.
## Consequences
- **Sybase karr #14 is unblocked and becomes purely driver-local.** No core code
change is required; the contract blessing is enough. Sybase stops dropping the
name in `_group_fks_by_constraint`, carries `constraint_name` into
`model->{foreign_keys}`, and has `DBIO::Sybase::Diff::ForeignKey` prefer the
real server name for `DROP` (falling back to the deterministically generated
name only when the name is absent). This is the FK drop/alter fidelity gap that
follows the FK diff op shipped in Sybase karr #11.
- **Drivers using `_constraint_name` realign to bare `constraint_name`** â DB2,
Informix, and the PostgreSQL `table_fk_info` relationship path. Each is tracked
as a per-driver follow-up ticket on that driver's own board (driver-repo work).
- **MSSQL and the PostgreSQL `foreign_keys` section are already conformant** and
docs/adr/0030-async-explicit-per-connection-mode.md view on Meta::CPAN
- **dbio-async / dbio-postgresql-ev / dbio-mysql-ev**: collapse to transport-only
over the core orchestration; register their mode. karr tickets on their boards.
- **dbio-postgresql / dbio-mysql**: register the `ev` mode mapping; drop the
MySQL-EV `connection()` hijack; reach parity (`deploy_async`, pool readiness).
- **Naming cleanup**: stale `::Async` / `DBIO::EV::Pg` names in core POD and
`DBIO::Manual::Heritage`; `Changes`/README staleness in the add-ons.
- **ResultSet/Row real async** (carried over from the earlier async ADRs): route RS `*_async`
through the storage backend with async row inflation and prefetch/collapse
parity. Its own ADR when taken up.
- **dbio-postgresql-age**: `DBIO::PostgreSQL::Age::Storage::Async` with
`cypher_async` (age board #5) â blocked on core #68 (pool on_connect seam).
## Relationship to other ADRs
- **0028 (class-declared embedded backend) and 0029 (forked auto-fallback) â
removed.** Both are fully replaced by this ADR and have been deleted from
`docs/adr/`; their still-relevant rationale is folded into the Context and
Decision above (why an auto-fallback is a footgun â §Context.1; why the embedded
backend belongs in the storage instance, now chosen per connection rather than
per class â §Decision.1). Git history preserves the originals.
- **0014 â binding/degrade superseded, API kept.** `*_async` stays universal and
lib/DBIO/Manual/Cookbook.pod view on Meta::CPAN
L<prefetch|DBIO::ResultSet/prefetch> relationships, where possible. See
L</Using joins and prefetch>.
=item *
Use L<populate|DBIO::ResultSet/populate> in void context to insert data
when you don't need the resulting L<result|DBIO::Manual::ResultClass> objects,
if possible, but see the caveats.
When inserting many rows, for best results, populate a large number of rows at a
time, but not so large that the table is locked for an unacceptably long time.
If using L<create|DBIO::ResultSet/create> instead, use a transaction and
commit every C<X> rows; where C<X> gives you the best performance without
locking the table for too long.
=item *
When selecting many rows, if you don't need full-blown L<DBIO::Row>
objects, consider using L<DBIO::ResultClass::HashRefInflator>.
lib/DBIO/ResultSet.pm view on Meta::CPAN
$ci->{$_} = { %{$ci->{$_}}, is_nullable => 0 }
for grep { ! $colinfo->{$_}{seen_null} } keys %$ci;
unless( $rsrc->_identifying_column_set($ci) ) {
carp_unique("Fast-path populate() of non-uniquely identifiable rows with related data is not possible - falling back to regular create()");
return my $throwaway = $self->populate(@_);
}
}
### inherit the data locked in the conditions of the resultset
my ($rs_data) = $self->_merge_with_rscond({});
delete @{$rs_data}{@$colnames}; # passed-in stuff takes precedence
# if anything left - decompose rs_data
my $rs_data_vals;
if (keys %$rs_data) {
push @$rs_data_vals, $rs_data->{$_}
for sort keys %$rs_data;
}
lib/DBIO/ResultSet.pm view on Meta::CPAN
sub as_subselect_rs {
my $self = shift;
my $attrs = $self->_resolved_attrs;
my $fresh_rs = (ref $self)->new (
$self->result_source,
{},
);
# these pieces will be locked in the subquery
delete $fresh_rs->{cond};
delete @{$fresh_rs->{attrs}}{qw/where bind/};
return $fresh_rs->search( {}, {
from => [{
$attrs->{alias} => $self->as_query,
-alias => $attrs->{alias},
-rsrc => $self->result_source,
}],
alias => $attrs->{alias},
share/skills/karr/SKILL.md view on Meta::CPAN
### Edit task
```bash
karr edit ID --title "New title"
karr edit ID --priority high --add-tag urgent
karr edit ID --body "New description"
karr edit ID -a "Appended note" # append to body
karr edit ID --claim agent-1 # claim
karr edit ID --release # release claim
karr edit ID --block "Waiting on API" # mark blocked
karr edit ID --unblock # clear blocked
```
### Delete task
```bash
karr delete ID --yes # skip confirmation
```
### Archive task
share/skills/karr/SKILL.md view on Meta::CPAN
Shows tasks grouped by status.
### Pick next task (multi-agent)
```bash
karr pick --claim agent-1 # pick highest priority available
karr pick --claim agent-1 --status todo --move in-progress
karr pick --claim agent-1 --tags backend
```
Atomically finds and claims the next available task. Respects claim timeouts, blocked state, and class-of-service priority ordering (expedite > fixed-date > standard > intangible).
### Handoff task for review
```bash
karr handoff ID --claim agent-1 # move to review, refresh claim
karr handoff ID --claim agent-1 --note "Done, needs QA" --timestamp
karr handoff ID --claim agent-1 --block "waiting for feedback" --release
```
Moves task to `review`, refreshes claim, optionally appends a timestamped note, blocks, or releases the claim.
share/skills/karr/SKILL.md view on Meta::CPAN
karr config --json # JSON output
```
Writable keys: `board.name`, `board.description`, `defaults.status`, `defaults.priority`, `defaults.class`, `claim_timeout`.
### Context (board summary for embedding)
```bash
karr context # print markdown summary
karr context --write-to AGENTS.md # create/update file with sentinels
karr context --sections blocked,overdue # filter sections
karr context --days 14 # lookback for recently-completed
karr context --json # JSON output
```
Generates a markdown summary with sections: In Progress, Blocked, Overdue, Recently Completed. Uses `<!-- BEGIN kanban-md context -->` / `<!-- END kanban-md context -->` sentinels for in-place updates.
### Skill management
```bash
karr skill install # install skill for detected agents
karr skill install --agent claude-code # install for specific agent
karr skill install --global # install globally (~/)
karr skill install --force # force reinstall
karr skill check # check if installed skills are current
karr skill update # update outdated skills
share/skills/karr/SKILL.md view on Meta::CPAN
is kept separately in `refs/karr/meta/next-id`.
## Decision tree: which command?
1. **Need a board?** â `karr init`
2. **New work item?** â `karr create "Title" --priority high`
3. **What's on the board?** â `karr board` or `karr list`
4. **Starting work?** â `karr pick --claim NAME --move in-progress`
5. **Done with task, hand to review?** â `karr handoff ID --claim NAME --note "reason"`
6. **Done with task, close it?** â `karr edit ID --release && karr move ID done`
7. **Blocked?** â `karr edit ID --block "reason"`
8. **Need details?** â `karr show ID`
9. **Soft-delete?** â `karr archive ID`
10. **Board snapshot for agent context?** â `karr context --write-to AGENTS.md`
11. **Check/change config?** â `karr config` / `karr config set KEY VALUE`
12. **Install agent skills?** â `karr skill install`
13. **Need a full board snapshot?** â `karr backup` / `karr restore --yes`
14. **Need shared non-task workflow data?** â `karr set-refs` / `karr get-refs`
15. **Need to remove the board completely?** â `karr destroy --yes`
## Multi-agent workflow
t/92admin_core.t view on Meta::CPAN
schema_class => 'DBIO::Test::Schema',
connect_info => ['dbi:MSSQL:dbname=test', '', '', {}],
quiet => 1,
);
{
local @INC = (
sub {
my ($self, $file) = @_;
if ($file =~ m{\ADBIO/(?:MSSQL|MSSQL/Storage)\.pm\z}) {
die "blocked in test: $file";
}
return;
},
@INC,
);
throws_ok {
$missing->schema;
} qr/No DBIO driver module available for DSN driver 'MSSQL'.*DBIO::MSSQL/s,
'missing DBIO driver module gives actionable error';
t/test/17_async_future_io_mro_walk.t view on Meta::CPAN
use warnings;
use Test::More;
use DBIO::Test;
use DBIO::Storage::Async;
use DBIO::Storage::DBI;
use DBIO::Test::Storage;
# karr #67 -- ADR 0030, second future_io refinement.
#
# t/test/16_async_future_io_convention.t (karr #65) locked in the SINGLE
# candidate rule: future_io's transport adapter is ref($storage) . '::Async',
# tried exactly once. That works for a driver storage class directly under
# DBIO::Storage::DBI, but an EXTENSION storage_type subclass (the
# DBIO::PostgreSQL::Age::Storage / DBIO::PostgreSQL::PostGIS::Storage pattern
# -- isa the driver's own storage, not DBIO::Storage::DBI directly) has no
# ::Async sibling of its own and loses future_io entirely, even for plain CRUD,
# while the 'ev' registry mode (which already walks the MRO) keeps working on
# the very same schema. This is a core resolution gap, not a driver bug.
#
# The decided fix (see karr #67, ADR 0030 refinement): the future_io