# 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,
   };
 }