diff --git a/packages/api/src/controllers/connections.js b/packages/api/src/controllers/connections.js index db0c95da..37b9252f 100644 --- a/packages/api/src/controllers/connections.js +++ b/packages/api/src/controllers/connections.js @@ -2,8 +2,9 @@ const path = require('path'); const { fork } = require('child_process'); const _ = require('lodash'); const nedb = require('nedb-promises'); +const fs = require('fs-extra'); -const { datadir } = require('../utility/directories'); +const { datadir, filesdir } = require('../utility/directories'); const socket = require('../utility/socket'); const { encryptConnection } = require('../utility/crypting'); const { handleProcessCommunication } = require('../utility/processComm'); @@ -175,4 +176,20 @@ module.exports = { const res = await this.datastore.find({ _id: conid }); return res[0]; }, + + newSqliteDatabase_meta: 'post', + async newSqliteDatabase({ file }) { + const sqliteDir = path.join(filesdir(), 'sqlite'); + if (!(await fs.exists(sqliteDir))) { + await fs.mkdir(sqliteDir); + } + const databaseFile = path.join(sqliteDir, `${file}.sqlite`); + const res = await this.save({ + engine: 'sqlite@dbgate-plugin-sqlite', + databaseFile, + singleDatabase: true, + defaultDatabase: `${file}.sqlite`, + }); + return res; + }, }; diff --git a/packages/web/src/appobj/SavedFileAppObject.svelte b/packages/web/src/appobj/SavedFileAppObject.svelte index 2f2c89d1..fc7a365f 100644 --- a/packages/web/src/appobj/SavedFileAppObject.svelte +++ b/packages/web/src/appobj/SavedFileAppObject.svelte @@ -47,12 +47,21 @@ currentConnection: true, }; + const sqlite: FileTypeHandler = { + icon: 'img sqlite-database', + format: 'binary', + tabComponent: null, + folder: 'sqlite', + currentConnection: true, + }; + const HANDLERS = { sql, shell, markdown, charts, query, + sqlite, }; export const extractKey = data => data.file; @@ -93,7 +102,7 @@ function createMenu() { return [ - { text: 'Open', onClick: openTab }, + handler?.tabComponent && { text: 'Open', onClick: openTab }, hasPermission(`files/${data.folder}/write`) && { text: 'Rename', onClick: handleRename }, hasPermission(`files/${data.folder}/write`) && { text: 'Delete', onClick: handleDelete }, folder == 'markdown' && { text: 'Show page', onClick: showMarkdownPage }, @@ -152,4 +161,11 @@ } - + diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts index e52cd927..c779f61e 100644 --- a/packages/web/src/commands/stdCommands.ts +++ b/packages/web/src/commands/stdCommands.ts @@ -1,6 +1,6 @@ import { currentDatabase, currentTheme, extensions, getExtensions, getVisibleToolbar, visibleToolbar } from '../stores'; import registerCommand from './registerCommand'; -import { derived, get } from 'svelte/store'; +import { get } from 'svelte/store'; import { ThemeDefinition } from 'dbgate-types'; import ConnectionModal from '../modals/ConnectionModal.svelte'; import AboutModal from '../modals/AboutModal.svelte'; @@ -17,9 +17,11 @@ import { getDefaultFileFormat } from '../plugins/fileformats'; import { getCurrentConfig, getCurrentDatabase } from '../stores'; import './recentDatabaseSwitch'; import hasPermission from '../utility/hasPermission'; +import axiosInstance from '../utility/axiosInstance'; import _ from 'lodash'; import { findEngineDriver } from 'dbgate-tools'; import { openArchiveFolder } from '../utility/openArchiveFolder'; +import InputTextModal from '../modals/InputTextModal.svelte'; const electron = getElectron(); @@ -185,6 +187,25 @@ registerCommand({ }, }); +registerCommand({ + id: 'new.sqliteDatabase', + category: 'New', + icon: 'img sqlite-database', + name: 'New SQLite database', + onClick: () => { + showModal(InputTextModal, { + value: 'newdb', + label: 'New database name', + header: 'Create SQLite database', + onConfirm: async file => { + const resp = await axiosInstance.post('connections/new-sqlite-database', { file }); + const connection = resp.data; + currentDatabase.set({ connection, name: `${file}.sqlite` }); + }, + }); + }, +}); + registerCommand({ id: 'group.save', category: null, diff --git a/packages/web/src/icons/FontIcon.svelte b/packages/web/src/icons/FontIcon.svelte index 4f38e6cc..865005f6 100644 --- a/packages/web/src/icons/FontIcon.svelte +++ b/packages/web/src/icons/FontIcon.svelte @@ -116,6 +116,7 @@ 'img macro': 'mdi mdi-hammer-wrench', 'img database': 'mdi mdi-database color-icon-gold', + 'img sqlite-database': 'mdi mdi-database color-icon-blue', 'img table': 'mdi mdi-table color-icon-blue', 'img collection': 'mdi mdi-table color-icon-red', 'img view': 'mdi mdi-table color-icon-magenta', diff --git a/packages/web/src/widgets/SavedFilesList.svelte b/packages/web/src/widgets/SavedFilesList.svelte index 357133ed..fc9fecbc 100644 --- a/packages/web/src/widgets/SavedFilesList.svelte +++ b/packages/web/src/widgets/SavedFilesList.svelte @@ -12,6 +12,7 @@ import { useFiles } from '../utility/metadataLoaders'; const markdownFiles = useFiles({ folder: 'markdown' }); const chartFiles = useFiles({ folder: 'charts' }); const queryFiles = useFiles({ folder: 'query' }); + const sqliteFiles = useFiles({ folder: 'sqlite' }); $: files = [ ...($sqlFiles || []), @@ -19,6 +20,7 @@ import { useFiles } from '../utility/metadataLoaders'; ...($markdownFiles || []), ...($chartFiles || []), ...($queryFiles || []), + ...($sqliteFiles || []), ]; diff --git a/plugins/dbgate-plugin-sqlite/src/frontend/driver.js b/plugins/dbgate-plugin-sqlite/src/frontend/driver.js index daebbf90..4bd8de2e 100644 --- a/plugins/dbgate-plugin-sqlite/src/frontend/driver.js +++ b/plugins/dbgate-plugin-sqlite/src/frontend/driver.js @@ -16,7 +16,7 @@ const dialect = { offsetFetchRangeSyntax: false, explicitDropConstraint: true, stringEscapeChar: "'", - fallbackDataType: 'nvarchar(max)', + fallbackDataType: 'nvarchar', dropColumnDependencies: ['indexes', 'primaryKey', 'uniques'], quoteIdentifier(s) { return `[${s}]`;