[php-src] Issue #21324: PDO\SQLite: add support for session extension

[email protected] (bohwaz)
Newsgroups php.bugs
Message-ID <qcwlHVoEjCJXMI9QEhYoC3Wv2s3bedT66irRws4Q5W0@main.internal.php.net>
Issue: https://github.com/php/php-src/issues/21324
Author: bohwaz

### Description

The session extension of SQLite provides support for creating changesets and reverting changes to a database: https://sqlite.org/sessionintro.html

Very useful for managing an app database.

It is currently enabled by default in Debian at least.

The best action would probably be to create a new PDO\SQLite\Session class:

```
PDO\SQLite\Session::__construct(PDO\SQLite $db, string $dbname = 'main')
PDO\SQLite\Session::attach(?string $table): void // pass null to attach all tables of the database
PDO\SQLite\Session::enable(?bool $enable): bool // pass null to return current enabled status
PDO\SQLite\Session::changeset(): PDO\SQLite\Session\Changeset
PDO\SQLite\Session::isEmpty(): bool
PDO\SQLite\Session::diff(string $table, string $dbname = 'main'): void
```

Deleting the session (sqlite3session_delete) would be handled when the Session object is unloaded from memory.

Starting a session would throw an exception if the session extension is not available.

By default, __construct would set `SQLITE_SESSION_OBJCONFIG_ROWID`  so that even if tables don't have a primary key they could see their changes recorded.

Here are the methods of a changeset:

```
PDO\SQLite\Session\Changeset::__construct()
PDO\SQLite\Session\Changeset::invert(): void
PDO\SQLite\Session\Changeset::load(?string $serialized_changeset = null): void // Loads an existing serialized changeset
PDO\SQLite\Session\Changeset::iterate(): Generator // iterates, for each iteration, return Change object
PDO\SQLite\Session\Changeset::__toString(): string // serialize the changeset
PDO\SQLite\Session\Changeset::add(PDO\SQLite\Session\Changeset): void // Add a changeset to another one: sqlite3changegroup_add
PDO\SQLite\Session\Changeset::addChange(PDO\SQLite\Session\Change): void // Add a single change: sqlite3changegroup_add_change
PDO\SQLite\Session\Changeset::apply(PDO\SQLite $db, ?callable $filter_callback = null, ?callable $conflict_callback = null)
PDO\SQLite\Session\Change {
  string $table;
  int $operation;
  bool $indirect;
  public function new(): array // return new values
  public function old(): array // return old values
}
```

I'm not sure about the interface of the Change object though. Probably needs more work and thought.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.