// @ts-ignore import sqlite3InitModule from "@sqlite.org/sqlite-wasm" import { SetterOrUpdater } from "recoil" type SQLite3DB = { exec(options: { sql: string // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (...args: any[]) => void }): void } export const loadStorage = ( arrayBuffer: ArrayBuffer, setter: SetterOrUpdater ): void => { sqlite3InitModule({ // eslint-disable-next-line @typescript-eslint/no-explicit-any print: (...args: any): void => { console.log(args) }, // eslint-disable-next-line @typescript-eslint/no-explicit-any printErr: (...args: any): void => { console.log(args) }, // @ts-ignore }).then((sqlite3) => { const p = sqlite3.wasm.allocFromTypedArray(arrayBuffer) const db = new sqlite3.oo1.DB() const rc = sqlite3.capi.sqlite3_deserialize( // @ts-ignore db.pointer, "main", p, arrayBuffer.byteLength, arrayBuffer.byteLength, sqlite3.capi.SQLITE_DESERIALIZE_FREEONCLOSE ) db.checkRc(rc) try { if (!isSupportedSchema(db)) { return } const studies = getStudies(db) setter((prev) => [...prev, ...studies]) } finally { db.close() } }) } const isSupportedSchema = (db: SQLite3DB): boolean => { let supported = true db.exec({ sql: "SELECT schema_version FROM version_info LIMIT 1", // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (vals: any[]) => { if (vals[0] != 12) { supported = false } }, }) return supported } const getStudies = (db: SQLite3DB): Study[] => { const studies: Study[] = [] db.exec({ sql: "SELECT s.study_id, s.study_name, sd.direction, sd.objective" + " FROM studies AS s INNER JOIN study_directions AS sd" + " ON s.study_id = sd.study_id ORDER BY sd.study_direction_id", // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (vals: any[]) => { const studyId = vals[0] const studyName = vals[1] const direction: StudyDirection = vals[2] === "MINIMIZE" ? "minimize" : "maximize" const objective = vals[3] const trials = getTrials(db, studyId) const union_search_space: SearchSpaceItem[] = [] let intersection_search_space: Set = new Set() trials.forEach((trial) => { const params: TrialParam[] = [] const param_names = new Set() db.exec({ sql: "SELECT param_name, param_value" + ` FROM trial_params WHERE trial_id = ${trial.trial_id}`, // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (vals: any[]) => { const param_name = vals[0] // TODO(c-bata): Support param_external_value params.push({ name: param_name, param_internal_value: vals[1], }) param_names.add(param_name) if ( union_search_space.findIndex((s) => s.name === param_name) == -1 ) { union_search_space.push({ name: param_name }) } }, }) if (intersection_search_space.size === 0) { param_names.forEach((s) => { intersection_search_space.add({ name: s, }) }) } else { intersection_search_space = new Set( Array.from(intersection_search_space).filter((s) => param_names.has(s.name) ) ) } trial.params = params }) if (objective === 0) { studies.push({ study_id: studyId, study_name: studyName, directions: [direction], union_search_space: union_search_space, intersection_search_space: Array.from(intersection_search_space), trials: trials, }) return } const index = studies.findIndex((s) => s.study_id === studyId) studies[index].directions.push(direction) }, }) return studies } const getTrials = (db: SQLite3DB, studyId: number): Trial[] => { const trials: Trial[] = [] db.exec({ sql: "SELECT trial_id, number, state, datetime_start, datetime_complete FROM trials" + ` WHERE study_id = ${studyId} ORDER BY number`, // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (vals: any[]) => { const trialId = vals[0] const state: TrialState = vals[2] === "COMPLETE" ? "Complete" : vals[2] === "PRUNED" ? "Pruned" : vals[2] === "RUNNING" ? "Running" : vals[2] === "WAITING" ? "Waiting" : "Fail" const trial: Trial = { trial_id: trialId, number: vals[1], study_id: studyId, state: state, values: getTrialValues(db, trialId), params: [], // Set this column later intermediate_values: getTrialIntermediateValues(db, trialId), datetime_start: vals[3], datetime_complete: vals[4], } trials.push(trial) }, }) return trials } const getTrialValues = (db: SQLite3DB, trialId: number): TrialValueNumber[] => { const values: TrialValueNumber[] = [] db.exec({ sql: "SELECT value, value_type" + ` FROM trial_values WHERE trial_id = ${trialId}` + " ORDER BY objective", // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (vals: any[]) => { values.push( vals[1] === "INF_NEG" ? "-inf" : vals[1] === "INF_POS" ? "+inf" : vals[0] ) }, }) return values } const getTrialIntermediateValues = ( db: SQLite3DB, trialId: number ): TrialIntermediateValue[] => { const values: TrialIntermediateValue[] = [] db.exec({ sql: "SELECT step, intermediate_value, intermediate_value_type" + ` FROM trial_values WHERE trial_id = ${trialId}` + " ORDER BY step", // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (vals: any[]) => { values.push({ step: vals[0], value: vals[2] === "INF_NEG" ? "-inf" : vals[2] === "INF_POS" ? "+inf" : vals[1], }) }, }) return values }