Yote-SQLObjectStore
view release on metacpan or search on metacpan
Arrays are tied Perl arrays backed by the database:
```perl
my $arr = $store->new_array( '*ARRAY_VARCHAR(200)', 'first', 'second' );
push @$arr, 'third';
my $val = $arr->[0];
my $len = scalar @$arr;
my $popped = pop @$arr;
splice @$arr, 1, 1, 'replaced';
```
### Reference Collections
Collections can hold object references instead of scalar values:
```perl
my $ref_hash = $store->new_hash( '*HASH<256>_*MyApp::User' );
$ref_hash->{alice} = $user;
my $ref_arr = $store->new_array( '*ARRAY_*MyApp::Post' );
push @$ref_arr, $post;
```
Use `*` as the value type to allow any reference type:
```perl
my $anything = $store->new_hash( '*HASH<256>_*' );
$anything->{user} = $user;
$anything->{posts} = $ref_arr;
```
## Path-Based Access
You can navigate the object tree using path strings, starting from the root:
```perl
# Fetch values by path
my $email = $store->fetch_string_path( '/users/alice/email' );
my $post = $store->fetch_string_path( '/users/alice/posts/0' );
# Check if a path exists
if ($store->has_path( 'users', 'alice' )) { ... }
# Delete a value at a path
$store->del_string_path( '/users/alice/bio' );
```
### ensure_path
`ensure_path` navigates a path, creating objects along the way if they don't exist:
```perl
# Ensure a scalar value exists
$store->ensure_path( '/settings/site_name|My Site' );
# Ensure an object exists (creates it if missing)
my $bob = $store->ensure_path( '/users/bob|MyApp::User' );
# Ensure a hash exists
my $prefs = $store->ensure_path( '/users/alice/prefs|*HASH<256>_VARCHAR(256)' );
# String path format: /key|type_or_value/key|type_or_value
```
### ensure_paths
Ensure multiple paths atomically in a transaction. If any path fails, none are applied:
```perl
$store->ensure_paths(
'/settings/version|1.0',
'/settings/mode|production',
);
```
### set_path
Set a value at a path (path must already exist up to the parent):
```perl
$store->set_path( 'users', 'charlie',
$store->new_obj('MyApp::User', name => 'charlie') );
```
## Finder Methods
Query objects by their scalar fields:
```perl
# Find one object by field value
my $user = $store->find_by( 'MyApp::User', 'email', 'alice@example.com' );
# Find all matching objects
my @active = $store->find_all_by( 'MyApp::User', 'status', 'active',
order_by => 'name ASC',
limit => 10,
offset => 0,
);
# Find with multiple criteria (AND logic)
my @admins = $store->find_where( 'MyApp::User',
role => 'admin',
active => 1,
_order_by => 'name ASC',
_limit => 50,
);
# Find single match with _single
my $user = $store->find_where( 'MyApp::User',
email => 'alice@example.com',
_single => 1,
);
```
Only scalar fields (not reference fields) can be searched.
## Schema Evolution
When you change `%cols` in a package, run `make_all_tables` again. The table manager detects differences and generates ALTER TABLE statements:
( run in 2.135 seconds using v1.01-cache-2.11-cpan-98e64b0badf )