Saving a quick snapshot after Gemini changes to Dexie function and processing functions.
This commit is contained in:
@@ -11,10 +11,10 @@ Core Aether modules
|
||||
|
||||
Additional Aether modules
|
||||
* events
|
||||
* presentation management - import the program data (events, session, presentations, presenters, evnet files, locations/rooms, devices)
|
||||
* presentation management - import the program data (events, session, presentations, presenters, event files, locations/rooms, devices)
|
||||
* launcher - Technically this is used with presentation management. It is part of the native app that uses Electron. One of the libraries is for functions that only work when the site is opened in an Electron app. For example the regular browser can not move files around on the local computer or run local commands.
|
||||
* badge printing
|
||||
* lead retreavl - attendee tracking; QR codes
|
||||
* lead retrieval - attendee tracking; QR codes
|
||||
* journals - journal, documentation, notes, diary, blog, etc
|
||||
* idaa - One of my clients
|
||||
|
||||
|
||||
@@ -1,248 +1,174 @@
|
||||
import type { key_val } from '$lib/ae_stores';
|
||||
import { get_object } from './api_get_object';
|
||||
|
||||
// The lookup "obj_type" should broken out into a separate function. - 2024-08-07
|
||||
// Updated 2023-11-15
|
||||
export async function get_ae_obj_li_for_obj_id_crud_v2(
|
||||
{
|
||||
api_cfg,
|
||||
obj_type,
|
||||
for_obj_type,
|
||||
for_obj_id, // NOTE: Changed 2023-12-06 to no longer required
|
||||
use_alt_tbl = false, // Alternate table or view name
|
||||
use_alt_mdl = false, // Alternate model name
|
||||
use_alt_exp = false, // Alternate export table or view name
|
||||
inc = {},
|
||||
enabled = 'enabled',
|
||||
hidden = 'not_hidden',
|
||||
order_by_li = null,
|
||||
limit = 999999,
|
||||
offset = 0,
|
||||
// key,
|
||||
// jwt = null,
|
||||
headers = {},
|
||||
params_json = null, // NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the API endpoint. Example: { "fulltext_search": { "default_qry_str": "Search string for default", "address_default_qry_str": "Search string for address", "contact_1_default_qry_str": "Search string for contact_1" } }
|
||||
// json_obj = null, // NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the search endpoint.
|
||||
params = {},
|
||||
// return_meta = false,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
api_cfg: any,
|
||||
obj_type: string,
|
||||
for_obj_type: string,
|
||||
for_obj_id?: string,
|
||||
use_alt_tbl?: boolean|string,
|
||||
use_alt_mdl?: boolean|string,
|
||||
use_alt_exp?: boolean|string,
|
||||
inc?: key_val
|
||||
enabled?: string,
|
||||
hidden?: string,
|
||||
order_by_li?: any,
|
||||
limit?: number,
|
||||
offset?: number,
|
||||
// key: string,
|
||||
// jwt?: string,
|
||||
headers?: any,
|
||||
params_json?: any,
|
||||
// json_obj?: any,
|
||||
params?: key_val,
|
||||
// return_meta?: boolean,
|
||||
log_lvl?: number
|
||||
}
|
||||
) {
|
||||
if (log_lvl) {
|
||||
console.log('*** get_ae_obj_li_for_obj_id_crud() ***');
|
||||
}
|
||||
// Refactored 2025-11-13 to use a lookup map for endpoints.
|
||||
const objTypeToEndpointMap: Record<string, string> = {
|
||||
account: '/crud/account/list',
|
||||
address: '/crud/address/list',
|
||||
archive: '/crud/archive/list',
|
||||
archive_content: '/crud/archive/content/list',
|
||||
contact: '/crud/contact/list',
|
||||
data_store: '/crud/data_store/list',
|
||||
event: '/crud/event/list',
|
||||
event_abstract: '/crud/event/abstract/list',
|
||||
event_badge: '/crud/event/badge/list',
|
||||
event_badge_template: '/crud/event/badge/template/list',
|
||||
event_device: '/crud/event/device/list',
|
||||
event_exhibit: '/crud/event/exhibit/list',
|
||||
event_exhibit_tracking: '/crud/event/exhibit/tracking/list',
|
||||
event_file: '/crud/event/file/list',
|
||||
event_location: '/crud/event/location/list',
|
||||
event_person: '/crud/event/person/list',
|
||||
event_presentation: '/crud/event/presentation/list',
|
||||
event_presenter: '/crud/event/presenter/list',
|
||||
event_session: '/crud/event/session/list',
|
||||
event_track: '/crud/event/track/list',
|
||||
grant: '/crud/grant/list',
|
||||
hosted_file: '/crud/hosted_file/list',
|
||||
journal: '/crud/journal/list',
|
||||
journal_entry: '/crud/journal/entry/list',
|
||||
order: '/crud/order/list',
|
||||
order_line: '/crud/order/line/list',
|
||||
page: '/crud/page/list',
|
||||
person: '/crud/person/list',
|
||||
post: '/crud/post/list',
|
||||
post_comment: '/crud/post/comment/list',
|
||||
site: '/crud/site/list',
|
||||
sponsorship_cfg: '/crud/sponsorship/cfg/list',
|
||||
sponsorship: '/crud/sponsorship/list',
|
||||
// user: '/crud/user/list',
|
||||
'lu-country_subdivision': '/crud/lu/country_subdivision/list',
|
||||
'lu-country': '/crud/lu/country/list',
|
||||
'lu-time_zone': '/crud/lu/time_zone/list'
|
||||
};
|
||||
|
||||
// data = {};
|
||||
// data['super_key'] = key;
|
||||
// data['jwt'] = jwt;
|
||||
// NOTE: The key and or JWT should be in the header of the DELETE, GET, PATCH, POST
|
||||
function getEndpointForObjType(obj_type: string, for_obj_type?: string): string {
|
||||
if (obj_type === 'lu' && for_obj_type) {
|
||||
const key = `lu-${for_obj_type}`;
|
||||
const endpoint = objTypeToEndpointMap[key];
|
||||
if (endpoint) return endpoint;
|
||||
}
|
||||
|
||||
// const endpoint = `/crud/${obj_type}/list`;
|
||||
const endpoint = objTypeToEndpointMap[obj_type];
|
||||
if (endpoint) return endpoint;
|
||||
|
||||
let endpoint = '';
|
||||
if (obj_type == 'account') {
|
||||
endpoint = `/crud/account/list`;
|
||||
} else if (obj_type == 'address') {
|
||||
endpoint = `/crud/address/list`;
|
||||
} else if (obj_type == 'archive') {
|
||||
endpoint = `/crud/archive/list`;
|
||||
} else if (obj_type == 'archive_content') {
|
||||
endpoint = `/crud/archive/content/list`;
|
||||
} else if (obj_type == 'contact') {
|
||||
endpoint = `/crud/contact/list`;
|
||||
} else if (obj_type == 'data_store') {
|
||||
endpoint = `/crud/data_store/list`;
|
||||
} else if (obj_type == 'event') {
|
||||
endpoint = `/crud/event/list`;
|
||||
} else if (obj_type == 'event_abstract') {
|
||||
endpoint = `/crud/event/abstract/list`;
|
||||
} else if (obj_type == 'event_badge') {
|
||||
endpoint = `/crud/event/badge/list`;
|
||||
} else if (obj_type == 'event_badge_template') {
|
||||
endpoint = `/crud/event/badge/template/list`;
|
||||
} else if (obj_type == 'event_device') {
|
||||
endpoint = `/crud/event/device/list`;
|
||||
} else if (obj_type == 'event_exhibit') {
|
||||
endpoint = `/crud/event/exhibit/list`;
|
||||
} else if (obj_type == 'event_exhibit_tracking') {
|
||||
endpoint = `/crud/event/exhibit/tracking/list`;
|
||||
} else if (obj_type == 'event_file') {
|
||||
endpoint = `/crud/event/file/list`;
|
||||
} else if (obj_type == 'event_location') {
|
||||
endpoint = `/crud/event/location/list`;
|
||||
} else if (obj_type == 'event_person') {
|
||||
endpoint = `/crud/event/person/list`;
|
||||
} else if (obj_type == 'event_presentation') {
|
||||
endpoint = `/crud/event/presentation/list`;
|
||||
} else if (obj_type == 'event_presenter') {
|
||||
endpoint = `/crud/event/presenter/list`;
|
||||
} else if (obj_type == 'event_session') {
|
||||
endpoint = `/crud/event/session/list`;
|
||||
} else if (obj_type == 'event_track') {
|
||||
endpoint = `/crud/event/track/list`;
|
||||
} else if (obj_type == 'grant') {
|
||||
endpoint = `/crud/grant/list`;
|
||||
} else if (obj_type == 'hosted_file') {
|
||||
endpoint = `/crud/hosted_file/list`;
|
||||
} else if (obj_type == 'journal') {
|
||||
endpoint = `/crud/journal/list`;
|
||||
} else if (obj_type == 'journal_entry') {
|
||||
endpoint = `/crud/journal/entry/list`;
|
||||
} else if (obj_type == 'order') {
|
||||
endpoint = `/crud/order/list`;
|
||||
} else if (obj_type == 'order_line') {
|
||||
endpoint = `/crud/order/line/list`;
|
||||
} else if (obj_type == 'page') {
|
||||
endpoint = `/crud/page/list`;
|
||||
} else if (obj_type == 'person') {
|
||||
endpoint = `/crud/person/list`;
|
||||
} else if (obj_type == 'post') {
|
||||
endpoint = `/crud/post/list`;
|
||||
} else if (obj_type == 'post_comment') {
|
||||
endpoint = `/crud/post/comment/list`;
|
||||
} else if (obj_type == 'site') {
|
||||
endpoint = `/crud/site/list`;
|
||||
} else if (obj_type == 'sponsorship_cfg') {
|
||||
endpoint = `/crud/sponsorship/cfg/list`;
|
||||
} else if (obj_type == 'sponsorship') {
|
||||
endpoint = `/crud/sponsorship/list`;
|
||||
// } else if (obj_type == 'user') {
|
||||
// endpoint = `/crud/user/list`;
|
||||
} else if (obj_type == 'lu' && for_obj_type == 'country_subdivision') {
|
||||
endpoint = `/crud/lu/country_subdivision/list`;
|
||||
// for_obj_type = null;
|
||||
} else if (obj_type == 'lu' && for_obj_type == 'country') {
|
||||
endpoint = `/crud/lu/country/list`;
|
||||
// for_obj_type = null;
|
||||
} else if (obj_type == 'lu' && for_obj_type == 'time_zone') {
|
||||
endpoint = `/crud/lu/time_zone/list`;
|
||||
// for_obj_type = null;
|
||||
} else {
|
||||
console.log(`Unknown object type: ${obj_type}`);
|
||||
return false;
|
||||
}
|
||||
endpoint = `/v2${endpoint}`;
|
||||
if (log_lvl) {
|
||||
console.log('Endpoint:', endpoint);
|
||||
}
|
||||
throw new Error(`Unknown object type: ${obj_type}`);
|
||||
}
|
||||
|
||||
// We need to remove a few parameters from the params object that are not allowed.
|
||||
delete params['qry__enabled'];
|
||||
delete params['qry__hidden'];
|
||||
delete params['qry__limit'];
|
||||
delete params['qry__offset'];
|
||||
type OrderBy = { [key: string]: 'ASC' | 'DESC' };
|
||||
|
||||
interface GetAeObjLiForObjIdCrudV2Params {
|
||||
api_cfg: any; // Consider defining a specific type for api_cfg
|
||||
obj_type: string;
|
||||
for_obj_type: string;
|
||||
for_obj_id?: string;
|
||||
use_alt_tbl?: boolean | string;
|
||||
use_alt_mdl?: boolean | string;
|
||||
use_alt_exp?: boolean | string;
|
||||
inc?: key_val;
|
||||
enabled?: 'all' | 'enabled' | 'not_enabled';
|
||||
hidden?: 'all' | 'hidden' | 'not_hidden';
|
||||
order_by_li?: OrderBy[] | null;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
headers?: Record<string, string>;
|
||||
params_json?: any;
|
||||
params?: key_val;
|
||||
log_lvl?: number;
|
||||
}
|
||||
|
||||
if (for_obj_type) {
|
||||
params['for_obj_type'] = for_obj_type;
|
||||
}
|
||||
if (for_obj_id) {
|
||||
params['for_obj_id'] = for_obj_id;
|
||||
}
|
||||
export async function get_ae_obj_li_for_obj_id_crud_v2({
|
||||
api_cfg,
|
||||
obj_type,
|
||||
for_obj_type,
|
||||
for_obj_id,
|
||||
use_alt_tbl = false,
|
||||
use_alt_mdl = false,
|
||||
use_alt_exp = false,
|
||||
enabled = 'enabled',
|
||||
hidden = 'not_hidden',
|
||||
order_by_li = null,
|
||||
limit = 999999,
|
||||
offset = 0,
|
||||
headers = {},
|
||||
params_json = null,
|
||||
params = {},
|
||||
log_lvl = 0
|
||||
}: GetAeObjLiForObjIdCrudV2Params) {
|
||||
if (log_lvl) {
|
||||
console.log('*** get_ae_obj_li_for_obj_id_crud_v2() ***');
|
||||
}
|
||||
|
||||
if (use_alt_tbl === true) {
|
||||
params['tbl_alt'] = 'alt'; // Use alternate table or view name
|
||||
}
|
||||
if (use_alt_mdl === true) {
|
||||
params['mdl_alt'] = 'alt'; // Use alternate model name
|
||||
}
|
||||
if (use_alt_exp === true) {
|
||||
params['exp_alt'] = 'alt'; // Use alternate export table or view name
|
||||
}
|
||||
try {
|
||||
const endpoint = `/v2${getEndpointForObjType(obj_type, for_obj_type)}`;
|
||||
if (log_lvl) {
|
||||
console.log('Endpoint:', endpoint);
|
||||
}
|
||||
|
||||
// We need to remove a few parameters from the params object that are not allowed.
|
||||
delete params['qry__enabled'];
|
||||
delete params['qry__hidden'];
|
||||
delete params['qry__limit'];
|
||||
delete params['qry__offset'];
|
||||
|
||||
// Need to deal with inc params here???
|
||||
if (for_obj_type) params['for_obj_type'] = for_obj_type;
|
||||
if (for_obj_id) params['for_obj_id'] = for_obj_id;
|
||||
|
||||
if (use_alt_tbl === true) params['tbl_alt'] = 'alt';
|
||||
if (use_alt_mdl === true) params['mdl_alt'] = 'alt';
|
||||
if (use_alt_exp === true) params['exp_alt'] = 'alt';
|
||||
|
||||
let allowed_enabled_list = ['all', 'enabled', 'not_enabled']
|
||||
if (allowed_enabled_list.includes(enabled) ) {
|
||||
params['enabled'] = enabled;
|
||||
}
|
||||
const allowed_enabled_list = ['all', 'enabled', 'not_enabled'];
|
||||
if (allowed_enabled_list.includes(enabled)) {
|
||||
params['enabled'] = enabled;
|
||||
}
|
||||
|
||||
let allowed_hidden_list = ['all', 'hidden', 'not_hidden'];
|
||||
if (allowed_hidden_list.includes(hidden) ) {
|
||||
params['hidden'] = hidden;
|
||||
}
|
||||
const allowed_hidden_list = ['all', 'hidden', 'not_hidden'];
|
||||
if (allowed_hidden_list.includes(hidden)) {
|
||||
params['hidden'] = hidden;
|
||||
}
|
||||
|
||||
// NOTE: The order_by_li variable is in the "headers" because if is a the URL GET params do not handle multiple values very well. Maybe base64 encore in the future or something? Reminder that GET requests should not have a body (no JSON).
|
||||
// NOTE: The order_by_li should be a key value pair of the property/DB field to sort and how to sort (ASC or DESC)
|
||||
if (order_by_li) {
|
||||
// headers['order_by_li'] = order_by_li;
|
||||
headers['order_by_li'] = JSON.stringify(order_by_li);
|
||||
}
|
||||
// NOTE: The order_by_li variable is in the "headers" because URL GET params do not handle complex objects very well.
|
||||
if (order_by_li) {
|
||||
headers['order_by_li'] = JSON.stringify(order_by_li);
|
||||
}
|
||||
|
||||
if (limit > 0) {
|
||||
params['limit'] = limit;
|
||||
}
|
||||
if (limit > 0) params['limit'] = limit;
|
||||
if (offset > 0) params['offset'] = offset;
|
||||
|
||||
if (offset > 0) {
|
||||
params['offset'] = offset;
|
||||
}
|
||||
if (params_json) {
|
||||
// NOTE: "jp" stands for "JSON Params". This is a JSON object that needs to be safely converted to a string for the params.
|
||||
// Max characters for a GET request is ~2000. This is a limitation of the browser.
|
||||
const json_params_str = encodeURIComponent(JSON.stringify(params_json));
|
||||
if (json_params_str.length > 2083) {
|
||||
// Using console.error instead of throwing an error to avoid crashing the app for a known limitation.
|
||||
console.error(
|
||||
`The JSON object is too large to be used as a GET parameter. Max length is 2083 characters. Length = ${json_params_str.length}`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
params['jp'] = json_params_str;
|
||||
}
|
||||
|
||||
if (params_json) {
|
||||
// NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the search endpoint.
|
||||
// Max characters for a GET request is 2083. This is a limitation of the browser (Microsoft IE and Edge).
|
||||
if (log_lvl) {
|
||||
console.log('JSON Object:', params_json);
|
||||
console.log(JSON.stringify(params_json));
|
||||
}
|
||||
// NOTE: "jp" stands for "JSON Params"
|
||||
params['jp'] = encodeURIComponent(JSON.stringify(params_json));
|
||||
if (params['jp'].length > 2083) {
|
||||
console.log(`The JSON object is too large to be used as a GET parameter. The overall max URL length is 2083 characters. Please use the POST endpoint instead. Length = ${params['jp'].length} [THIS DOES NOT EXIST YET]`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (log_lvl) {
|
||||
console.log('Params:', params);
|
||||
}
|
||||
|
||||
// if (json_obj) {
|
||||
// // NOTE: This is a JSON object that needs to be safely converted to a string for the params. This is used for the search endpoint.
|
||||
// // Max characters for a GET request is 2083. This is a limitation of the browser (Microsoft IE and Edge).
|
||||
// console.log('JSON Object:', json_obj);
|
||||
// params['json_str'] = encodeURIComponent(JSON.stringify(json_obj));
|
||||
// if (params['json_str'].length > 2083) {
|
||||
// console.log(`The JSON object is too large to be used as a GET parameter. The overall max URL length is 2083 characters. Please use the POST endpoint instead. Length = ${params['json_str'].length} [THIS DOES NOT EXIST YET]`);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
const object_li_get_promise = await get_object({
|
||||
api_cfg: api_cfg,
|
||||
endpoint: endpoint,
|
||||
headers: headers,
|
||||
params: params,
|
||||
log_lvl: log_lvl
|
||||
});
|
||||
|
||||
if (log_lvl) {
|
||||
console.log('Params:', params);
|
||||
}
|
||||
if (log_lvl > 1) {
|
||||
console.log(object_li_get_promise);
|
||||
}
|
||||
|
||||
let object_li_get_promise = await get_object({
|
||||
api_cfg: api_cfg,
|
||||
endpoint: endpoint,
|
||||
headers: headers,
|
||||
params: params,
|
||||
// return_meta: return_meta,
|
||||
log_lvl: log_lvl
|
||||
});
|
||||
|
||||
if (log_lvl > 1) {
|
||||
console.log(object_li_get_promise);
|
||||
}
|
||||
|
||||
return object_li_get_promise;
|
||||
}
|
||||
return object_li_get_promise;
|
||||
} catch (error) {
|
||||
console.error('Error in get_ae_obj_li_for_obj_id_crud_v2:', error);
|
||||
return false; // Or handle the error as appropriate
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,91 +1,115 @@
|
||||
import type { Dexie, Table } from 'dexie';
|
||||
|
||||
// This function will save an array of objects to a Dexie database table.
|
||||
// It will first attempt to update existing records using bulkUpdate.
|
||||
// If that fails, it will fall back to bulkPut.
|
||||
// The function takes a database instance, table name, array of objects, and properties to save.
|
||||
// It also accepts a log level for debugging purposes.
|
||||
// Updated 2025-05-09
|
||||
export async function db_save_ae_obj_li__ae_obj({
|
||||
db_instance,
|
||||
table_name,
|
||||
obj_li,
|
||||
properties_to_save,
|
||||
log_lvl = 0,
|
||||
}: {
|
||||
db_instance: any; // The Dexie database instance
|
||||
table_name: string; // The name of the table in the database
|
||||
obj_li: any[];
|
||||
properties_to_save: string[];
|
||||
log_lvl?: number;
|
||||
}) {
|
||||
// log_lvl = 1;
|
||||
if (log_lvl) {
|
||||
console.log(`*** db_save_ae_obj_li__ae_obj() *** table_name=${table_name}`, obj_li);
|
||||
}
|
||||
/**
|
||||
* Extracts the primary key from an object using a prioritized list of possible key names.
|
||||
* @param obj The object to extract the ID from.
|
||||
* @param table_name The name of the table, used to construct legacy key names.
|
||||
* @param log_lvl The logging level.
|
||||
* @returns The found ID, or undefined if no ID could be found.
|
||||
*/
|
||||
function findObjectId(obj: any, table_name: string, log_lvl: number): string | number | undefined {
|
||||
const potentialKeys = ['id', `${table_name}_id`, `${table_name}_id_random`];
|
||||
|
||||
if (!obj_li || obj_li.length === 0) {
|
||||
if (log_lvl) {
|
||||
console.log('No objects to save.');
|
||||
}
|
||||
return [];
|
||||
}
|
||||
for (const key of potentialKeys) {
|
||||
if (obj[key]) {
|
||||
if (key !== 'id' && log_lvl > 0) {
|
||||
console.warn(
|
||||
`Found legacy ID key "${key}" for table "${table_name}". Consider standardizing to "id".`,
|
||||
obj
|
||||
);
|
||||
}
|
||||
return obj[key];
|
||||
}
|
||||
}
|
||||
|
||||
const db_table = db_instance[table_name];
|
||||
if (!db_table) {
|
||||
console.error(`Table not found in ${db_instance}: ${table_name}`);
|
||||
return [];
|
||||
}
|
||||
console.error(`Object is missing a valid ID for table "${table_name}". It will be skipped.`, obj);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const bulkUpdateData = [];
|
||||
const bulkPutData = [];
|
||||
/**
|
||||
* Saves an array of objects to a Dexie database table using bulkPut.
|
||||
* This function handles both creating new records and updating existing ones.
|
||||
*
|
||||
* @param db_instance The Dexie database instance.
|
||||
* @param table_name The name of the table in the database.
|
||||
* @param obj_li The array of objects to save.
|
||||
* @param properties_to_save The list of property names to include in the saved object.
|
||||
* @param log_lvl The logging level for debugging.
|
||||
* @returns A promise that resolves with the keys of the saved objects.
|
||||
* @throws An error if the database operation fails.
|
||||
*
|
||||
* @version 2.0.0
|
||||
* @since 2025-11-13
|
||||
*/
|
||||
export async function db_save_ae_obj_li__ae_obj<T extends Record<string, any>>({
|
||||
db_instance,
|
||||
table_name,
|
||||
obj_li,
|
||||
properties_to_save,
|
||||
log_lvl = 0
|
||||
}: {
|
||||
db_instance: Dexie;
|
||||
table_name: string;
|
||||
obj_li: T[];
|
||||
properties_to_save: (keyof T)[];
|
||||
log_lvl?: number;
|
||||
}) {
|
||||
if (log_lvl > 0) {
|
||||
console.log(
|
||||
`*** db_save_ae_obj_li__ae_obj: Attempting to save ${obj_li.length} objects to table "${table_name}" ***`
|
||||
);
|
||||
}
|
||||
|
||||
for (const obj of obj_li) {
|
||||
const obj_record: Record<string, any> = {};
|
||||
if (!obj_li || obj_li.length === 0) {
|
||||
if (log_lvl > 0) console.log('No objects to save.');
|
||||
return [];
|
||||
}
|
||||
|
||||
// Extract only the specified properties to save
|
||||
for (const prop of properties_to_save) {
|
||||
obj_record[prop] = obj[prop];
|
||||
}
|
||||
const db_table: Table<T> = db_instance.table(table_name);
|
||||
if (!db_table) {
|
||||
const errorMsg = `Table not found in Dexie instance: ${table_name}`;
|
||||
console.error(errorMsg);
|
||||
throw new Error(errorMsg);
|
||||
}
|
||||
|
||||
// Ensure the `id` field is included
|
||||
obj_record.id = obj_record.id || obj.id || obj[`${table_name}_id`] || obj[`${table_name}_id_random`];
|
||||
const dataToSave = obj_li
|
||||
.map((obj) => {
|
||||
const record: Partial<T> = {};
|
||||
|
||||
if (!obj_record.id) {
|
||||
console.error(`Object is missing an ID:`, obj);
|
||||
continue;
|
||||
}
|
||||
// Extract only the specified properties to save.
|
||||
for (const prop of properties_to_save) {
|
||||
record[prop] = obj[prop];
|
||||
}
|
||||
|
||||
// Prepare data for bulkUpdate or bulkPut
|
||||
bulkUpdateData.push({
|
||||
key: obj_record.id,
|
||||
changes: obj_record,
|
||||
});
|
||||
bulkPutData.push(obj_record);
|
||||
}
|
||||
// Ensure the primary key is included, attempting to find it from various legacy keys.
|
||||
const id = findObjectId(obj, table_name, log_lvl);
|
||||
|
||||
// Attempt bulkUpdate first
|
||||
try {
|
||||
const updatedKeys = await db_table.bulkUpdate(bulkUpdateData);
|
||||
if (log_lvl) {
|
||||
console.log(`Bulk update completed. Updated keys:`, updatedKeys);
|
||||
}
|
||||
} catch (error) {
|
||||
// This is fairly common and normal if the object is new
|
||||
if (log_lvl) {
|
||||
console.log(`Bulk update failed. Falling back to bulkPut. This is normal.`, error);
|
||||
}
|
||||
}
|
||||
if (id === undefined) {
|
||||
return null; // Skip objects without a valid ID.
|
||||
}
|
||||
|
||||
// Use bulkPut for any records that couldn't be updated
|
||||
try {
|
||||
const putKeys = await db_table.bulkPut(bulkPutData);
|
||||
if (log_lvl) {
|
||||
console.log(`Bulk put completed. Put keys:`, putKeys);
|
||||
}
|
||||
return putKeys;
|
||||
} catch (error) {
|
||||
// This should not happen if the object is new
|
||||
console.error(`Bulk put failed. Something likely went wrong!`, error);
|
||||
return [];
|
||||
}
|
||||
(record as any).id = id;
|
||||
return record;
|
||||
})
|
||||
.filter(Boolean) as T[];
|
||||
|
||||
if (dataToSave.length === 0) {
|
||||
if (log_lvl > 0) {
|
||||
console.warn('All objects were skipped, likely due to missing IDs.');
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
// bulkPut efficiently handles both inserts and updates.
|
||||
const keys = await db_table.bulkPut(dataToSave);
|
||||
if (log_lvl > 0) {
|
||||
console.log(`Successfully saved ${keys.length} objects to "${table_name}".`);
|
||||
}
|
||||
return keys;
|
||||
} catch (error) {
|
||||
console.error(`Failed to save objects to "${table_name}":`, error);
|
||||
// Re-throw the error to let the caller handle it.
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
import type { key_val } from '$lib/ae_stores';
|
||||
import { api } from '$lib/api';
|
||||
|
||||
import { db_save_ae_obj_li__ae_obj } from "$lib/ae_core/core__idb_dexie";
|
||||
import { db_events } from "$lib/ae_events/db_events";
|
||||
import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';
|
||||
import { db_events } from '$lib/ae_events/db_events';
|
||||
|
||||
import { load_ae_obj_li__event_device } from './ae_events__event_device';
|
||||
import { load_ae_obj_li__event_location } from './ae_events__event_location';
|
||||
import { load_ae_obj_li__event_session } from './ae_events__event_session';
|
||||
import { load_ae_obj_li__event_badge_template } from "$lib/ae_events/ae_events__event_badge_template";
|
||||
import { load_ae_obj_li__event_badge_template } from '$lib/ae_events/ae_events__event_badge_template';
|
||||
|
||||
let ae_promises: key_val = {};
|
||||
|
||||
|
||||
@@ -998,4 +998,4 @@ export async function process_ae_obj__journal_props(
|
||||
}
|
||||
|
||||
return processed_obj_li;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user