Skip to content

Commit

Permalink
Merge af5f7a6 into 59b5cc6
Browse files Browse the repository at this point in the history
  • Loading branch information
bradleyboy committed Jan 10, 2018
2 parents 59b5cc6 + af5f7a6 commit 2d3b273
Show file tree
Hide file tree
Showing 9 changed files with 357 additions and 12 deletions.
125 changes: 125 additions & 0 deletions src/__tests__/arguments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import Sequelize from 'sequelize';
import { TEXT, INTEGER, REAL, NUMERIC, BLOB } from 'sequelize';

import {
getPkFieldKey,
makeCreateArgs,
makeUpdateArgs,
makeDeleteArgs,
makePolyArgs,
} from '../builders/arguments';
import { GraphQLString, GraphQLNonNull, GraphQLInt } from 'graphql';

const db = new Sequelize({
dialect: 'sqlite',
storage: ':memory:',
logging: false,
operatorsAliases: Sequelize.Op,
});

const model = db.define(
'posts',
{
id: {
type: INTEGER,
primaryKey: true,
},
title: {
type: TEXT,
allowNull: true,
},
userId: {
type: INTEGER,
allowNull: false,
},
},
{ timestamps: false }
);

const model2 = db.define(
'categories',
{
id: {
type: INTEGER,
primaryKey: true,
},
title: {
type: TEXT,
allowNull: true,
},
userId: {
type: INTEGER,
allowNull: false,
},
},
{ timestamps: false }
);

describe('getPkField', () => {
it('detects the primary key key', () => {
const pk = getPkFieldKey(model);
expect(pk).toBe('id');
});

it('makeCreateArgs', () => {
const args = makeCreateArgs(model);
expect(args).toEqual({
title: { type: GraphQLString },
userId: { type: new GraphQLNonNull(GraphQLInt) },
});
});

it('makeUpdateArgs', () => {
const args = makeUpdateArgs(model);
expect(args).toEqual({
id: { type: GraphQLInt },
title: { type: GraphQLString },
userId: { type: GraphQLInt },
});
});

it('makeDeleteArgs', () => {
const args = makeDeleteArgs(model);
expect(args).toEqual({
id: { type: new GraphQLNonNull(GraphQLInt) },
});
});

it('makePolyArgs', () => {
const args = makePolyArgs(model, model2);
expect(args).toEqual({
id: { type: new GraphQLNonNull(GraphQLInt) },
categoryId: { type: new GraphQLNonNull(GraphQLInt) },
});
});

it('makePolyArgs with non-equal keys', () => {
const posts = db.define(
'posts',
{
postId: {
type: INTEGER,
primaryKey: true,
},
},
{ timestamps: false }
);

const categories = db.define(
'categories',
{
categoryId: {
type: INTEGER,
primaryKey: true,
},
},
{ timestamps: false }
);

const args = makePolyArgs(posts, categories);
expect(args).toEqual({
postId: { type: new GraphQLNonNull(GraphQLInt) },
categoryId: { type: new GraphQLNonNull(GraphQLInt) },
});
});
});
4 changes: 4 additions & 0 deletions src/__tests__/associations.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ describe('join associations', () => {
options: {
through: 'post_user',
foreignKey: 'post_id',
timestamps: false,
},
},
{
Expand All @@ -100,6 +101,7 @@ describe('join associations', () => {
options: {
through: 'post_user',
foreignKey: 'user_id',
timestamps: false,
},
},
]);
Expand Down Expand Up @@ -129,6 +131,7 @@ describe('join associations', () => {
options: {
through: 'post_user',
foreignKey: 'post_id',
timestamps: false,
},
},
{
Expand All @@ -138,6 +141,7 @@ describe('join associations', () => {
options: {
through: 'post_user',
foreignKey: 'user_id',
timestamps: false,
},
},
]);
Expand Down
40 changes: 40 additions & 0 deletions src/__tests__/definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,51 @@ describe('definitions', () => {
field: 'AlbumId',
primaryKey: true,
type: TEXT,
allowNull: true,
autoIncrement: false,
defaultValue: undefined,
},
postId: {
field: 'post_id',
primaryKey: false,
type: INTEGER,
allowNull: true,
autoIncrement: false,
defaultValue: undefined,
},
});
});

it('does the thing with int pks', () => {
const results = definitions([
{
name: 'AlbumId',
pk: 1,
type: 'INTEGER',
},
{
name: 'post_id',
pk: 0,
type: 'INTEGER',
},
]);

expect(results).toEqual({
albumId: {
field: 'AlbumId',
primaryKey: true,
type: INTEGER,
allowNull: true,
autoIncrement: true,
defaultValue: undefined,
},
postId: {
field: 'post_id',
primaryKey: false,
type: INTEGER,
allowNull: true,
autoIncrement: false,
defaultValue: undefined,
},
});
});
Expand Down
6 changes: 3 additions & 3 deletions src/bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,15 @@ if (options.help) {
process.exit();
}

const app = express();

const promise = options.infile
? buildSchemaFromInfile(options.infile)
: buildSchemaFromDatabase(options.db);

if (options.schema) {
promise.then(schema => console.log(printSchema(schema)));
promise.then(schema => process.stdout.write(printSchema(schema)));
} else {
const app = express();

const message = options.infile
? `Creating in-memory database with ${options.infile}`
: `Reading schema from ${options.db}`;
Expand Down
68 changes: 68 additions & 0 deletions src/builders/arguments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { attributeFields } from 'graphql-sequelize';
import { singular } from 'pluralize';
import { GraphQLBoolean, GraphQLNonNull } from 'graphql';
import camelcase from 'camelcase';

export const getPkFieldKey = model => {
return Object.keys(model.attributes).find(key => {
const attr = model.attributes[key];
return attr.primaryKey;
});
};

export const makeCreateArgs = model => {
const fields = attributeFields(model);
const pk = getPkFieldKey(model);

delete fields[pk];

return fields;
};

export const makeUpdateArgs = model => {
const fields = attributeFields(model);

return Object.keys(fields).reduce((acc, key) => {
const field = fields[key];

if (field.type instanceof GraphQLNonNull) {
field.type = field.type.ofType;
}

acc[key] = field;
return acc;
}, fields);
};

export const makeDeleteArgs = model => {
const fields = attributeFields(model);
const pk = getPkFieldKey(model);

return { [pk]: fields[pk] };
};

export const getPolyKeys = (model, otherModel) => {
const key = getPkFieldKey(model);
const otherKey = getPkFieldKey(otherModel);

if (otherKey === key) {
return [
key,
otherKey,
camelcase(`${singular(otherModel.name)}_${otherKey}`),
];
}

return [key, otherKey, otherKey];
};

export const makePolyArgs = (model, otherModel) => {
const [key, otherKey, otherKeyFormatted] = getPolyKeys(model, otherModel);
const fields = attributeFields(model);
const otherFields = attributeFields(otherModel);

return {
[key]: fields[key],
[otherKeyFormatted]: otherFields[otherKey],
};
};
2 changes: 2 additions & 0 deletions src/builders/associations.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const formJoinTableAssociations = (a, b, aKey, bKey, table) => {
options: {
through: table,
foreignKey: aKey,
timestamps: false,
},
},
{
Expand All @@ -21,6 +22,7 @@ const formJoinTableAssociations = (a, b, aKey, bKey, table) => {
options: {
through: table,
foreignKey: bKey,
timestamps: false,
},
},
];
Expand Down
3 changes: 3 additions & 0 deletions src/builders/definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ export default (columns, tableName) => {
type: transformColumnToType(column.type),
primaryKey: column.pk === 1,
field: column.name,
allowNull: column.notnull === 0 || column.dflt_value !== null,
defaultValue: column.dflt_value,
autoIncrement: column.type === 'INTEGER' && column.pk === 1,
};

return acc;
Expand Down

0 comments on commit 2d3b273

Please sign in to comment.