@next-model/mariadb-connector
v1.2.0
Published
Native MariaDB connector for next-model. Extends @next-model/mysql-connector and uses MariaDB's RETURNING clause.
Readme
@next-model/mariadb-connector
Native MariaDB connector for @next-model/core, built as a thin extension of @next-model/mysql-connector.
Why a separate package?
MariaDB is wire-compatible with MySQL, so mysql2 connects to it without modification. The reason this connector exists is what MariaDB lets us do server-side that MySQL doesn't:
INSERT … RETURNING *(MariaDB 10.5+) andDELETE … RETURNING *(MariaDB 10.0+). The MySQL connector has to issue an extraSELECTto capture affected rows and expandinsertIdto consecutive ids forbatchInsert; this connector skips that dance for those two cases.UPDATEis the gap: MariaDB does not supportUPDATE … RETURNING, soupdateAllfalls through to the inherited SELECT-then-UPDATE.- JSON validation without a native
JSONtype — MariaDB'sJSONis an alias forLONGTEXT, so we emitLONGTEXT CHECK (JSON_VALID(...)), which gives back the validation guarantee.
Everything else (identifier quoting, filter compilation, transactions, the rest of the schema DSL) is inherited from @next-model/mysql-connector.
When to pick this over @next-model/mysql-connector
- You're targeting MariaDB ≥ 10.5 and want the cleaner / faster code path that
RETURNINGmakes possible. - You want native
JSON_VALIDenforcement ont.json(...)columns.
If you might switch between MySQL and MariaDB at runtime, the MySQL connector still works against MariaDB — you just lose the RETURNING shortcut.
Installation
pnpm add @next-model/mariadb-connector mysql2
# or: npm install @next-model/mariadb-connector mysql2Constructing the connector
import { MariaDbConnector } from '@next-model/mariadb-connector';
const connector = new MariaDbConnector('mariadb://app:secret@host:3306/myapp');
await connector.destroy();Pass an optional extras: { schema } second arg to attach a DatabaseSchema (from @next-model/core's defineSchema(...)) so Model({ connector, tableName: 'users' }) can infer per-table props at the type level:
const connector = new MariaDbConnector(process.env.DATABASE_URL!, { schema });The constructor signature, pool config, and runtime API are otherwise identical to MysqlConnector's — see its README for the full surface.
What the override actually does
import { MysqlConnector, quoteIdent } from '@next-model/mysql-connector';
class MariaDbConnector extends MysqlConnector {
async batchInsert(table, _keys, items) {
// INSERT … RETURNING * — one round-trip, no consecutive-id trick
}
async deleteAll(scope) {
// DELETE … RETURNING * — no SELECT capture
}
// updateAll is inherited (MariaDB has no UPDATE ... RETURNING).
}batchInsert previously needed:
INSERT INTO … VALUES (…), (…)- read
insertId(= first auto-increment id) - compute
[firstId, firstId+1, …] SELECT * … WHERE id IN (…)to re-fetch
Now it's just step 1 with RETURNING *. Same pattern for updateAll / deleteAll.
Schema reflection (reflectSchema)
Inherited verbatim from MysqlConnector — MariaDB's information_schema views (TABLES, COLUMNS, STATISTICS) are wire-compatible with MySQL's, so the parent's introspection path works as-is. Returns a TableDefinition[] for every base table in the current DATABASE(). The result feeds straight into generateSchemaSource(...) from @next-model/core for end-to-end nm-generate-migration schema-from-db reflection.
Testing matrix
CI runs the shared runModelConformance suite (every Model feature) plus RETURNING-specific assertions against a real MariaDB 11 service container.
Locally:
DATABASE_URL=mysql://root:[email protected]:3306/test pnpm --filter @next-model/mariadb-connector testChangelog
See HISTORY.md.
