Skip to content

Commit

Permalink
feat: support n:m relationships
Browse files Browse the repository at this point in the history
fix: do not serialize empty hasMany relationships

fix: n:m queries not executing correctly
  • Loading branch information
zacharygolba committed Jun 12, 2016
1 parent 93e3c0a commit 2d0f2ef
Show file tree
Hide file tree
Showing 13 changed files with 317 additions and 153 deletions.
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ test/*
node_modules/*

# misc
decl/*
examples/*
interfaces/*
7 changes: 7 additions & 0 deletions decl/proxy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare class Proxy<T> {
constructor(target: T, handler: {
get?: (target: T, key: string, reciever: Proxy) => ?mixed | void;
set?: (target: T, key: string, value: mixed, receiver: Proxy) => void;
has?: (target: T, key: string) => boolean;
}): T;
}
14 changes: 7 additions & 7 deletions src/packages/application/initialize.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,16 @@ export default async function initialize(app: Application, {
logger
});

const store = new Database({
logger,
const store = await new Database({
path,
config: database
models,
logger,
config: database,
checkMigrations: true
});

Object.freeze(store);

Object.defineProperties(app, {
path: {
value: path,
Expand Down Expand Up @@ -95,10 +99,6 @@ export default async function initialize(app: Application, {
}
});

await store.define(models);

Object.freeze(store);

Object.assign(app, {
models,
controllers,
Expand Down
9 changes: 5 additions & 4 deletions src/packages/cli/commands/db-migrate.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Database, { createMigrations, pendingMigrations } from '../../database';
import Database, { pendingMigrations } from '../../database';
import Logger, { sql } from '../../logger';
import loader from '../../loader';

Expand All @@ -9,20 +9,21 @@ const { env: { PWD } } = process;
*/
export default async function dbMigrate() {
const { database: config } = loader(PWD, 'config');
const models = loader(PWD, 'models');
const migrations = loader(PWD, 'migrations');

const { connection, schema } = new Database({
const { connection, schema } = await new Database({
config,
models,
path: PWD,
checkMigrations: false,

logger: await new Logger({
path: PWD,
enabled: false
})
});

await createMigrations(schema);

const pending = await pendingMigrations(PWD, () => connection('migrations'));

if (pending.length) {
Expand Down
9 changes: 5 additions & 4 deletions src/packages/cli/commands/db-rollback.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Database, { createMigrations } from '../../database';
import Database from '../../database';
import Logger, { sql } from '../../logger';
import fs from '../../fs';
import loader from '../../loader';
Expand All @@ -10,20 +10,21 @@ const { env: { PWD } } = process;
*/
export default async function dbRollback() {
const { database: config } = loader(PWD, 'config');
const models = loader(PWD, 'models');
const migrations = loader(PWD, 'migrations');

const { connection, schema } = new Database({
const { connection, schema } = await new Database({
config,
models,
path: PWD,
checkMigrations: false,

logger: await new Logger({
path: PWD,
enabled: false
})
});

await createMigrations(schema);

const migrationFiles = await fs.readdirAsync(`${PWD}/db/migrate`);

if (migrationFiles.length) {
Expand Down
3 changes: 2 additions & 1 deletion src/packages/cli/commands/db-seed.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ export default async function dbSeed() {

await new Database({
config,
models,
path: PWD,

logger: await new Logger({
path: PWD,
enabled: false
})
}).define(models);
});

await seed();
}
115 changes: 16 additions & 99 deletions src/packages/database/index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
// @flow
import { worker, isMaster } from 'cluster';

import {
ModelMissingError,
MigrationsPendingError
} from './errors';
import { ModelMissingError } from './errors';

import Logger from '../logger';
import Model, { initialize } from './model';

import connect from './utils/connect';
import createMigrations from './utils/create-migrations';
import pendingMigrations from './utils/pending-migrations';
import Model from './model';

const { env: { NODE_ENV = 'development' } } = process;
import initialize from './initialize';

/**
* @private
Expand All @@ -31,70 +22,28 @@ class Database {

connection: any;

models: Map<string, typeof Model> = new Map();
models: Map<string, typeof Model>;

constructor({
path,
models,
config,
logger,
} : {
checkMigrations
}: {
path: string,
models: Map<string, typeof Model>,
config: Object,
logger: Logger,
} = {}): Database {
config = config[NODE_ENV];

const {
debug = (NODE_ENV === 'development')
}: {
debug: boolean
} = config;

Object.defineProperties(this, {
path: {
value: path,
writable: false,
enumerable: false,
configurable: false
},

debug: {
value: debug,
writable: false,
enumerable: false,
configurable: false
},

logger: {
value: logger,
writable: false,
enumerable: false,
configurable: false
},

config: {
value: config,
writable: false,
enumerable: true,
configurable: false
},

schema: {
value: () => this.connection.schema,
writable: false,
enumerable: false,
configurable: false
},

connection: {
value: connect(path, config),
writable: false,
enumerable: false,
configurable: false
}
checkMigrations: boolean
} = {}): Promise<Database> {
return initialize(this, {
path,
models,
config,
logger,
checkMigrations
});

return this;
}

modelFor(type: string): typeof Model {
Expand All @@ -106,38 +55,6 @@ class Database {

return model;
}

async define(
models: Map<string, typeof Model>
): Promise<Model[]> {
const { path, connection, schema } = this;

if (isMaster || worker && worker.id === 1) {
await createMigrations(schema);

const pending = await pendingMigrations(path, () => {
return connection('migrations');
});

if (pending.length) {
throw new MigrationsPendingError(pending);
}
}

models.forEach((model, name) => {
this.models.set(name, model);
});

return await Promise.all(
Array
.from(models.values())
.map(model => {
return initialize(this, model, () => {
return connection(model.tableName);
});
})
);
}
}

export { default as connect } from './utils/connect';
Expand Down
116 changes: 116 additions & 0 deletions src/packages/database/initialize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// @flow
import { worker, isMaster } from 'cluster';

import { MigrationsPendingError } from './errors';

import connect from './utils/connect';
import createMigrations from './utils/create-migrations';
import pendingMigrations from './utils/pending-migrations';

import type Database from './index';
import type Logger from '../logger';
import typeof Model from './model';

const { env: { NODE_ENV = 'development' } } = process;

/**
* @private
*/
export default async function initialize(instance: Database, {
path,
models,
config,
logger,
checkMigrations
}: {
path: string,
models: Map<string, Model>,
config: Object,
logger: Logger,
checkMigrations: boolean
}): Promise<Database> {
config = config[NODE_ENV];

const {
debug = (NODE_ENV === 'development')
}: {
debug: boolean
} = config;

Object.defineProperties(instance, {
path: {
value: path,
writable: false,
enumerable: false,
configurable: false
},

debug: {
value: debug,
writable: false,
enumerable: false,
configurable: false
},

models: {
value: models,
writable: false,
enumerable: false,
configurable: false
},

logger: {
value: logger,
writable: false,
enumerable: false,
configurable: false
},

config: {
value: config,
writable: false,
enumerable: true,
configurable: false
},

schema: {
value: () => instance.connection.schema,
writable: false,
enumerable: false,
configurable: false
},

connection: {
value: connect(path, config),
writable: false,
enumerable: false,
configurable: false
}
});

if (isMaster || worker && worker.id === 1) {
await createMigrations(instance.schema);

if (checkMigrations) {
const pending = await pendingMigrations(path, () => {
return instance.connection('migrations');
});

if (pending.length) {
throw new MigrationsPendingError(pending);
}
}
}

await Promise.all(
Array
.from(models.values())
.map(model => {
return model.initialize(instance, () => {
return instance.connection(model.tableName);
});
})
);

return instance;
}
Loading

0 comments on commit 2d0f2ef

Please sign in to comment.