Skip to content
This repository has been archived by the owner on Apr 9, 2024. It is now read-only.

Commit

Permalink
improve import/export
Browse files Browse the repository at this point in the history
  • Loading branch information
coreyEntropy committed Jul 26, 2018
1 parent 3852780 commit 9a067d4
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 34 deletions.
20 changes: 14 additions & 6 deletions docs/GraphQLGenieAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,13 @@ const fragmentMatcher = new IntrospectionFragmentMatcher({
#### **getRawData**

```
getRawData(): Promise<any[]>
getRawData(types?: string[], context?): Promise<any[]>
```

Returns all of the data in the database, this will look a little different than what is returned by graphql. Every object will have a __typename field and relations will just be ids or an array of ids rather than objects. It will look something like:
**types** - Optional. List of the GraphQL Object Types you want data for. If null or blank all data will be returned
**context** - Optional. Context object that will be sent to input/output hooks, may be needed if using the authentication plugin

Returns data in the database, this will look a little different than what is returned by graphql. Every object will have a __typename field and relations will just be ids or an array of ids rather than objects. Also if you use interfaces and unions there may be null fields you weren't expecting on that type. It will look something like:

```json
[
Expand Down Expand Up @@ -143,17 +146,17 @@ Returns all of the data in the database, this will look a little different than
#### **importRawData**

```
importRawData(data: any[], merge = false, defaultTypename?: string): Promise
importRawData(data: any[], merge = false, defaultTypename?: string, context?): Promise
```

Import data into the store. Note any relationship fields must also either exist already or also be part of the data provided.

**data**
**data**

an array of objects to import. It can be either in the format of raw data (as exported from `getRawData` ) or in the format returned from a graphql query. Note that if it is in the format of the graphql query and __typename fields are not added the defaultTypename must be provided


**merge**
**merge** - Default = false

If false every object will create a new object, the id won't be preserved from the current data but relationships will still be built as they were in the provided data.

Expand All @@ -171,10 +174,15 @@ Note when merging list fields by default the array in the provided data will rep
}
```

**defaultTypename**
**defaultTypename** - Optional.

Must be provided if every object in data does not have a `__typename` property

**context** - Optional.

Context object that will be sent to input/output hooks, may be needed if using the authentication plugin


---

#### **getDataResolver**
Expand Down
2 changes: 1 addition & 1 deletion examples/apollo-server2-redis-jwt-auth/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "graphql-genie-redis-example",
"name": "graphql-genie-redis-example-jwt",
"version": "1.0.0",
"description": "GraphQL Genie Redis Example",
"author": "Genie Team",
Expand Down
2 changes: 1 addition & 1 deletion examples/graphql-yoga-redis-authentication/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "graphql-genie-redis-example",
"name": "graphql-genie-redis-example-session",
"version": "1.0.0",
"description": "GraphQL Genie Redis Example",
"author": "Genie Team",
Expand Down
2 changes: 1 addition & 1 deletion examples/graphql-yoga-redis-firebase-auth/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "graphql-genie-redis-example",
"name": "graphql-genie-redis-example-firebase",
"version": "1.0.0",
"description": "GraphQL Genie Redis Example",
"author": "Genie Team",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "graphql-genie",
"version": "0.3.0",
"version": "0.3.1",
"description": "GraphQL Genie",
"browser": "./lib/browser.umd.js",
"jsnext:main": "./lib/module.js",
Expand Down
38 changes: 21 additions & 17 deletions src/GraphQLGenie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ export class GraphQLGenie {
return currIDs;
}

public importRawData = async (data: any[], merge = false, defaultTypename?: string) => {
public importRawData = async (data: any[], merge = false, defaultTypename?: string, context?) => {
const meta = context ? {context} : undefined;
let index = 0;
const createPromises = [];
let createData = data;
Expand Down Expand Up @@ -301,7 +302,7 @@ export class GraphQLGenie {
});
createPromises.push(
new Promise((resolve, reject) => {
this.graphQLFortune.create(typeName, record).then(createdObj => {
this.graphQLFortune.create(typeName, record, meta).then(createdObj => {
objectsMap.set(object['id'], createdObj);
resolve(createdObj);
}).catch(reason => {
Expand Down Expand Up @@ -387,31 +388,34 @@ export class GraphQLGenie {
update['id'] = objectsMap.get(object.id)['id'];
update = this.graphQLFortune.generateUpdates(update);
// console.log(typeName, update);
updatePromies.push(this.graphQLFortune.update(typeName, update, undefined, { fortuneFormatted: true }));
updatePromies.push(this.graphQLFortune.update(typeName, update, meta, { fortuneFormatted: true }));
}
index++;
});
await Promise.all(updatePromies);
}

public getRawData = async (): Promise<any> => {
public getRawData = async (types = [], context?): Promise<any[]> => {
const meta = context ? {context} : undefined;
let nodes = [];
const result = await graphql(this.schema, `{
__schema {
types {
name
kind
if (isEmpty(types)) {
const result = await graphql(this.schema, `{
__schema {
types {
name
kind
}
}
}
}`);
const types = get(result, 'data.__schema.types');
if (types) {
const userObjects = result.data.__schema.types.filter(
}`);
types = get(result, 'data.__schema.types');
types = types.filter(
type => type.kind === 'OBJECT' && this.schemaBuilder.isUserTypeByName(type.name)
);
).map(type => type.name);
}
if (types) {
const promises = [];
userObjects.forEach(object => {
promises.push(this.graphQLFortune.find(object.name));
types.forEach(typeName => {
promises.push(this.graphQLFortune.find(typeName, undefined, undefined, meta));
});
const allData = await Promise.all(promises);
nodes = [].concat.apply([], allData); // flatten
Expand Down
12 changes: 6 additions & 6 deletions src/GraphQLGenieInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,24 +39,24 @@ export interface Features {
logicalOperators: boolean;
}
export interface DataResolver {
getLink(graphQLTypeName: string, field: string): string;
delete(graphQLTypeName: string, ids?: string[], meta?): Promise<any>;
update(graphQLTypeName: string, updates: object, meta?, options?: object): Promise<any>;
find(graphQLTypeName: string, ids?: string[], options?, meta?): Promise<any>;
create(graphQLTypeName: string, records, meta?): Promise<any>;
find(graphQLTypeName: string, ids?: string[], options?, meta?): Promise<any>;
update(graphQLTypeName: string, updates: object, meta?, options?: object): Promise<any>;
delete(graphQLTypeName: string, ids?: string[], meta?): Promise<any>;
addOutputHook(graphQLTypeName: string, hook: DataResolverOutputHook);
addInputHook(graphQLTypeName: string, hook: DataResolverInputHook);
getValueByUnique(returnTypeName: string, args, meta): Promise<Object>;
canAdd(graphQLTypeName: string, records: Object, meta): Promise<boolean>;
getConnection(allEdges: any[], before: string, after: string, first: number, last: number): Connection;
getFeatures(): Features;
applyOptions(graphQLTypeName: string, records, options, meta?);
getStore(): any;
addOutputHook(graphQLTypeName: string, hook: DataResolverOutputHook);
addInputHook(graphQLTypeName: string, hook: DataResolverInputHook);
beginTransaction(): Promise<void>;
endTransaction(): Promise<void>;
computeId(graphType: string, id?: string): string;
getTypeFromId(inputId: string): string;
getOriginalIdFromObjectId(inputId: string): string;
getLink(graphQLTypeName: string, field: string): string;
}

export interface GenerateConfig {
Expand Down
20 changes: 19 additions & 1 deletion src/tests/__tests__/genie.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ApolloClient } from 'apollo-client';
import gql from 'graphql-tag';
import { getClient } from '../setupTests';
import { genie, getClient } from '../setupTests';
let client: ApolloClient<any>;
beforeAll(async () => {
client = await getClient();
Expand Down Expand Up @@ -886,4 +886,22 @@ describe('genie', () => {
});
expect(result.data['node']['id']).toBe(testData.posts[0].id);
});

test('genie - getRawData', async () => {
const nodes = await genie.getRawData();
expect(nodes).not.toBeNull();
expect(nodes.length).toBeGreaterThan(0);
});

test('genie - getRawData Address only, then import', async () => {
let nodes = await genie.getRawData(['Address']);
expect(nodes).not.toBeNull();
expect(nodes.length).toBe(1);
nodes[0].city = 'Olympus';
await genie.importRawData(nodes, true);
nodes = await genie.getRawData(['Address']);
expect(nodes).not.toBeNull();
expect(nodes.length).toBe(1);
expect(nodes[0].city).toBe('Olympus');
});
});

0 comments on commit 9a067d4

Please sign in to comment.