Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
ISMAELHADDAD committed Feb 21, 2024
2 parents e2a4af5 + c84d45a commit 4dc444f
Showing 1 changed file with 154 additions and 107 deletions.
261 changes: 154 additions & 107 deletions src/services/localDB/module/baseEntity.ts
Original file line number Diff line number Diff line change
@@ -1,135 +1,182 @@
import { Platform } from "react-native"
import { Campaign, Measurement, Observation, ObservationImage } from "../../../models";
import { Platform } from "react-native";
import {
Campaign,
Measurement,
Observation,
ObservationImage,
} from "../../../models";
import { db } from "../db";
import { EntityType } from "../types";

type Entity = Observation | Measurement | Campaign | ObservationImage
type Entity = Observation | Measurement | Campaign | ObservationImage;
type EntityPayload = Array<Entity>;

function getOsSpecificUpsertQuery(isSynced: boolean,
entityType: EntityType,
campaignId: string | null,
observationId: string | null,
measurementId: string | null,
payloadArray: Array<Entity>) {
async function upsertOldSqlite(
isSynced: boolean,
entityType: EntityType,
campaignId: string | null,
observationId: string | null,
measurementId: string | null,
payloadArray: Array<Entity>
) {
const updateQuery = `UPDATE baseEntity SET isSynced = ?, jsonObject = ? WHERE id = ?`;
const insertQuery = `INSERT INTO baseEntity (id, isSynced, type, campaignId, observationId, measurementId, jsonObject) VALUES (?, ?, ?, ?, ?, ?, ?)`;

return new Promise<void>((resolve, reject) => {
// Start a single transaction for all upsert operations
db.transaction(
(tx) => {
payloadArray.forEach((payload) => {
// Step 1: Attempt to update the existing payload
tx.executeSql(
updateQuery,
[isSynced ? "1" : "0", JSON.stringify(payload), payload.id],
function (tx, res) {
// If the update affected 0 rows, try to insert the payload
if (res.rowsAffected === 0) {
// Step 2: Insert the new payload
tx.executeSql(
insertQuery,
[payload.id, isSynced ? "1" : "0", entityType, campaignId, observationId, measurementId, JSON.stringify(payload)],
function (tx, res) {
// console.log("Insert successful for payload with id:", payload.id);
},
function (tx, err) {
console.error("Insert failed for payload with id:", payload.id, err);
return false;
}
);
} else {
// console.log("Update successful for payload with id:", payload.id);
}
},
function (tx, err) {
console.error("Update failed for payload with id:", payload.id, err);
return false;
}
);
});
},
reject,
resolve
);
});
}

async function upsert(
isSynced: boolean,
entityType: EntityType,
campaignId: string | null,
observationId: string | null,
measurementId: string | null,
payloadArray: Array<Entity>
) {
const toInsertValue = (payload: Entity): string =>
Platform.select(
{
android:
`('${payload.id}',
COALESCE((select isSynced from baseEntity where id='${payload.id}'), ${isSynced ? "1" : "0"}),
'${entityType}',
'${campaignId || "null"}',
'${observationId || "null"}',
'${measurementId || "null"}',
COALESCE((select jsonObject from baseEntity where id='${payload.id}'), '${JSON.stringify(payload)}')
)`,
default:
`('${payload.id}',
${isSynced ? "1" : "0"},
'${entityType}',
'${campaignId || "null"}',
'${observationId || "null"}',
'${measurementId || "null"}',
'${JSON.stringify(payload)}'
)`,
})
`('${payload.id}',
${isSynced ? "1" : "0"},
'${entityType}',
'${campaignId || "null"}',
'${observationId || "null"}',
'${measurementId || "null"}',
'${JSON.stringify(payload)}'
)`;
const insertValues = payloadArray.map(toInsertValue);
return Platform.select(
{
// upsert is only supported from SQL 3.24 which is not available on Android 10 or earlier.
android:
`insert
or replace into baseEntity
(id, isSynced, type, campaignId, observationId, measurementId, jsonObject)
values
${insertValues.join(", ")};`,
default:
`insert into baseEntity (id, isSynced, type, campaignId, observationId, measurementId, jsonObject)
values ${insertValues.join(", ")} on conflict(id) do
update
set isSynced=excluded.isSynced, jsonObject=excluded.jsonObject;`,
})
return new Promise<void>((resolve, reject) => {
db.transaction(
(tx) => {
tx.executeSql(`insert into baseEntity (id, isSynced, type, campaignId, observationId, measurementId, jsonObject)
values ${insertValues.join(", ")} on conflict(id) do
update set isSynced=excluded.isSynced, jsonObject=excluded.jsonObject;`);
},
reject,
resolve
);
});
}

export const baseEntityModule = {
upsertEntities(
payloadArray: EntityPayload,
entityType: EntityType,
isSynced: boolean,
campaignId: string | null = null,
observationId: string | null = null,
measurementId: string | null = null,
payloadArray: EntityPayload,
entityType: EntityType,
isSynced: boolean,
campaignId: string | null = null,
observationId: string | null = null,
measurementId: string | null = null
) {
const query = getOsSpecificUpsertQuery(isSynced, entityType, campaignId, observationId, measurementId, payloadArray)
return new Promise<void>((resolve, reject) => {
db.transaction(
(tx) => {
tx.executeSql(query);
},
reject,
resolve,
);
});
// upsert is only supported from SQL 3.24 which is not available on Android 10 or earlier.
return Platform.OS === "android" && Platform.Version < 30
? upsertOldSqlite(
isSynced,
entityType,
campaignId,
observationId,
measurementId,
payloadArray
)
: upsert(
isSynced,
entityType,
campaignId,
observationId,
measurementId,
payloadArray
);
},
getEntities<T>(
entityType: EntityType,
isSynced: boolean | null = null,
campaignId: string | null = null,
observationId: string | null = null,
measurementId: string | null = null,
entityType: EntityType,
isSynced: boolean | null = null,
campaignId: string | null = null,
observationId: string | null = null,
measurementId: string | null = null
): Promise<Array<T>> {
return new Promise<Array<T>>((resolve, reject) => {
db.transaction((tx) => {
const filerByCampaign =
db.transaction(
(tx) => {
const filerByCampaign =
campaignId !== null ? `and campaignId = '${campaignId}'` : "";
const filerByObservation =
const filerByObservation =
observationId !== null
? `and observationId = '${observationId}'`
: "";
const filerByFeature =
measurementId !== null ? `and measurementId = '${measurementId}'` : "";
const filerByIsSynced =
isSynced !== null
? `and isSynced = ${observationId ? 1 : 0}`
: "";
const query = `select *
? `and observationId = '${observationId}'`
: "";
const filerByFeature =
measurementId !== null
? `and measurementId = '${measurementId}'`
: "";
const filerByIsSynced =
isSynced !== null ? `and isSynced = ${observationId ? 1 : 0}` : "";
const query = `select *
from baseEntity
where type = ? ${filerByCampaign} ${filerByObservation} ${filerByFeature} ${filerByIsSynced}`
tx.executeSql(
query,
[entityType],
(_, {rows}) => {
let entities: Array<T> = [];
for (let i = 0; i < rows.length; i++) {
entities = [...entities, JSON.parse(rows.item(i).jsonObject)];
}
resolve(entities);
},
);
}, (e) => {
console.error("baseEntity.ts", "getEntities", "error:", e)
reject(e)
});
where type = ? ${filerByCampaign} ${filerByObservation} ${filerByFeature} ${filerByIsSynced}`;
tx.executeSql(query, [entityType], (_, { rows }) => {
let entities: Array<T> = [];
for (let i = 0; i < rows.length; i++) {
entities = [...entities, JSON.parse(rows.item(i).jsonObject)];
}
resolve(entities);
});
},
(e) => {
console.error("baseEntity.ts", "getEntities", "error:", e);
reject(e);
}
);
});
},
deleteEntities(payloadArray: Array<string>) {
return new Promise<void>((resolve, reject) => {
db.transaction(
(tx) => {
tx.executeSql(
`delete
(tx) => {
tx.executeSql(
`delete
from baseEntity
where id in ("${payloadArray.join(
"\", \"",
)}")`,
);
},
(e) => {
console.error("baseEntity.ts", "deleteEntities", "error:", e)
reject(e)
},
resolve,
where id in ("${payloadArray.join('", "')}")`
);
},
(e) => {
console.error("baseEntity.ts", "deleteEntities", "error:", e);
reject(e);
},
resolve
);
});
},
Expand Down

0 comments on commit 4dc444f

Please sign in to comment.