Commit b87b4aab authored by Sandro Lutz's avatar Sandro Lutz
Browse files

Add Query utility class

parent 7b6546c4
...@@ -2,6 +2,7 @@ import m from 'mithril'; ...@@ -2,6 +2,7 @@ import m from 'mithril';
import { apiUrl } from 'config'; import { apiUrl } from 'config';
import { getToken, getUserId } from './auth'; import { getToken, getUserId } from './auth';
import { error } from './log'; import { error } from './log';
import Query from './query';
let querySaved = ''; let querySaved = '';
...@@ -96,7 +97,7 @@ export function withdraw(groupMembershipId, etag) { ...@@ -96,7 +97,7 @@ export function withdraw(groupMembershipId, etag) {
* @return {Promise} exports for additional response handling * @return {Promise} exports for additional response handling
*/ */
export function load(query = {}) { export function load(query = {}) {
const queryEncoded = m.buildQueryString({ where: JSON.stringify(query) }); const queryEncoded = Query.buildQueryString({ where: query });
querySaved = query; querySaved = query;
return m return m
...@@ -123,9 +124,9 @@ export function load(query = {}) { ...@@ -123,9 +124,9 @@ export function load(query = {}) {
* @return {Promise} exports for additional response handling * @return {Promise} exports for additional response handling
*/ */
export function loadMemberships() { export function loadMemberships() {
const queryEncoded = m.buildQueryString({ const queryEncoded = Query.buildQueryString({
where: JSON.stringify({ user: getUserId() }), where: { user: getUserId() },
embedded: JSON.stringify({ group: 1 }), embedded: { group: 1 },
}); });
return m return m
.request({ .request({
......
...@@ -2,6 +2,7 @@ import m from 'mithril'; ...@@ -2,6 +2,7 @@ import m from 'mithril';
import { apiUrl } from 'config'; import { apiUrl } from 'config';
import { getToken } from './auth'; import { getToken } from './auth';
import { currentLanguage } from './language'; import { currentLanguage } from './language';
import Query from './query';
const date = `${new Date().toISOString().split('.')[0]}Z`; const date = `${new Date().toISOString().split('.')[0]}Z`;
...@@ -35,14 +36,9 @@ export function getSelectedOffer() { ...@@ -35,14 +36,9 @@ export function getSelectedOffer() {
* @return {Promise} exports for additional response handling * @return {Promise} exports for additional response handling
*/ */
export function load(query = {}) { export function load(query = {}) {
querySaved = query; querySaved = Query.copy(query);
// Parse query such that the backend understands it const queryString = Query.buildQueryString(query);
const parsedQuery = {};
Object.keys(query).forEach(key => {
parsedQuery[key] = key === 'sort' ? query[key] : JSON.stringify(query[key]);
});
const queryString = m.buildQueryString(parsedQuery);
return m return m
.request({ .request({
......
import m from 'mithril'; import m from 'mithril';
import { apiUrl } from 'config'; import { apiUrl } from 'config';
import { getToken } from './auth'; import { getToken } from './auth';
import Query from './query';
/** /**
* PaginationController class * PaginationController class
...@@ -22,6 +23,7 @@ export default class PaginationController { ...@@ -22,6 +23,7 @@ export default class PaginationController {
this.additionalQuery = additionalQuery; this.additionalQuery = additionalQuery;
this._lastLoadedPage = 0; this._lastLoadedPage = 0;
this._totalPages = 1; this._totalPages = 1;
this._pages = [];
} }
/** /**
...@@ -50,7 +52,7 @@ export default class PaginationController { ...@@ -50,7 +52,7 @@ export default class PaginationController {
* @public * @public
*/ */
setQuery(query) { setQuery(query) {
this.query = JSON.parse(JSON.stringify(query || {})); this.query = Query.copy(query || {});
this._pages = []; this._pages = [];
this._lastLoadedPage = 0; this._lastLoadedPage = 0;
this._totalPages = 1; this._totalPages = 1;
...@@ -115,40 +117,11 @@ export default class PaginationController { ...@@ -115,40 +117,11 @@ export default class PaginationController {
({ additionalQuery } = this); ({ additionalQuery } = this);
} }
const date = `${new Date().toISOString().split('.')[0]}Z`; const date = `${new Date().toISOString().split('.')[0]}Z`;
const query = JSON.parse( const query = Query.merge(this.query, additionalQuery, {
JSON.stringify( where: { show_website: true, time_advertising_start: { $lt: date } },
Object.assign({}, this.query, additionalQuery, { max_results: this.query.max_results || 10,
where: Object.assign({}, this.query.where, additionalQuery.where), page: pageNum,
}) });
)
);
if (
this.query.where &&
this.query.where.$or &&
additionalQuery.where &&
additionalQuery.where.$or
) {
query.where.$and = query.where.$and || [];
query.where.$and.push(
JSON.parse(JSON.stringify({ $or: this.query.where.$or })),
JSON.parse(JSON.stringify({ $or: additionalQuery.where.$or }))
);
delete query.where.$or;
}
if (this.query.where && this.query.where.$and) {
query.where.$and = query.where.$and.concat(JSON.parse(JSON.stringify(this.query.where.$and)));
}
if (additionalQuery.where && additionalQuery.where.$and) {
query.where.$and = query.where.$and.concat(
JSON.parse(JSON.stringify(additionalQuery.where.$and))
);
}
query.where.show_website = true;
query.where.time_advertising_start = { $lt: date };
query.max_results = query.max_results || 10;
query.page = pageNum;
const data = await this._loadData(query); const data = await this._loadData(query);
this._pages[pageNum] = { datetime: new Date(), items: data }; this._pages[pageNum] = { datetime: new Date(), items: data };
...@@ -165,12 +138,7 @@ export default class PaginationController { ...@@ -165,12 +138,7 @@ export default class PaginationController {
* @private * @private
*/ */
async _loadData(query) { async _loadData(query) {
// Parse query such that the backend understands it const queryString = Query.buildQueryString(query);
const parsedQuery = {};
Object.keys(query).forEach(key => {
parsedQuery[key] = key === 'sort' ? query[key] : JSON.stringify(query[key]);
});
const queryString = m.buildQueryString(parsedQuery);
const response = await m.request({ const response = await m.request({
method: 'GET', method: 'GET',
......
import m from 'mithril';
/**
* Query helper utility class
*/
export default class Query {
/**
* checks if two querys are equal
* @param {object} query1
* @param {object} query2
* @return {boolean}
*/
static isEqual(query1, query2) {
return JSON.stringify(query1) === JSON.stringify(query2);
}
/**
* Creates a deep copy from a query.
* @param {object} query
*/
static copy(query) {
return JSON.parse(JSON.stringify(query || {}));
}
/**
* Merges multiple queries together to one single query (deep copy included).
*
* *Please note that the value on the last parameter has the highest precedence.*
* @param {*} queries
*/
static merge(...queries) {
const newQuery = {};
queries.forEach(query => {
Object.entries(query).forEach(([key, value]) => {
if (newQuery[key]) {
if (key === '$or') {
if (!newQuery.$and) newQuery.$and = [];
newQuery.push({ $or: Query.copy(value) });
} else if (key === '$and') {
newQuery.$and = newQuery.$and.concat(Query.copy(value));
} else if (typeof newQuery[key] === 'object') {
newQuery[key] = Query.merge(newQuery[key], value);
} else {
newQuery[key] = value;
}
} else {
newQuery[key] = Query.copy(value);
}
});
});
return newQuery;
}
/**
* Builds a query string for use with a server request.
*
* Parses a query such that the backend understands it
* @param {object} query
*/
static buildQueryString(query) {
const parsedQuery = {};
Object.keys(query).forEach(key => {
if (Array.isArray(query[key])) {
parsedQuery[key] = query[key];
} else {
parsedQuery[key] = JSON.stringify(query[key]);
}
});
return m.buildQueryString(parsedQuery);
}
}
import m from 'mithril'; import m from 'mithril';
import { apiUrl } from 'config'; import { apiUrl } from 'config';
import { getToken } from './auth'; import { getToken } from './auth';
import Query from './query';
let querySaved = {}; let querySaved = {};
...@@ -23,8 +24,8 @@ export function getList() { ...@@ -23,8 +24,8 @@ export function getList() {
* @return {Promise} exports for additional response handling * @return {Promise} exports for additional response handling
*/ */
export function load(query = {}) { export function load(query = {}) {
querySaved = query; querySaved = Query.copy(query);
const queryEncoded = m.buildQueryString({ where: JSON.stringify(query) }); const queryEncoded = Query.buildQueryString({ where: query });
return m return m
.request({ .request({
...@@ -51,8 +52,8 @@ export function getInputSuggestions(field, input) { ...@@ -51,8 +52,8 @@ export function getInputSuggestions(field, input) {
// TODO: debug Error 502 Bad Gateway returned by API // TODO: debug Error 502 Bad Gateway returned by API
// const projection = {}; // const projection = {};
// projection[field] = 1; // projection[field] = 1;
const queryEncoded = m.buildQueryString({ const queryEncoded = Query.buildQueryString({
where: JSON.stringify(query), where: query,
// projection: JSON.stringify(projection), // projection: JSON.stringify(projection),
}); });
return m.request({ return m.request({
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment