# HG changeset patch # User Frank Bessou <frank.bessou@logilab.fr> # Date 1614262350 -3600 # Thu Feb 25 15:12:30 2021 +0100 # Node ID 11292fd331a6f4df11f4fe1e055a9c396cd3f6e4 # Parent eb356ab55f0301e15bc636345abeff3c1577999a refactor: extract methods declaration outside of returned object diff --git a/packages/ra-cubicweb/src/index.ts b/packages/ra-cubicweb/src/index.ts --- a/packages/ra-cubicweb/src/index.ts +++ b/packages/ra-cubicweb/src/index.ts @@ -19,177 +19,208 @@ rqlClient: client.CwRqlClient, schema: S ): DataProvider { - return { - getList: async (resource: ETypesNames<S>, { pagination, sort, filter }) => { - const sortAttribute = sort.field === "id" ? "eid" : sort.field; - const attributesNames = ["eid", ...Object.keys(schema.etypes[resource])]; - const selection: string[] = []; - const restrictions: string[] = []; - let sortvariable = null; - attributesNames.forEach((key, idx) => { - const variable = `X${idx}`; - selection.push(variable); - restrictions.push(`X ${key} ${variable}`); - if (key === sortAttribute) { - sortvariable = variable; - } + const getList: DataProvider["getList"] = async ( + resource: ETypesNames<S>, + { pagination, sort, filter } + ) => { + const sortAttribute = sort.field === "id" ? "eid" : sort.field; + const attributesNames = ["eid", ...Object.keys(schema.etypes[resource])]; + const selection: string[] = []; + const restrictions: string[] = []; + let sortvariable = null; + attributesNames.forEach((key, idx) => { + const variable = `X${idx}`; + selection.push(variable); + restrictions.push(`X ${key} ${variable}`); + if (key === sortAttribute) { + sortvariable = variable; + } + }); + + // Handle filters + restrictions.push( + ...Object.entries(filter).map(([attrName, attrValue]) => { + return `EXISTS(X ${attrName} ~= '%${attrValue}%')`; + }) + ); + + const total = await rqlClient + .queryRows(`Any Count(${selection[0]}) WHERE ${restrictions.join(",")}`) + .then((rows) => rows[0][0]); + return rqlClient + .queryRows( + `Any ${selection.join(", ")} ORDERBY ${sortvariable} ${ + sort.order + } LIMIT ${pagination.perPage} OFFSET ${ + (pagination.page - 1) * pagination.perPage + } WHERE ${restrictions.join(", ")}`, + {} + ) + .then((rows) => { + return { + data: rows.map((row) => + row.reduce( + (agg, attributeValue, idx) => ({ + [attributesNames[idx]]: attributeValue, + ...agg, + }), + { id: row[0] } + ) + ), + total, + }; }); + }; - // Handle filters - restrictions.push( - ...Object.entries(filter).map(([attrName, attrValue]) => { - return `EXISTS(X ${attrName} ~= '%${attrValue}%')`; - }) - ); + const getOne: DataProvider["getOne"] = async ( + resource: ETypesNames<S>, + params + ) => { + // FIXME Retrieve object relation + // Getting attributes + const attributesNames = [...Object.keys(schema.etypes[resource])]; + const selection: string[] = []; + const restrictions: string[] = []; + attributesNames.forEach((key, idx) => { + const variable = `X${idx}`; + selection.push(variable); + restrictions.push(`X ${key} ${variable}`); + }); - const total = await rqlClient - .queryRows(`Any Count(${selection[0]}) WHERE ${restrictions.join(",")}`) - .then((rows) => rows[0][0]); - return rqlClient - .queryRows( - `Any ${selection.join(", ")} ORDERBY ${sortvariable} ${ - sort.order - } LIMIT ${pagination.perPage} OFFSET ${ - (pagination.page - 1) * pagination.perPage - } WHERE ${restrictions.join(", ")}`, - {} - ) - .then((rows) => { - return { - data: rows.map((row) => - row.reduce( - (agg, attributeValue, idx) => ({ - [attributesNames[idx]]: attributeValue, - ...agg, - }), - { id: row[0] } - ) - ), - total, - }; - }); - }, - getOne: async (resource: ETypesNames<S>, params) => { - // FIXME Retrieve object relation - // Getting attributes - const attributesNames = [...Object.keys(schema.etypes[resource])]; - const selection: string[] = []; - const restrictions: string[] = []; - attributesNames.forEach((key, idx) => { - const variable = `X${idx}`; - selection.push(variable); - restrictions.push(`X ${key} ${variable}`); - }); + const result = await rqlClient.queryRows( + `Any ${selection.join(",")} Where ${restrictions.join(",")}, X eid ${ + params.id + }` + ); + const row = result[0]; + const entity = row.reduce( + (agg, attributeValue, idx) => ({ + [attributesNames[idx]]: attributeValue, + ...agg, + }), + { eid: params.id, id: params.id } + ); + + // Getting subject relations + const subjectRelations = Object.fromEntries( + Object.entries( + schema.relationships + ).filter( + ([_relationName, definition]: [string, S["relationships"][string]]) => + definition.subject.includes(resource) + ) + ); + for (const relationName in subjectRelations) { + const result = await rqlClient.queryRows( + `Any TARGET Where X ${relationName} TARGET, X eid ${params.id}` + ); + if (result.length !== 0) { + entity[relationName] = result.map((row) => row[0]); + } + } + // Getting object relations + const objectRelations = Object.fromEntries( + Object.entries( + schema.relationships + ).filter( + ([_relationName, definition]: [string, S["relationships"][string]]) => + definition.object.includes(resource) + ) + ); + for (const relationName in objectRelations) { const result = await rqlClient.queryRows( - `Any ${selection.join(",")} Where ${restrictions.join(",")}, X eid ${ - params.id - }` + `Any TARGET Where TARGET ${relationName} X, X eid ${params.id}` ); - const row = result[0]; - const entity = row.reduce( + if (result.length !== 0) { + entity[`reverse_${relationName}`] = result.map((row) => row[0]); + } + } + return { data: entity }; + }; + + const getMany: DataProvider["getMany"] = async (resource, params) => { + // FIXME handle several params id and refactor code to use GetOne + // Getting attributes + const attributesNames = [...Object.keys(schema.etypes[resource])]; + const selection: string[] = []; + const restrictions: string[] = []; + attributesNames.forEach((key, idx) => { + const variable = `X${idx}`; + selection.push(variable); + restrictions.push(`X ${key} ${variable}`); + }); + const result = await rqlClient.queryRows( + `Any ${selection.join(",")} Where ${restrictions.join( + "," + )}, X eid IN (${params.ids.join(",")})` + ); + const entities = result.map((row, rowIdx) => + row.reduce( (agg, attributeValue, idx) => ({ [attributesNames[idx]]: attributeValue, ...agg, }), - { eid: params.id, id: params.id } - ); + { id: params.ids[rowIdx] } + ) + ); + + return { data: entities }; + }; - // Getting subject relations - const subjectRelations = Object.fromEntries( - Object.entries( - schema.relationships - ).filter( - ([_relationName, definition]: [string, S["relationships"][string]]) => - definition.subject.includes(resource) - ) - ); - for (const relationName in subjectRelations) { - const result = await rqlClient.queryRows( - `Any TARGET Where X ${relationName} TARGET, X eid ${params.id}` - ); - if (result.length !== 0) { - entity[relationName] = result.map((row) => row[0]); - } - } + const getManyReference: DataProvider["getManyReference"] = ( + _resource, + _params + ) => Promise.reject("Not implemented"); - // Getting object relations - const objectRelations = Object.fromEntries( - Object.entries( - schema.relationships - ).filter( - ([_relationName, definition]: [string, S["relationships"][string]]) => - definition.object.includes(resource) - ) - ); - for (const relationName in objectRelations) { - const result = await rqlClient.queryRows( - `Any TARGET Where TARGET ${relationName} X, X eid ${params.id}` - ); - if (result.length !== 0) { - entity[`reverse_${relationName}`] = result.map((row) => row[0]); - } + const update: DataProvider["update"] = async (resource, { data, id }) => { + // FIXME update relations + const attributesUpdates: string[] = []; + Object.entries(data).forEach(([key, value]) => { + if (key in schema.etypes[resource]) { + attributesUpdates.push(`X ${key} ${JSON.stringify(value)}`); } - return { data: entity }; - }, - getMany: async (resource, params) => { - // FIXME handle several params id and refactor code to use GetOne - // Getting attributes - const attributesNames = [...Object.keys(schema.etypes[resource])]; - const selection: string[] = []; - const restrictions: string[] = []; - attributesNames.forEach((key, idx) => { - const variable = `X${idx}`; - selection.push(variable); - restrictions.push(`X ${key} ${variable}`); - }); - const result = await rqlClient.queryRows( - `Any ${selection.join(",")} Where ${restrictions.join( - "," - )}, X eid IN (${params.ids.join(",")})` - ); - const entities = result.map((row, rowIdx) => - row.reduce( - (agg, attributeValue, idx) => ({ - [attributesNames[idx]]: attributeValue, - ...agg, - }), - { id: params.ids[rowIdx] } - ) - ); - - return { data: entities }; - }, - getManyReference: (_resource, _params) => Promise.reject("Not implemented"), - update: async (resource, { data, id }) => { - // FIXME update relations - const attributesUpdates: string[] = []; - Object.entries(data).forEach(([key, value]) => { - if (key in schema.etypes[resource]) { - attributesUpdates.push(`X ${key} ${JSON.stringify(value)}`); - } - }); - await rqlClient.queryRows(` + }); + await rqlClient.queryRows(` SET ${attributesUpdates.join(", ")} WHERE X is ${resource}, X eid ${id} `); - return Promise.resolve({ data: { ...data, id } }); - }, - updateMany: (_resource, _params) => Promise.reject("Not implemented"), - create: async (resource, { data }) => { - // FIXME create relations - const attributesUpdates: string[] = []; - Object.entries(data).forEach(([key, value]) => { - if (key in schema.etypes[resource]) { - attributesUpdates.push(`X ${key} ${JSON.stringify(value)}`); - } - }); - const result = await rqlClient.queryRows(` + return Promise.resolve({ data: { ...data, id } }); + }; + + const updateMany: DataProvider["updateMany"] = (_resource, _params) => + Promise.reject("Not implemented"); + + const create: DataProvider["create"] = async (resource, { data }) => { + // FIXME create relations + const attributesUpdates: string[] = []; + Object.entries(data).forEach(([key, value]) => { + if (key in schema.etypes[resource]) { + attributesUpdates.push(`X ${key} ${JSON.stringify(value)}`); + } + }); + + const result = await rqlClient.queryRows(` INSERT ${resource} X: ${attributesUpdates.join(", ")} `); - const eid = result[0][0]; - return Promise.resolve({ data: { ...data, id: eid } }); - }, - delete: (_resource, _params) => Promise.reject("Not implemented"), - deleteMany: (_resource, _params) => Promise.reject("Not implemented"), + const eid = result[0][0]; + return Promise.resolve({ data: { ...data, id: eid } }); + }; + + const _delete: DataProvider["delete"] = (_resource, _params) => + Promise.reject("Not implemented"); + + const deleteMany: DataProvider["deleteMany"] = (_resource, _params) => + Promise.reject("Not implemented"); + + return { + getList, + getOne, + getMany, + getManyReference, + update, + updateMany, + create, + delete: _delete, + deleteMany, }; }