Skip to content

Commit

Permalink
Merge pull request #283 from palmaresHQ:databases-migration-issues
Browse files Browse the repository at this point in the history
Databases-migration-issues
  • Loading branch information
nicolasmelo1 authored Nov 10, 2024
2 parents c1daa6b + 9268a32 commit 84dac05
Show file tree
Hide file tree
Showing 23 changed files with 259 additions and 45 deletions.
9 changes: 9 additions & 0 deletions .changeset/sharp-glasses-melt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@palmares/databases': patch
'@palmares/core': patch
'@palmares/drizzle-engine': patch
'@palmares/sequelize-engine': patch
---

- Fix docs with better explanation on how to use palmares/databases when on standalone.
- Fixed standalone to add palmares_migrations table when the engine runs.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
"build:watch": "turbo run build:watch --concurrency 20",
"build:watch:tests": "turbo run build:watch --filter=@palmares/core --filter=@palmares/tests --filter=@palmares/jest-tests",
"build:watch:schemas": "turbo run build:watch --filter=@palmares/core --filter=@palmares/schemas --filter=@palmares/zod-schema",
"build:watch:databases": "turbo run build:watch --filter=@palmares/core --filter=@palmares/databases",
"build:watch:databases": "turbo run build:watch --filter=@palmares/core --filter=@palmares/databases --filter=@palmares/sequelize-engine --filter=@palmares/drizzle-engine",
"build:watch:databases:sequelize": "turbo run build:watch --filter=@palmares/core --filter=@palmares/databases --filter=@palmares/sequelize-engine",
"build:watch:databases:drizzle": "turbo run build:watch --filter=@palmares/core --filter=@palmares/databases --filter=@palmares/drizzle-engine",
"build:watch:server": "turbo run build:watch --filter=@palmares/core --filter=@palmares/server --filter=@palmares/express-adapter",
"dev": "turbo run dev --parallel",
"examples:server-express-only": "turbo run dev --parallel --filter=@examples/server-express-only --filter=@palmares/*",
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/conf/exceptions.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
export class SettingsNotFoundException extends Error {
constructor() {
super(
`No settings file was found for the application.\nMake sure you either pass an option through:` +
`\n-'Command.handleCommands'\n-PALMARES_SETTINGS_MODULE environment variable\n-Or inside` +
` 'src' folder in the root directory`
`No settings file was found for the application.\nMake sure you either pass an option through` +
`'Command.handleCommands'`
);
}
}
2 changes: 2 additions & 0 deletions packages/core/src/conf/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ export async function setSettings(
let settings = undefined;
if (settingsOrStd instanceof Promise) {
const awaitedSettingsOrSrd = await settingsOrStd;
// eslint-disable-next-line ts/no-unnecessary-condition
if (awaitedSettingsOrSrd === undefined) throw new SettingsNotFoundException();
if ('files' in awaitedSettingsOrSrd.default) await extractSettingsFromPath(awaitedSettingsOrSrd.default);
else {
settings = awaitedSettingsOrSrd.default;
Expand Down
23 changes: 16 additions & 7 deletions packages/databases/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The [@palmares/databases](https://www.npmjs.com/package/@palmares/databases) pac

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. 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.
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.

Expand All @@ -24,7 +24,16 @@ Although we kinda see ourselves as an ORM, we are not **data frameworks** as dri

**TIP:** This QuickStart uses [drizzle orm, reach out to their docs for reference](https://orm.drizzle.team/docs/overview)

- **Step 1**. Create a `database.config.ts` with:
- **Step 1**. Install a few more packages, and don't act like you cared about the number of dependencies on your projects

```sh
$ 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:

```ts
import {
Expand Down Expand Up @@ -103,11 +112,13 @@ export default setDatabaseConfig({
});
```

- **Step 2**. Make your queries
- **Step 3**. Make your queries

- **Using your Palmares models:**

```ts
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) =>
Expand All @@ -118,13 +129,11 @@ export default setDatabaseConfig({
firstName: 'Foo',
lastName: 'bar',
email: '[email protected]',
isActive: true,
},
{
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
isActive: true,
}
)
)
Expand All @@ -138,15 +147,15 @@ export default setDatabaseConfig({

- **Using your favorite ORM**:

1. Create a file called `load.ts` and add the following:
1. Create a file called `load.ts` and add the following (You are responsible for your own CLI):

```ts
import databasesConfig from './database.config';
databasesConfig.load();
```

2. Run (we are using to run typescript from the command line [tsx](https://tsx.is/)):
2. Run (we are using [tsx](https://tsx.is/) to run typescript from the command line):

```sh
$ tsx load.ts
Expand Down
4 changes: 3 additions & 1 deletion packages/databases/__tests__/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"sqlize:test": "tsx --experimental-vm-modules manage.sequelize.ts test",
"sqlize:makemigrations": "tsx manage.sequelize.ts makemigrations",
"sqlize:migrate": "tsx manage.sequelize.ts migrate",
"standalone": "tsx ./src/standalone.ts"
"standalone:drzle": "tsx ./src/standalone.ts",
"standalone:sqlize:makemigrations": "tsx ./src/standalone/sequelize/makemigrations.ts",
"standalone:sqlize:migrate": "tsx ./src/standalone/sequelize/migrate.ts"
},
"keywords": [],
"author": "",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { setDatabaseConfig } from '@palmares/databases';
import { NodeStd } from '@palmares/node-std';
import { SequelizeEngine } from '@palmares/sequelize-engine';
import * as migrations from './migrations';

import { Company, User } from './models';

export default setDatabaseConfig({
databases: {
default: {
engine: SequelizeEngine.new({
dialect: 'sqlite',
storage: './standalone.sequelize.db',
}),
},
},
locations: [
{
name: 'default',
path: import.meta.dirname,
getMigrations: () => migrations,
getModels: () => [User, Company],
},
],
std: new NodeStd(),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import db from './database.config';

db.makeMigrations({});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import db from './database.config';

db.migrate({});
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* prettier-ignore-start */

/* eslint-disable */

// @ts-nocheck

// noinspection JSUnusedGlobalSymbols

/**
* Automatically generated by palmares on 2024-11-10T14:38:35.815Z
*/

import { models, actions } from '@palmares/databases';


export default {
name: '002_default_auto_migration_1731249515815',
database: 'default',
dependsOn: 'create_palmares_migration_table',
operations: [
new actions.CreateModel(
"Company",
{
id: models.fields.AutoField.new().primaryKey(true).allowNull(true).unique(true).dbIndex(true).databaseName("id").underscored(true).setCustomAttributes({}),
name: models.fields.CharField.new({ maxLen: 255 }).primaryKey(false).allowNull(false).unique(false).dbIndex(false).databaseName("name").underscored(true).setCustomAttributes({}).allowBlank(false),
slug: models.fields.CharField.new({ maxLen: 255 }).primaryKey(false).allowNull(false).unique(false).dbIndex(false).databaseName("slug").underscored(true).setCustomAttributes({}).allowBlank(false),
isActive: models.fields.BooleanField.new().primaryKey(false).default(true).allowNull(false).unique(false).dbIndex(false).databaseName("is_active").underscored(true).setCustomAttributes({})
},
{
abstract: false,
underscored: true,
tableName: "company",
managed: true,
ordering: [],
indexes: [],
databases: ["default"],
customOptions: {}
}
),
new actions.CreateModel(
"User",
{
id: models.fields.AutoField.new().primaryKey(true).allowNull(true).unique(true).dbIndex(true).databaseName("id").underscored(true).setCustomAttributes({}),
firstName: models.fields.CharField.new({ maxLen: 255 }).primaryKey(false).allowNull(false).unique(false).dbIndex(false).databaseName("first_name").underscored(true).setCustomAttributes({}).allowBlank(false),
lastName: models.fields.CharField.new({ maxLen: 255 }).primaryKey(false).allowNull(false).unique(false).dbIndex(false).databaseName("last_name").underscored(true).setCustomAttributes({}).allowBlank(false),
email: models.fields.TextField.new().primaryKey(false).allowNull(true).unique(false).dbIndex(false).databaseName("email").underscored(true).setCustomAttributes({}).allowBlank(false),
companyId: models.fields.ForeignKeyField.new({relatedTo: "Company", toField: "id", onDelete: models.fields.ON_DELETE.CASCADE, relationName: "company", relatedName: "undefined"}).primaryKey(false).allowNull(false).unique(false).dbIndex(false).databaseName("company_id").underscored(true).setCustomAttributes({})
},
{
abstract: false,
underscored: true,
tableName: undefined,
managed: true,
ordering: [],
indexes: [],
databases: ["default"],
customOptions: {}
}
)
]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as M002_default_auto_migration_1731249515815 } from './002_default_auto_migration_1731249515815';
44 changes: 44 additions & 0 deletions packages/databases/__tests__/src/standalone/sequelize/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {
Model,
define,
auto,
char,
text,
bool,
ON_DELETE,
foreignKey
} from '@palmares/databases';

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(),
companyId: foreignKey({
relatedTo: () => Company,
toField: 'id',
relationName: 'company',
relatedName: 'usersOfCompany',
onDelete: ON_DELETE.CASCADE
})
},
options: {
tableName: 'user'
}
});
Binary file not shown.
12 changes: 12 additions & 0 deletions packages/databases/docs/consumers/getting-started/on-your-own.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ Let's go over it?

- **std** - The dependency from the runtime you are using to build your applications on.

## Now let's guarantee that the database is initialized when using

You found the root of your project. It is `index.ts` or `app.ts`, whatever. It's the first file that runs when your application runs.

Now make sure to add this on the root of that file.

```ts
import './database.config';
```

This will guarantee that when your code gets executed all of the models are translated.

## Up Next

- [Migrating the Changes](https://github.com/palmaresHQ/palmares/blob/main/packages/databases/docs/consumers/getting-started/migrating-the-changes.md)
23 changes: 16 additions & 7 deletions packages/databases/docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The [@palmares/databases](https://www.npmjs.com/package/@palmares/databases) pac

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. 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.
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.

Expand All @@ -24,7 +24,16 @@ Although we kinda see ourselves as an ORM, we are not **data frameworks** as dri

**TIP:** This QuickStart uses [drizzle orm, reach out to their docs for reference](https://orm.drizzle.team/docs/overview)

- **Step 1**. Create a `database.config.ts` with:
- **Step 1**. Install a few more packages, and don't act like you cared about the number of dependencies on your projects

```sh
$ 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:

```ts
import {
Expand Down Expand Up @@ -103,11 +112,13 @@ export default setDatabaseConfig({
});
```

- **Step 2**. Make your queries
- **Step 3**. Make your queries

- **Using your Palmares models:**

```ts
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) =>
Expand All @@ -118,13 +129,11 @@ export default setDatabaseConfig({
firstName: 'Foo',
lastName: 'bar',
email: '[email protected]',
isActive: true,
},
{
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
isActive: true,
}
)
)
Expand All @@ -138,15 +147,15 @@ export default setDatabaseConfig({

- **Using your favorite ORM**:

1. Create a file called `load.ts` and add the following:
1. Create a file called `load.ts` and add the following (You are responsible for your own CLI):

```ts
import databasesConfig from './database.config';
databasesConfig.load();
```

2. Run (we are using to run typescript from the command line [tsx](https://tsx.is/)):
2. Run (we are using [tsx](https://tsx.is/) to run typescript from the command line):

```sh
$ tsx load.ts
Expand Down
6 changes: 3 additions & 3 deletions packages/databases/src/databases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,12 @@ export class Databases {
const modelInstance = new foundModel.model();
const isModelManagedByEngine =
// eslint-disable-next-line ts/no-unnecessary-condition
modelInstance.options?.abstract !== true &&
foundModel.model['_options'](modelInstance)?.abstract !== true &&
// eslint-disable-next-line ts/no-unnecessary-condition
modelInstance.options?.managed !== false &&
foundModel.model['_options'](modelInstance)?.managed !== false &&
// eslint-disable-next-line ts/no-unnecessary-condition
(Array.isArray(modelInstance.options?.databases) === false ||
modelInstance.options.databases.includes(engineName) === true);
foundModel.model['_options'](modelInstance).databases.includes(engineName) === true);

const modelName =
(foundModel.model as unknown as typeof BaseModel & typeof Model)['__getName']() ||
Expand Down
1 change: 1 addition & 0 deletions packages/databases/src/migrations/actions/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export class CreateModel extends Operation {
returnOfInit: any
): Promise<void> {
const toModel = toState[this.modelName];

await engineInstance.migrations?.addModel(engineInstance, toModel, migration, returnOfInit);
}

Expand Down
Loading

0 comments on commit 84dac05

Please sign in to comment.