Implement pointer types in postgres. (#2086)
* Support pointers in postgres * implement count * Fix bug in createClass
This commit is contained in:
@@ -103,7 +103,7 @@ describe('InstallationsRouter', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it_exclude_dbs(['postgres'])('query installations with count = 1', (done) => {
|
it('query installations with count = 1', done => {
|
||||||
var androidDeviceRequest = {
|
var androidDeviceRequest = {
|
||||||
'installationId': '12345678-abcd-abcd-abcd-123456789abc',
|
'installationId': '12345678-abcd-abcd-abcd-123456789abc',
|
||||||
'deviceType': 'android'
|
'deviceType': 'android'
|
||||||
@@ -130,10 +130,14 @@ describe('InstallationsRouter', () => {
|
|||||||
expect(response.results.length).toEqual(2);
|
expect(response.results.length).toEqual(2);
|
||||||
expect(response.count).toEqual(2);
|
expect(response.count).toEqual(2);
|
||||||
done();
|
done();
|
||||||
});
|
})
|
||||||
|
.catch(error => {
|
||||||
|
fail(JSON.stringify(error));
|
||||||
|
done();
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
it_exclude_dbs(['postgres'])('query installations with limit = 0 and count = 1', (done) => {
|
it('query installations with limit = 0 and count = 1', (done) => {
|
||||||
var androidDeviceRequest = {
|
var androidDeviceRequest = {
|
||||||
'installationId': '12345678-abcd-abcd-abcd-123456789abc',
|
'installationId': '12345678-abcd-abcd-abcd-123456789abc',
|
||||||
'deviceType': 'android'
|
'deviceType': 'android'
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ describe('Parse.Object testing', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it_exclude_dbs(['postgres'])("save cycle", function(done) {
|
it("save cycle", done => {
|
||||||
var a = new Parse.Object("TestObject");
|
var a = new Parse.Object("TestObject");
|
||||||
var b = new Parse.Object("TestObject");
|
var b = new Parse.Object("TestObject");
|
||||||
a.set("b", b);
|
a.set("b", b);
|
||||||
@@ -1478,7 +1478,7 @@ describe('Parse.Object testing', () => {
|
|||||||
expectError(Parse.Error.MISSING_OBJECT_ID, done));
|
expectError(Parse.Error.MISSING_OBJECT_ID, done));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("fetchAll error on deleted object", function(done) {
|
it_exclude_dbs(['postgres'])("fetchAll error on deleted object", function(done) {
|
||||||
var numItems = 11;
|
var numItems = 11;
|
||||||
var container = new Container();
|
var container = new Container();
|
||||||
var subContainer = new Container();
|
var subContainer = new Container();
|
||||||
|
|||||||
@@ -135,8 +135,7 @@ describe("test validate_receipt endpoint", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should fail at appstore validation", (done) => {
|
it("should fail at appstore validation", done => {
|
||||||
|
|
||||||
request.post({
|
request.post({
|
||||||
headers: {
|
headers: {
|
||||||
'X-Parse-Application-Id': 'test',
|
'X-Parse-Application-Id': 'test',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"use strict"
|
"use strict"
|
||||||
// Sets up a Parse API server for testing.
|
// Sets up a Parse API server for testing.
|
||||||
|
|
||||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = process.env.PARSE_SERVER_TEST_TIMEOUT || 3000;
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = process.env.PARSE_SERVER_TEST_TIMEOUT || 5000;
|
||||||
|
|
||||||
var cache = require('../src/cache').default;
|
var cache = require('../src/cache').default;
|
||||||
var DatabaseAdapter = require('../src/DatabaseAdapter');
|
var DatabaseAdapter = require('../src/DatabaseAdapter');
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ export class PostgresStorageAdapter {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(() => this._client.query('INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($<className>, $<schema>, true)', { className, schema }))
|
.then(() => this._client.query('INSERT INTO "_SCHEMA" ("className", "schema", "isParseClass") VALUES ($<className>, $<schema>, true)', { className, schema }))
|
||||||
|
.then(() => schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
addFieldIfNotExists(className, fieldName, type) {
|
addFieldIfNotExists(className, fieldName, type) {
|
||||||
@@ -212,7 +213,7 @@ export class PostgresStorageAdapter {
|
|||||||
// rejection reason are TBD.
|
// rejection reason are TBD.
|
||||||
getAllClasses() {
|
getAllClasses() {
|
||||||
return this._ensureSchemaCollectionExists()
|
return this._ensureSchemaCollectionExists()
|
||||||
.then(() => this._client.map('SELECT * FROM "_SCHEMA"'), null, row => ({ className: row.className, ...row.schema }));
|
.then(() => this._client.map('SELECT * FROM "_SCHEMA"', null, row => ({ className: row.className, ...row.schema })));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a promise for the schema with the given name, in Parse format. If
|
// Return a promise for the schema with the given name, in Parse format. If
|
||||||
@@ -329,6 +330,10 @@ export class PostgresStorageAdapter {
|
|||||||
updatePatterns.push(`$${index}:name = $${index + 1}`);
|
updatePatterns.push(`$${index}:name = $${index + 1}`);
|
||||||
values.push(fieldName, fieldValue);
|
values.push(fieldName, fieldValue);
|
||||||
index += 2;
|
index += 2;
|
||||||
|
} else if (fieldValue.__type === 'Pointer') {
|
||||||
|
updatePatterns.push(`$${index}:name = $${index + 1}`);
|
||||||
|
values.push(fieldName, fieldValue.objectId);
|
||||||
|
index += 2;
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject(new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, `Postgres doesn't support update ${JSON.stringify(fieldValue)} yet`));
|
return Promise.reject(new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, `Postgres doesn't support update ${JSON.stringify(fieldValue)} yet`));
|
||||||
}
|
}
|
||||||
@@ -352,7 +357,10 @@ export class PostgresStorageAdapter {
|
|||||||
let where = buildWhereClause({ schema, query, index: 2 })
|
let where = buildWhereClause({ schema, query, index: 2 })
|
||||||
values.push(...where.values);
|
values.push(...where.values);
|
||||||
|
|
||||||
const qs = `SELECT * FROM $1:name WHERE ${where.pattern} ${limit !== undefined ? `LIMIT $${values.length + 1}` : ''}`;
|
const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : '';
|
||||||
|
const limitPattern = limit !== undefined ? `LIMIT $${values.length + 1}` : '';
|
||||||
|
|
||||||
|
const qs = `SELECT * FROM $1:name ${wherePattern} ${limitPattern}`;
|
||||||
if (limit !== undefined) {
|
if (limit !== undefined) {
|
||||||
values.push(limit);
|
values.push(limit);
|
||||||
}
|
}
|
||||||
@@ -408,7 +416,14 @@ export class PostgresStorageAdapter {
|
|||||||
|
|
||||||
// Executes a count.
|
// Executes a count.
|
||||||
count(className, schema, query) {
|
count(className, schema, query) {
|
||||||
return Promise.reject('Not implemented yet.')
|
let values = [className];
|
||||||
|
let where = buildWhereClause({ schema, query, index: 2 });
|
||||||
|
values.push(...where.values);
|
||||||
|
|
||||||
|
const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : '';
|
||||||
|
const qs = `SELECT COUNT(*) FROM $1:name ${wherePattern}`;
|
||||||
|
return this._client.query(qs, values)
|
||||||
|
.then(result => parseInt(result[0].count))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -408,23 +408,25 @@ class SchemaController {
|
|||||||
return Promise.resolve(this);
|
return Promise.resolve(this);
|
||||||
}
|
}
|
||||||
// We don't have this class. Update the schema
|
// We don't have this class. Update the schema
|
||||||
return this.addClassIfNotExists(className).then(() => {
|
return this.addClassIfNotExists(className)
|
||||||
// The schema update succeeded. Reload the schema
|
// The schema update succeeded. Reload the schema
|
||||||
return this.reloadData();
|
.then(() => this.reloadData())
|
||||||
}, error => {
|
.catch(error => {
|
||||||
// The schema update failed. This can be okay - it might
|
// The schema update failed. This can be okay - it might
|
||||||
// have failed because there's a race condition and a different
|
// have failed because there's a race condition and a different
|
||||||
// client is making the exact same schema update that we want.
|
// client is making the exact same schema update that we want.
|
||||||
// So just reload the schema.
|
// So just reload the schema.
|
||||||
return this.reloadData();
|
return this.reloadData();
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
// Ensure that the schema now validates
|
// Ensure that the schema now validates
|
||||||
if (this.data[className]) {
|
if (this.data[className]) {
|
||||||
return this;
|
return this;
|
||||||
} else {
|
} else {
|
||||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `Failed to add ${className}`);
|
throw new Parse.Error(Parse.Error.INVALID_JSON, `Failed to add ${className}`);
|
||||||
}
|
}
|
||||||
}, error => {
|
})
|
||||||
|
.catch(error => {
|
||||||
// The schema still doesn't validate. Give up
|
// The schema still doesn't validate. Give up
|
||||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'schema class name does not revalidate');
|
throw new Parse.Error(Parse.Error.INVALID_JSON, 'schema class name does not revalidate');
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user