@palmares/databases
v0.2.14
Published
Add support for working with databases with palmares framework
Downloads
220
Readme
@palmares/databases
Introduction
This documentation will walk you through palmares, but focusing on the @palmares/databases package.
A rough and quick intro to Palmares
The goal of palmares is to give you, the programmer, the freedom to use what you want while still maintaining a core, well defined structure. This way you can still use Drizzle or Sequelize as you already using. At the same time library maintainers like Lucia, don't need to recreate adapters for every ORM available, palmares will be the common abstraction above all. This specially useful when thinking on a framework level. We can create abstractions like Auth, Admin, Scaffolding, without needing to worry about which ORM or server you choose to use and those can work together.
What is palmares databases?
The @palmares/databases package offers you a simple API to interact with databases. Manage Schemas, access your data, relate your data. Everything you would do on a normal database.
At its core it does nothing, at the same time it does everything!
With 0 dependencies at its core (even no dependency on Node), you don't need to worry if it'll work on Expo, the Browser or even a Brain interface. Without an adapter this will simply not do anything. But with the adapter this package offers you the ability to generate migrations, query your data and offer a really nice way to interact with your database.
Although we kinda see ourselves as an ORM, we are not data frameworks as drizzle like to call others like Django or Spring. You are not forced to build your project around our structure, although we think this is preferable most of the times, you are still free to use it the way you want, on your own existing projects without any hassle or problem.
Blazingly-Fast QuickStart
If you don't have time, or is always living on the edging, just run this:
$ npx palmares@latest new db
Or kinda slow Getting Started
On your own
TIP: This QuickStart uses drizzle orm, reach out to their docs for reference
- Step 1. Install a few more packages, and don't act like you cared about the number of dependencies on your projects
$ pnpm add @palmares/node-std @palmares/drizzle-engine
$ npm i @palmares/node-std @palmares/drizzle-engine
$ yarn i @palmares/node-std @palmares/drizzle-engine
$ bun i @palmares/node-std @palmares/drizzle-engine
- Step 2. Create a
database.config.ts
with:
import {
Model,
define,
auto,
char,
text,
bool,
ON_DELETE,
setDatabaseConfig
} from '@palmares/databases';
import { NodeStd } from '@palmares/node-std';
import { DrizzleDatabaseAdapter } from '@palmares/drizzle-engine';
import { drizzle as drizzleBetterSqlite3 } from '@palmares/drizzle-engine/better-sqlite3';
import Database from 'better-sqlite3';
import type { ModelOptionsType } from '@palmares/databases'
export class Company extends Model<Company>() {
fields = {
id: auto(),
name: char({ maxLen: 255 }),
slug: char({ maxLen: 255 }),
isActive: bool().default(true)
},
options = {
tableName: 'company'
} satisfies ModelOptionsType<Company> // We use satisfies here so we can still infer and you don't lose intellisense.
}
export const User = define('User', {
fields: {
id: auto(),
firstName: char({ maxLen: 255 }),
lastName: char({ maxLen: 255 }),
email: text().allowNull(),
createdAt: date().autoNowAdd(),
companyId: foreignKey({
relatedTo: () => Company,
toField: 'id',
relationName: 'company',
relatedName: 'usersOfCompany',
onDelete: ON_DELETE.CASCADE
})
}
});
const database = new Database('sqlite.db');
const newEngine = DrizzleDatabaseAdapter.new({
output: './.drizzle/schema.ts',
type: 'better-sqlite3',
drizzle: drizzleBetterSqlite3(database),
});
export const db = newEngine[1]().instance.instance;
export default setDatabaseConfig({
databases: {
default: {
engine: newEngine,
},
},
locations: [
{
name: 'default',
// @ts-ignore
path: import.meta.dirname, // If your package.json does not contain the "type": "module" in it, change that to __dirname
getMigrations: () => [],
getModels: () => [User, Company],
},
],
std: new NodeStd(),
});
Step 3. Make your queries
- Using your Palmares models:
import './database.config'; // On this quickstart it's redundant, but make sure to initialize the DB before trying to query. import { Company, User } from './database.config'; await Company.default.set((qs) => qs .join(User, 'usersOfCompany', (qs) => qs.data( { firstName: 'Foo', lastName: 'bar', email: '[email protected]', }, { firstName: 'John', lastName: 'Doe', email: '[email protected]', } ) ) .data({ name: 'Evil Foo', slug: 'evil-foo', isActive: true, }) );
Using your favorite ORM:
- Create a file called
load.ts
and add the following (You are responsible for your own CLI):
import databasesConfig from './database.config'; databasesConfig.load();
- Run (we are using tsx to run typescript from the command line):
$ tsx load.ts
- You will see that
./.drizzle/schema.ts
file was created. You can query your models from there.
import { db } from './database.config'; import { Company } from './.drizzle/schema'; const data = await db.insert(Company).values({ name: 'Evil Foo', slug: 'evil-foo', });
- Create a file called
With Palmares:
Coming Soon...