Configuration - Getting Started

This guide is for Northwind Studio developers wiring DeskFlow’s database layer before TaskService and MemberService touch real rows. You will configure [db] in settings.ini, then query tasks, projects, and team_members with table() on port 8000.

What you will learn

  • Register default and named connections in environment/settings.ini
  • Call table(), db(), and connectionManager() from DeskFlow services
  • Use table aliases and column casts when listing Northwind data
Before you start

How it works

environment/settings.ini  →  [db] section discovered at boot
connectionManager()  →  pooled PDO per process
table('tasks')  →  Porm  →  Piql (prepared statements)

What is Porm?

Porm is Pionia’s database access layer. It exposes a fluent API similar to Medoo with prepared statements under the hood.

  • No Eloquent-style models — query tables directly.
  • Works with new or legacy schemas.
  • Included in every Pionia app — use table() / db() from day one.

Entry points

HelperReturnsPurpose
table($name, $alias, $connection)Pionia\Porm\Core\PormPrimary API
db(...)same as table()Alias
connectionManager()ConnectionManagerPooled PDO per process
table('tasks');                           // default connection
table('tasks', 't');                      // tasks AS t
table('tasks', null, 'db_pgsql');         // section name from settings.ini

Db::table() and Db::from() exist on Pionia\Porm\Database\Db but apps should prefer the global helpers.

Configuration (settings.ini)

Database sections are auto-discovered when they define a driver + database name. Example environment/settings.ini:

[db]
database_type = "sqlite"
database_name = "database.sqlite3"
default = 1

[db_pgsql]
database_type = "pgsql"
database_name = "deskflow"
username = "app"
host = "localhost"
port = 5432
; Store DB_PASSWORD in environment/.env — do not commit real credentials
# environment/.env (gitignored)
DB_PASSWORD=your-local-password

Recognized keys

KeyAliasesNotes
database_typetypemysql, pgsql, sqlite, mssql, oracle, sybase
database_namedatabaseDatabase name or SQLite file path
hostserver
username, password, port, socket
charset, collation, prefixTable prefix in SQL
defaultdefault=1Marks the default connection
loggingPer-connection query logging
testModeSkip real PDO (tests)
pdoInject an existing PDO instance

Environment overrides: LOG_QUERIES / SHOW_QUERIES enable logging on the connection.

Supported databases

DriverPHP extension
mysql / MariaDBpdo_mysql
pgsqlpdo_pgsql
sqlitepdo_sqlite
mssqlpdo_sqlsrv or pdo_dblib
oraclepdo_oci
sybasepdo_dblib

Multiple connections

Register sections as [db], [db_pgsql], etc. Pass the section name (without brackets) as the third argument to table():

table('projects', null, 'db_pgsql')->get(1);

See Connections for pooling, Connection::connect() vs open(), and RoadRunner workers.

Table & columns

table('tasks', 't')
    ->columns(['t.id', 't.title'])
    ->filter(['status' => 'open'])
    ->all();

Column alias in SELECT: column_name(alias) — e.g. 'p.name(project_name)' returns project_name in the result.

Type casts on read: suffix [Int], [Bool], [JSON], [Object] on column names (use [Object] only with trusted data).

Last insert ID & debugging

$porm = table('tasks');
$porm->save(['title' => 'Ship DeskFlow v1', 'project_id' => 1]);
$id = $porm->lastSaved();   // or Piql::id() via getDatabase()

$sql = $porm->lastQuery();    // last interpolated SQL string
$piql = $porm->getDatabase(); // low-level Piql engine (advanced)

Piql (advanced)

$porm->getDatabase() returns Pionia\Porm\Core\Piql. Application code should use table() chains; Piql is for framework contributors and debugging (debug(), log()).

Next: Making queries.

Common mistakes

  • Committing DB_PASSWORD to git — keep credentials in environment/.env for alex@northwind.studio’s local DeskFlow setup.
  • Using Db::from() in services — global table() is the supported entry point in v3.
  • Forgetting default = 1 on [db] — without a default section, table('tasks') has nowhere to connect.
  • Passing the bracketed section name — use 'db_pgsql', not '[db_pgsql]', as the third table() argument.

What’s next

Making queries

get, save, update on tasks.

Connections

Pooling under RoadRunner.

Filtering

Builder mode after filter().