mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
ec8ab598cb
Summary: This adds rudimentary support for opening certain SQLite files in Grist. If you have a file such as `landing.db` in Grist, you can convert it to Grist format by doing (either in monorepo or grist-core): ``` yarn run cli -h yarn run cli sqlite -h yarn run cli sqlite gristify landing.db ``` The file is now openable by Grist. To actually do so with the regular Grist server, you'll need to either import it, or convert some doc you don't care about in the `samples/` directory to be a soft link to it (and then force a reload). This implementation is a rudimentary experiment. Here are some awkwardnesses: * Only tables that happen to have a column called `id`, and where the column happens to be an integer, can be opened directly with Grist as it is today. That could be generalized, but it looked more than a Gristathon's worth of work, so I instead used SQLite views. * Grist will handle tables that start with an uncapitalized letter a bit erratically. You can successfully add columns, for example, but removing them will cause sadness - Grist will rename the table in a confused way. * I didn't attempt to deal with column names with spaces etc (though views could deal with those). * I haven't tried to do any fancy type mapping. * Columns with constraints can make adding new rows impossible in Grist, since Grist requires that a row can be added with just a single cell set. Test Plan: added small test Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3502
71 lines
3.6 KiB
TypeScript
71 lines
3.6 KiB
TypeScript
import {DocEntry} from 'app/common/DocListAPI';
|
|
import {DocSnapshots} from 'app/common/DocSnapshot';
|
|
import {DocumentUsage} from 'app/common/DocUsage';
|
|
import {DocReplacementOptions} from 'app/common/UserAPI';
|
|
|
|
export interface IDocStorageManager {
|
|
getPath(docName: string): string;
|
|
getSampleDocPath(sampleDocName: string): string|null;
|
|
getCanonicalDocName(altDocName: string): Promise<string>;
|
|
|
|
// This method must not be called for the same docName twice in parallel.
|
|
// In the current implementation, it is called in the context of an
|
|
// AsyncCreate[docName].
|
|
prepareLocalDoc(docName: string): Promise<boolean>;
|
|
prepareToCreateDoc(docName: string): Promise<void>;
|
|
prepareFork(srcDocName: string, destDocName: string): Promise<string>; // Returns filename.
|
|
|
|
listDocs(): Promise<DocEntry[]>;
|
|
deleteDoc(docName: string, deletePermanently?: boolean): Promise<void>;
|
|
renameDoc(oldName: string, newName: string): Promise<void>;
|
|
makeBackup(docName: string, backupTag: string): Promise<string>;
|
|
showItemInFolder(docName: string): Promise<void>;
|
|
closeStorage(): Promise<void>;
|
|
closeDocument(docName: string): Promise<void>;
|
|
// Mark document as needing a backup (due to edits, migrations, etc).
|
|
// If reason is set to 'edit' the user-facing timestamp on the document should be updated.
|
|
markAsChanged(docName: string, reason?: 'edit'): void;
|
|
scheduleUsageUpdate(docName: string, usage: DocumentUsage|null, minimizeDelay?: boolean): void;
|
|
testReopenStorage(): void; // restart storage during tests
|
|
addToStorage(docName: string): Promise<void>; // add a new local document to storage
|
|
prepareToCloseStorage(): void; // speed up sync with remote store
|
|
getCopy(docName: string): Promise<string>; // get an immutable copy of a document
|
|
|
|
flushDoc(docName: string): Promise<void>; // flush a document to persistent storage
|
|
// If skipMetadataCache is set, then any caching of snapshots lists should be skipped.
|
|
// Metadata may not be returned in this case.
|
|
getSnapshots(docName: string, skipMetadataCache?: boolean): Promise<DocSnapshots>;
|
|
removeSnapshots(docName: string, snapshotIds: string[]): Promise<void>;
|
|
replace(docName: string, options: DocReplacementOptions): Promise<void>;
|
|
}
|
|
|
|
/**
|
|
* A very minimal implementation of IDocStorageManager that is just
|
|
* enough to allow an ActiveDoc to open and get to work.
|
|
*/
|
|
export class TrivialDocStorageManager implements IDocStorageManager {
|
|
public getPath(docName: string): string { return docName; }
|
|
public getSampleDocPath() { return null; }
|
|
public async getCanonicalDocName(altDocName: string) { return altDocName; }
|
|
public async prepareLocalDoc() { return false; }
|
|
public async prepareToCreateDoc() { }
|
|
public async prepareFork(): Promise<never> { throw new Error('no'); }
|
|
public async listDocs() { return []; }
|
|
public async deleteDoc(): Promise<never> { throw new Error('no'); }
|
|
public async renameDoc(): Promise<never> { throw new Error('no'); }
|
|
public async makeBackup(): Promise<never> { throw new Error('no'); }
|
|
public async showItemInFolder(): Promise<never> { throw new Error('no'); }
|
|
public async closeStorage() {}
|
|
public async closeDocument() {}
|
|
public markAsChanged() {}
|
|
public scheduleUsageUpdate() {}
|
|
public testReopenStorage() {}
|
|
public async addToStorage(): Promise<never> { throw new Error('no'); }
|
|
public prepareToCloseStorage() {}
|
|
public async getCopy(): Promise<never> { throw new Error('no'); }
|
|
public async flushDoc() {}
|
|
public async getSnapshots(): Promise<never> { throw new Error('no'); }
|
|
public async removeSnapshots(): Promise<never> { throw new Error('no'); }
|
|
public async replace(): Promise<never> { throw new Error('no'); }
|
|
}
|