Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d16a30064 | |||
| cf601c33c0 | |||
| ea3a61077a | |||
| d1a898b40d | |||
| a521a81ef0 | |||
| ab5a54dbb6 | |||
| 44ad8fa60a | |||
| 5b27a241d7 | |||
| 084019ca65 | |||
| ba147af8fe | |||
| 1b3f4db07d | |||
| c36705d458 | |||
| 0e126cb8cf | |||
| c48183a539 | |||
| 50f380dbbe | |||
| 66023a9a68 | |||
| c3fbc3354c | |||
| a7d2ed11f3 | |||
| 6a3dc92572 | |||
| e3a4667422 | |||
| c4dd99bba9 | |||
| 588b6f9882 | |||
| 375f69ca1e | |||
| a32e5cc139 | |||
| 8e00137751 | |||
| 003db50833 | |||
| bc519c2c20 | |||
| 3b41fa8cfa | |||
| 39ed0f6d2d | |||
| 710f796832 | |||
| 9ec5fb7263 | |||
| 407db457d5 | |||
| 0c5d2cfcd1 | |||
| 87ace375bb | |||
| d010020f3b | |||
| c60227a98f | |||
| 2824681bff | |||
| 073a3e3946 | |||
| 93e91127a0 | |||
| b60a6cff56 | |||
| 1f3b1963d9 | |||
| 4915f57abb | |||
| 97c6fc97d5 | |||
| b68421bbc3 | |||
| 2d10559754 | |||
| b398a7b546 | |||
| 1711d2102d | |||
| 97cea230f3 | |||
| b6a0fe9465 | |||
| 06c50659bb | |||
| 244b47f548 | |||
| b72a244d93 | |||
| c1e069d4dc | |||
| f99994085a | |||
| 32fd0dd78c | |||
| a557b6b2b4 | |||
| e84583c776 | |||
| a548b0d543 | |||
| de94f15383 | |||
| 7045d986ef | |||
| de7ae9cf09 | |||
| ab3d6888dc | |||
| 98a70891f3 | |||
| 52e7326a2c | |||
| bfd2e3b07a | |||
| 799f5e30d3 | |||
| d3e544c3c0 | |||
| 866fd55834 | |||
| 74ce1fba32 | |||
| a11b93b4cc | |||
| 066f2baa03 | |||
| e02396280f | |||
| a654c80746 | |||
| 3b50f4bd7c | |||
| cc1f77f5bc | |||
| 381fce4a82 | |||
| bc3be97cee | |||
| 1c389208a7 | |||
| cbeed2d3d0 | |||
| 3d974ad144 | |||
| 749042a05d | |||
| 52413b82ee | |||
| 212a7ec083 | |||
| cee94fe113 | |||
| e1ead2519a | |||
| 80330a25ac | |||
| 508470e970 | |||
| bc64b4b5c7 | |||
| 48d8494ead | |||
| 2a51d2ed96 | |||
| cfabcc7bf6 | |||
| 90fc8fd0fc |
@@ -47,7 +47,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: c33e71a6ddc30d8ce59cf0351e04e08f6be272a3
|
||||
ref: 5baa88d0ad253537298e911868579bae0835888d
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: c33e71a6ddc30d8ce59cf0351e04e08f6be272a3
|
||||
ref: 5baa88d0ad253537298e911868579bae0835888d
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: c33e71a6ddc30d8ce59cf0351e04e08f6be272a3
|
||||
ref: 5baa88d0ad253537298e911868579bae0835888d
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: c33e71a6ddc30d8ce59cf0351e04e08f6be272a3
|
||||
ref: 5baa88d0ad253537298e911868579bae0835888d
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: c33e71a6ddc30d8ce59cf0351e04e08f6be272a3
|
||||
ref: 5baa88d0ad253537298e911868579bae0835888d
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -56,7 +56,10 @@ jobs:
|
||||
working-directory: packages/sqltree
|
||||
run: |
|
||||
npm publish --tag "$NPM_TAG"
|
||||
|
||||
- name: Publish rest
|
||||
working-directory: packages/rest
|
||||
run: |
|
||||
npm publish --tag "$NPM_TAG"
|
||||
- name: Publish api
|
||||
working-directory: packages/api
|
||||
run: |
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: c33e71a6ddc30d8ce59cf0351e04e08f6be272a3
|
||||
ref: 5baa88d0ad253537298e911868579bae0835888d
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
@@ -132,6 +132,10 @@ jobs:
|
||||
image: redis
|
||||
ports:
|
||||
- '16011:6379'
|
||||
dynamodb:
|
||||
image: amazon/dynamodb-local
|
||||
ports:
|
||||
- '16015:8000'
|
||||
mssql:
|
||||
image: mcr.microsoft.com/mssql/server
|
||||
ports:
|
||||
|
||||
+196
-41
@@ -1,14 +1,38 @@
|
||||
# ChangeLog
|
||||
|
||||
Builds:
|
||||
- docker - build
|
||||
- npm - npm package dbgate-serve
|
||||
- app - classic electron app
|
||||
- mac - application for macOS
|
||||
- linux - application for linux
|
||||
- win - application for Windows
|
||||
|
||||
- docker - build
|
||||
- npm - npm package dbgate-serve
|
||||
- app - classic electron app
|
||||
- mac - application for macOS
|
||||
- linux - application for linux
|
||||
- win - application for Windows
|
||||
|
||||
## 7.1.5
|
||||
|
||||
- FIXED: Issues with cloud and file loading
|
||||
- ADDED: Support for displaying MongoDB UUID #1394
|
||||
- ADDED: SVG icon sanitization
|
||||
|
||||
## 7.1.4
|
||||
|
||||
- FIXED: NPM installation failure #1375
|
||||
|
||||
## 7.1.3
|
||||
|
||||
- FIXED: "Add files" button in import/export #1373
|
||||
- FIXED: Importing XLSX files #1379
|
||||
- ADDED: Ability to set default transaction isolation level for connections #1376
|
||||
- ADDED: Option to set transaction isolation level directly in Query Tab #1376
|
||||
- ADDED: Filtering of SQL Scripts by connection and database name #1377
|
||||
- ADDED: Proxy configuration support for OData, OpenAPI and GraphQL (Premium) #1381
|
||||
- CHANGED: Updated DuckDB version to 1.5.0 #1386
|
||||
- FIXED: DuckDB column order in query result #1385
|
||||
- FIXED: Administration panel not displayed for authorized users (Team Premium) #1374
|
||||
|
||||
## 7.1.2
|
||||
|
||||
- ADDED: GraphQL chat - AI chat with GraphQL endpoint (Premium)
|
||||
- FIXED: Error "400 Provider returned error" in Database Chat (Premium)
|
||||
- CHANGED: Upgraded AI components to latest versions, improved stability and performance of AI features (Premium)
|
||||
@@ -16,6 +40,7 @@ Builds:
|
||||
- CHANGED: Upgraded some internal building components (svelte-preprocess, typescript)
|
||||
|
||||
## 7.1.1
|
||||
|
||||
- CHANGED: Fixed some DynamoDB issues, improved filtering performance
|
||||
- FIXED: Afilter filter scroll issue #1370
|
||||
- FIXED: Team Premium - filtering by connection in database and table permissions
|
||||
@@ -24,10 +49,10 @@ Builds:
|
||||
- FIXED: Firebird - improved connectivity & table loading #1324
|
||||
- ADDED: New GraphQL query option, changed GraphQL query icon (Premium)
|
||||
|
||||
|
||||
## 7.1.0
|
||||
|
||||
- ADDED: Support for Amazon DynamoDB (Premium)
|
||||
- ADDED: Connect to API endpoints - OpenAPI (Swagger), GraphQL and oData (Premium)
|
||||
- ADDED: Connect to API endpoints - OpenAPI (Swagger), GraphQL and oData (Premium)
|
||||
- FIXED: Redis key list infinite loading when first key hierarchy segment is numeric (e.g. "0:profile:1234") #1363
|
||||
- FIXED: Sum of PostgreSQL numeric values always 0 #1354
|
||||
- FIXED: SQL SERVER Table structure key duplication #1351
|
||||
@@ -37,10 +62,12 @@ Builds:
|
||||
- CHANGED: Used rolldown bundler instead of legacy rollup
|
||||
|
||||
## 7.0.6
|
||||
|
||||
- ADDED: Reset password for Team Premium edition
|
||||
- ADDED: Encrypting passwords sent to frontend when using SHELL_CONNECTION=1 in Docker Community edition #1357
|
||||
|
||||
## 7.0.4
|
||||
|
||||
- FIXED: MS SQL server export to CSV does not convert bit FALSE to 0 #1276
|
||||
- ADDED: MySQL FULLTEXT support #1305
|
||||
- FIXED: Error messages in Chinese will display garbled characters(MS SQL over ODBC) #1321
|
||||
@@ -53,6 +80,7 @@ Builds:
|
||||
- CHANGED: Improved custom connection color palette
|
||||
|
||||
## 7.0.3
|
||||
|
||||
- FIXED: Optimalized loading MySQL primary keys #1261
|
||||
- FIXED: Test connection now works for MS Entra authentication #1315
|
||||
- FIXED: SQL Server - Unable to use 'Is Empty or Null' or 'Has Not Empty Value' filters on a field with data type TEXT #1338
|
||||
@@ -64,6 +92,7 @@ Builds:
|
||||
- CHANGED: Upgraded node for DbGate AWS distribution
|
||||
|
||||
## 7.0.1
|
||||
|
||||
- FIXED: Foreign key actions not detected on PostgreSQL #1323
|
||||
- FIXED: Vulnerabilities in bundled dependencies: axios, cross-spawn, glob #1322
|
||||
- FIXED: The JsonB field in the cell data view always displays as null. #1320
|
||||
@@ -74,6 +103,7 @@ Builds:
|
||||
- ADDED: Default editor theme is part of application theme now
|
||||
|
||||
## 7.0.0
|
||||
|
||||
- CHANGED: New design of application, new theme system
|
||||
- ADDED: Theme AI assistant - create custom themes using AI (Premium)
|
||||
- CHANGED: Themes are now defined in JSON files, custom themes could be shared via DbGate Cloud
|
||||
@@ -89,12 +119,15 @@ Builds:
|
||||
- ADDED: Widget for currently opened tabs
|
||||
|
||||
## 6.8.2
|
||||
|
||||
- FIXED: Initialize storage database from envoronment variables failed with PostgreSQL
|
||||
|
||||
## 6.8.1
|
||||
|
||||
- FIXED: Won't navigate to the relevant field on click of a field in columns #1303
|
||||
|
||||
## 6.8.0
|
||||
|
||||
- ADDED: Form cell view for detailed data inspection and editing in data grids, with multi-row bulk editing support
|
||||
- CHANGED: Cell data sidebar moved to right side, now is part of data grid
|
||||
- FIXED: Improved widget resizing algorithm
|
||||
@@ -113,11 +146,13 @@ Builds:
|
||||
- ADDED: Import connections from environment variables (Team Premium)
|
||||
|
||||
## 6.7.3
|
||||
|
||||
- FIXED: Fixed problem in analyser core - in PostgreSQL, after dropping table, dropped table still appeared in structure
|
||||
- FIXED: PostgreSQL numeric columns do not align right #1254
|
||||
- ADDED: Custom thousands separator #1213
|
||||
|
||||
## 6.7.2
|
||||
|
||||
- CHANGED: Settings modal redesign - now is settings opened in tab instead of modal, similarily as in VSCode
|
||||
- FIXED: Fixed search in table shortcuts #1273
|
||||
- CHANGED: Improved foreign key editor UX
|
||||
@@ -127,6 +162,7 @@ Builds:
|
||||
- CHANGED: Improved storage of settings, especially for Team Premium edition
|
||||
|
||||
## 6.7.1
|
||||
|
||||
- ADDED: LANGUAGE environment variable for the web version. #1266
|
||||
- ADDED: New localizations (Italian, Portugese (Brazil), Japanese)
|
||||
- ADDED: Option to detect language from browser settings in web version
|
||||
@@ -140,6 +176,7 @@ Builds:
|
||||
- ADDED: Other files types supported in Team Premium edition (diagrams, query design, perspectives, import/export jobs, shell scripts, database compare jobs)
|
||||
|
||||
## 6.7.0
|
||||
|
||||
- ADDED: Added localization support, now you can use DbGate in multiple languages (French, Spanish, German, Czech, Slovak, Simplified Chinese) #347 #705 #939 #1079
|
||||
- CHANGED: Solved many issues with binary fields, huge performance improvements in binary fields processing
|
||||
- FIXED: Export to CSV produces empty file #1247
|
||||
@@ -153,13 +190,16 @@ Builds:
|
||||
- FIXED: Horizontal scrolling on macOS trackpad/Magic Mouse #1250
|
||||
|
||||
## 6.6.12
|
||||
|
||||
- FIXED: Cannot paste license key on Mac (special commands like copy/paste were disabled on license screen)
|
||||
|
||||
## 6.6.11
|
||||
|
||||
- FIXED: Fixed theming on application startup
|
||||
- CHANGED: Improved licensing page
|
||||
|
||||
## 6.6.10
|
||||
|
||||
- FIXED: License from environment variable is not refreshed #1245
|
||||
- FIXED: connection closing / reconnecting #1237
|
||||
- ADDED: retain history across multiple queries #1236
|
||||
@@ -167,19 +207,22 @@ Builds:
|
||||
- FIXED: Not possible to scroll the data view horizontally by pressing shift and scroll mouse middle button on Mac #453
|
||||
- FIXED: Expired trial workflow (Premium)
|
||||
- ADDED: Column name collision resolving #1234 (MySQL)
|
||||
|
||||
|
||||
## 6.6.8
|
||||
|
||||
- CHANGED: Windows executable now uses Azure trusted signing certificate
|
||||
- CHANGED: NPM packages now use GitHub OIDC provenance signing for better security
|
||||
- CHANGED: Some features moved to Premium edition (master/detail views, FK lookups, column expansion, split view, advanced export/import, data archives, grouping, macros)
|
||||
|
||||
## 6.6.6
|
||||
|
||||
- ADDED: Allow disable/re-enable filter #1174
|
||||
- ADDED: Close right side tabs #1219
|
||||
- ADDED: Ability disable execute current line in query editor #1209
|
||||
- ADDED: Support for Redis Cluster #1204 (Premium)
|
||||
|
||||
## 6.6.5
|
||||
|
||||
- ADDED: SQL AI assistant - powered by database chat, could help you to write SQL queries (Premium)
|
||||
- ADDED: Explain SQL error (powered by AI) (Premium)
|
||||
- ADDED: Database chat (and SQL AI Assistant) now supports showing charts (Premium)
|
||||
@@ -188,6 +231,7 @@ Builds:
|
||||
- FIXED: Cannot open up large JSON file #1215
|
||||
|
||||
## 6.6.4
|
||||
|
||||
- ADDED: AI Database chat now supports much more LLM models. (Premium)
|
||||
- ADDED: Possibility to use your own API key with OPENAI-compatible providers (OpenRouter, Antropic...)
|
||||
- ADDED: Possibility to use self-hosted own LLM (eg. Llama)
|
||||
@@ -201,11 +245,13 @@ Builds:
|
||||
- CHANGED: Community edition now supports shared folders in read-only mode
|
||||
|
||||
## 6.6.3
|
||||
|
||||
- FIXED: Error “db.getCollection(…).renameCollection is not a function” when renaming collection in dbGate #1198
|
||||
- FIXED: Can't list databases from Azure SQL SERVER #1197
|
||||
- ADDED: Save zoom level in electron apps
|
||||
|
||||
## 6.6.2
|
||||
|
||||
- ADDED: List of processes, ability to kill process (Server summary) #1178
|
||||
- ADDED: Database and table permissions (Team Premium edition)
|
||||
- ADDED: Redis search box - Scan all #1191
|
||||
@@ -215,6 +261,7 @@ Builds:
|
||||
- FIXED: Executing queries for SQLite crash #1195
|
||||
|
||||
## 6.6.1
|
||||
|
||||
- ADDED: Support for Mongo shell (Premium) - #1114
|
||||
- FIXED: Support for BLOB in Oracle #1181
|
||||
- ADDED: Connect to named SQL Server instance #340
|
||||
@@ -224,12 +271,14 @@ Builds:
|
||||
- CHANGED: Improved logging system, added related database and connection to logs metadata
|
||||
|
||||
## 6.6.0
|
||||
|
||||
- ADDED: Database chat - AI powered chatbot, which knows your database (Premium)
|
||||
- ADDED: Firestore support (Premium)
|
||||
- REMOVED: Query AI assistant (replaced by Database Chat) (Premium)
|
||||
- FIXED: Chart permissions were ignored (Premium)
|
||||
- REMOVED: Query AI assistant (replaced by Database Chat) (Premium)
|
||||
- FIXED: Chart permissions were ignored (Premium)
|
||||
|
||||
## 6.5.6
|
||||
|
||||
- ADDED: New object window - quick access to most common functions
|
||||
- ADDED: Possibility to disable split query by empty line #1162
|
||||
- ADDED: Possibility to opt out authentication #1152
|
||||
@@ -238,6 +287,7 @@ Builds:
|
||||
- FIXED: Fixed some minor problems of charts
|
||||
|
||||
## 6.5.5
|
||||
|
||||
- ADDED: Administer cloud folder window
|
||||
- CHANGED: Cloud menu redesign
|
||||
- ADDED: Audit log (for Team Premium edition)
|
||||
@@ -247,25 +297,29 @@ Builds:
|
||||
- ADDED: Added chart data type detection
|
||||
- FIXED: Fixed chart displaying problems
|
||||
- FIXED: Fixed exporting chart to HTML
|
||||
- CHANGED: Choose COUNT measure without selecting underlying ID field (use virtual __count)
|
||||
- CHANGED: Choose COUNT measure without selecting underlying ID field (use virtual \_\_count)
|
||||
- FIXED: Problems with authentification administration, especially for Postgres storage
|
||||
- CHANGED: Anonymous autentification (in Team Premium) is now by default disabled
|
||||
- CHANGED: Anonymous autentification (in Team Premium) is now by default disabled
|
||||
|
||||
## 6.5.3
|
||||
|
||||
- CHANGED: Improved DbGate Cloud sign-in workflow
|
||||
- FIXED: Some fixes and error handling in new charts engine
|
||||
- ADDED: Charts - ability to choose aggregate function
|
||||
- CHANGED: Improved About window
|
||||
|
||||
## 6.5.2
|
||||
|
||||
- CHANGED: Autodetecting charts is disabled by default #1145
|
||||
- CHANGED: Improved chart displaying workflow
|
||||
- ADDED: Ability to close chart
|
||||
|
||||
## 6.5.1
|
||||
|
||||
- FIXED: DbGate Cloud e-mail sign-in method for desktop clients
|
||||
|
||||
## 6.5.0
|
||||
|
||||
- ADDED: DbGate cloud - online storage for connections, SQL scripts and other objects
|
||||
- ADDED: Public knowledge base - common SQL scripts for specific DB engines (table sizes, index stats etc.)
|
||||
- ADDED: Query results could be visualised in charts (Premium)
|
||||
@@ -286,7 +340,7 @@ Builds:
|
||||
|
||||
## 6.4.2
|
||||
|
||||
- ADDED: Source label to docker container #1105
|
||||
- ADDED: Source label to docker container #1105
|
||||
- FIXED: DbGate restart needed to take effect after trigger is created/deleted on mariadb #1112
|
||||
- ADDED: View PostgreSQL query console output #1108
|
||||
- FIXED: Single quote generete MySql error #1107
|
||||
@@ -296,6 +350,7 @@ Builds:
|
||||
- FIXED: Fixed loading Redis keys with :: in key name
|
||||
|
||||
## 6.4.0
|
||||
|
||||
- ADDED: DuckDB support
|
||||
- ADDED: Data deployer (Premium)
|
||||
- ADDED: Compare data between JSON lines file in archive and database table
|
||||
@@ -317,6 +372,7 @@ Builds:
|
||||
- CHANGED: Amazon and Azure instalations are not auto-upgraded by default
|
||||
|
||||
## 6.3.3
|
||||
|
||||
- CHANGED: New administration UI, redesigned administration of users, connections and roles
|
||||
- ADDED: Encrypting passwords in team-premium edition
|
||||
- ADDED: Show scale bar on map #1090
|
||||
@@ -326,6 +382,7 @@ Builds:
|
||||
- ADDED: Line Wrap for JSON viewer #768
|
||||
|
||||
### 6.3.2
|
||||
|
||||
- ADDED: "Use system theme" switch, use changed system theme without restart #1084
|
||||
- ADDED: "Skip SETNAME instruction" option for Redis #1077
|
||||
- FIXED: Clickhouse views are now available even for user with limited permissions #1076
|
||||
@@ -338,6 +395,7 @@ Builds:
|
||||
- FIXED: Correctly end connection process after succesful/unsuccesful connect
|
||||
|
||||
### 6.3.0
|
||||
|
||||
- ADDED: Support for libSQL and Turso (Premium)
|
||||
- ADDED: Native backup and restore database for MySQL and PostgreSQL (Premium)
|
||||
- REMOVED: DbGate internal dump export for MySQL (replaced with call of mysqldump)
|
||||
@@ -349,6 +407,7 @@ Builds:
|
||||
- FIXED: Linux Appimage crash => A JavaScript error occurred in the main process #1065 , #1067
|
||||
|
||||
### 6.2.1
|
||||
|
||||
- ADDED: Commit/rollback and autocommit in scripts #1039
|
||||
- FIXED: Doesn't import all the records from MongoDB #1044
|
||||
- ADDED: Show server name alongside database name in title of the tab group #1041
|
||||
@@ -361,6 +420,7 @@ Builds:
|
||||
- CHANGED: Upgraded SQLite engine version
|
||||
|
||||
### 6.2.0
|
||||
|
||||
- ADDED: Query AI Assistant (Premium)
|
||||
- ADDED: Cassandra database support
|
||||
- ADDED: XML cell data view
|
||||
@@ -373,13 +433,16 @@ Builds:
|
||||
- CHANGED: Open real executed query, when datagrid shows loading error
|
||||
|
||||
### 6.1.6
|
||||
|
||||
- FIXED: Hotfix build process for premium edition
|
||||
|
||||
### 6.1.5
|
||||
|
||||
- FIXED: Serious security hotfix (for Docker and NPM, when using LOGIN and PASSWORD environment variables or LOGIN_PASSWORD_xxx)
|
||||
- no changes for desktop app and for Team premium edition, when using storage DB
|
||||
|
||||
### 6.1.4
|
||||
|
||||
- CHANGED: Show Data/Structure button in one place #1015
|
||||
- ADDED: Data view coloring (every second row) #1014
|
||||
- ADDED: Pin icon for tab in preview mode (#1013)
|
||||
@@ -394,11 +457,12 @@ Builds:
|
||||
- ADDED: Redis JSON format for String values #852
|
||||
|
||||
### 6.1.3
|
||||
|
||||
- FIXED: Fulltext search now shows correctly columns and SQL code lines
|
||||
- ADDED: Configuration of SSH tunnel local host (IPv4 vs IPv6). Should fix majority of SSH tunnel problems
|
||||
- FIXED: Handled SSH tunnel connection error, now it shows error instead of connecting forever
|
||||
- ADDED: Support of triggers (SQLite)
|
||||
- ADDED: Create, drop trigger
|
||||
- ADDED: Create, drop trigger
|
||||
- ADDED: Support for MySQL scheduled events
|
||||
- FIXED: Cannot connect to DB using askUser/askPassword mode #995
|
||||
- FIXED: Filtering in Oracle #992
|
||||
@@ -406,6 +470,7 @@ Builds:
|
||||
- ADDED: Introduced E2E Cypress tests, test refactor
|
||||
|
||||
### 6.1.1
|
||||
|
||||
- ADDED: Trigger support (SQL Server, PostgreSQL, MySQL, Oracle)
|
||||
- FIXED: PostgreSQL and Oracle export #970
|
||||
- FIXED: Cursor Becomes Stuck When Escaping "Case" #954
|
||||
@@ -413,6 +478,7 @@ Builds:
|
||||
- FIXED: Search in packed list
|
||||
|
||||
### 6.1.0
|
||||
|
||||
- ADDED: Fulltext search in DB model and connections, highlight searched names
|
||||
- ADDED: Tab preview mode configuration #963
|
||||
- CHANGED: Single-click to open server connection/database + ability to configure this #959
|
||||
@@ -429,6 +495,7 @@ Builds:
|
||||
- ADDED: Display comment into tables and column list #755
|
||||
|
||||
### 6.0.0
|
||||
|
||||
- ADDED: Order or filter the indexes for huge tables #922
|
||||
- ADDED: Empty string filters
|
||||
- CHANGED: (Premium) Workflow for new installation (used in Docker and AWS distribution)
|
||||
@@ -461,6 +528,7 @@ Builds:
|
||||
- ADDED: Show SQL quick view
|
||||
|
||||
### 5.5.6
|
||||
|
||||
- FIXED: DbGate process consumes 100% after UI closed - Mac, Linux (#917, #915)
|
||||
- FIXED: Correctly closing connection behind SSH tunnel (#920)
|
||||
- FIXED: Updating MongoDB documents on MongoDB 4 (#916)
|
||||
@@ -468,6 +536,7 @@ Builds:
|
||||
- FIXED: (Premium) Better handling of connection storage errors
|
||||
|
||||
### 5.5.5
|
||||
|
||||
- ADDED: AWS IAM authentication for MySQL, MariaDB, PostgreSQL (Premium)
|
||||
- FIXED: Datitme filtering #912
|
||||
- FIXED: Load redis keys
|
||||
@@ -478,6 +547,7 @@ Builds:
|
||||
- FIXED: Save connection params in administration for MS SQL and Postgres storages (Team Premium)
|
||||
|
||||
### 5.5.4
|
||||
|
||||
- FIXED: correct handling when use LOGIN and PASSWORD env variables #903
|
||||
- FIXED: fixed problems in dbmodel commandline tool
|
||||
- ADDED: dbmodel - allow connection defined in environment variables
|
||||
@@ -489,6 +559,7 @@ Builds:
|
||||
- ADDED: (Premium) Show purchase button after trial license is expired
|
||||
|
||||
### 5.5.3
|
||||
|
||||
- FIXED: Separate schema mode #894 - for databases with many schemas
|
||||
- FIXED: Sort by UUID column in POstgreSQL #895
|
||||
- ADDED: Load pg_dump outputs #893
|
||||
@@ -498,9 +569,11 @@ Builds:
|
||||
- FIXED: MS Entra authentication for Azure SQL
|
||||
|
||||
### 5.5.2
|
||||
|
||||
- FIXED: MySQL, PostgreSQL readonly conections #900
|
||||
|
||||
### 5.5.1
|
||||
|
||||
- ADDED: Clickhouse support (#532)
|
||||
- ADDED: MySQL - specify table engine, show table engine in table list
|
||||
- FIXED: Hidden primary key name in PK editor for DB engines with anonymous PK (MySQL)
|
||||
@@ -528,6 +601,7 @@ Builds:
|
||||
- ADDED: (Premium) MS Entra authentization for Azure SQL databases
|
||||
|
||||
### 5.4.4
|
||||
|
||||
- CHANGED: Improved autoupdate, notification is now in app
|
||||
- CHANGED: Default behaviour of autoupdate, new version is downloaded after click of "Download" button
|
||||
- ADDED: Ability to configure autoupdate (check only, check+download, don't check)
|
||||
@@ -536,14 +610,17 @@ Builds:
|
||||
- FIXED: Fixes following issues: #886, #865, #782, #375
|
||||
|
||||
### 5.4.2
|
||||
|
||||
- FIXED: DbGate now works correctly with Oracle 10g
|
||||
- FIXED: Fixed update channel for premium edition
|
||||
|
||||
### 5.4.1
|
||||
|
||||
- FIXED: Broken older plugins #881
|
||||
- ADDED: Premium edition - "Start trial" button
|
||||
|
||||
### 5.4.0
|
||||
|
||||
- ADDED: Support for CosmosDB (Premium only)
|
||||
- ADDED: Administration UI (Premium only)
|
||||
- ADDED: New application icon
|
||||
@@ -560,10 +637,12 @@ Builds:
|
||||
- FIXED: Script with escaped backslash causes erro #880
|
||||
|
||||
### 5.3.4
|
||||
|
||||
- FIXED: On blank system does not start (window does not appear) #862
|
||||
- FIXED: Missing Execute, Export bar #861
|
||||
|
||||
### 5.3.3
|
||||
|
||||
- FIXED: The application Window is not visible when openning after changing monitor configuration. #856
|
||||
- FIXED: Multi column filter is broken for Postgresql #855
|
||||
- ADDED: Do not display internal timescaledb objects in postgres databases #839
|
||||
@@ -571,12 +650,14 @@ Builds:
|
||||
- FIXED: Cannot filter by uuid field in psql #538
|
||||
|
||||
### 5.3.1
|
||||
|
||||
- FIXED: Column sorting on query tab not working #819
|
||||
- FIXED: Postgres Connection stays in "Loading database structure" until reloading the page #826
|
||||
- FIXED: Cannot read properties of undefined (reading 'length') on Tables #824
|
||||
- FIXED: Redshift doesn't show tables when connected #816
|
||||
|
||||
### 5.3.0
|
||||
|
||||
- CHANGED: New Oracle driver, much better Oracle support. Works now also in docker distribution
|
||||
- FIXED: Connection to oracle with service name #809
|
||||
- ADDED: Connect to redis using a custom username #807
|
||||
@@ -585,18 +666,20 @@ Builds:
|
||||
- ADDED: Switch connection for opened file #814
|
||||
|
||||
### 5.2.9
|
||||
|
||||
- FIXED: PostgresSQL doesn't show tables when connected #793 #805
|
||||
- FIXED: MongoDB write operations fail #798 #802
|
||||
- FIXED: Elecrron app logging losed most of log messages
|
||||
- FIXED: Connection error with SSH tunnel
|
||||
- FIXED: Connection error with SSH tunnel
|
||||
- ADDED: option to disable autoupgrades (with --disable-auto-upgrade)
|
||||
- ADDED: Send error context to github gist
|
||||
|
||||
### 5.2.8
|
||||
|
||||
- FIXED: file menu save and save as not working
|
||||
- FIXED: query editor on import/export screen overlaps with selector
|
||||
- FIXED: Fixed inconsistencies in max/unmaximize window buttons
|
||||
- FIXED: shortcut for select all
|
||||
- FIXED: shortcut for select all
|
||||
- FIXED: download with auth header
|
||||
- CHANGED: Upgraded database drivers for mysql, postgres, sqlite, mssql, mongo, redis
|
||||
- CHANGED: Upgraded electron version (now using v30)
|
||||
@@ -613,8 +696,8 @@ Builds:
|
||||
- ADDED: Button for discard/reset changes (#759)
|
||||
- FIXED: Don't show error dialog when subprocess fails, as DbGate handles this correctly (#751, #746, #542, #272)
|
||||
|
||||
|
||||
### 5.2.7
|
||||
|
||||
- FIXED: fix body overflow when context menu height great than viewport #592
|
||||
- FIXED: Pass signals in entrypoint.sh #596
|
||||
- FIXED: Remove missing links to jenasoft #625
|
||||
@@ -625,6 +708,7 @@ Builds:
|
||||
- CHANGED: Improved stability of electron client on Windows and Mac (fewer EPIPE errors)
|
||||
|
||||
### 5.2.6
|
||||
|
||||
- FIXED: DbGate creates a lot of .tmp.node files in the temp directory #561
|
||||
- FIXED: Typo in datetimeoffset dataType #556
|
||||
- FIXED: SQL export is using the wrong hour formatting #537
|
||||
@@ -632,6 +716,7 @@ Builds:
|
||||
- FIXED: MongoDB password could contain special characters #560
|
||||
|
||||
### 5.2.5
|
||||
|
||||
- ADDED: Split Windows #394
|
||||
- FIXED: Postgres index asc/desc #514
|
||||
- FIXED: Excel export not working since 5.2.3 #511
|
||||
@@ -640,9 +725,11 @@ Builds:
|
||||
- FIXED: Solved some minor problems with widget collapsing
|
||||
|
||||
### 5.2.4
|
||||
|
||||
- FIXED: npm version crash (#508)
|
||||
|
||||
### 5.2.3
|
||||
|
||||
- ADDED: Search entire table (multi column filter) #491
|
||||
- ADDED: OracleDB - connection to toher than default ports #496
|
||||
- CHANGED: OracleDB - status of support set to experimental
|
||||
@@ -674,8 +761,8 @@ Builds:
|
||||
- FIXED: Fixed some scenarios using tables from different DBs
|
||||
- FIXED: Sessions with long-running queries are not killed
|
||||
|
||||
|
||||
### 5.2.2
|
||||
|
||||
- FIXED: Optimalized load DB structure for PostgreSQL #451
|
||||
- ADDED: Auto-closing query connections after configurable (15 minutes default) no-activity interval #468
|
||||
- ADDED: Set application-name connection parameter (for PostgreSQL and MS SQL) for easier identifying of DbGate connections
|
||||
@@ -686,8 +773,8 @@ Builds:
|
||||
- FIXED: crash on Windows and Mac after system goes in suspend mode #458
|
||||
- ADDED: dbmodel standalone NPM package (https://www.npmjs.com/package/dbmodel) - deploy database via commandline tool
|
||||
|
||||
|
||||
### 5.2.1
|
||||
|
||||
- FIXED: client_id param in OAuth
|
||||
- ADDED: OAuth scope parameter
|
||||
- FIXED: login page - password was not sent, when submitting by pressing ENTER
|
||||
@@ -695,6 +782,7 @@ Builds:
|
||||
- FIXED: Export modal - fixed crash when selecting different database
|
||||
|
||||
### 5.2.0
|
||||
|
||||
- ADDED: Oracle database support #380
|
||||
- ADDED: OAuth authentification #407
|
||||
- ADDED: Active directory (Windows) authentification #261
|
||||
@@ -716,7 +804,7 @@ Builds:
|
||||
- ADDED: Perspective designer supports joins from MongoDB nested documents and arrays
|
||||
- FIXED: Perspective designer joins on MongoDB ObjectId fields
|
||||
- ADDED: Filtering columns in designer (query designer, diagram designer, perspective designer)
|
||||
- FIXED: Clone MongoDB rows without _id attribute #404
|
||||
- FIXED: Clone MongoDB rows without \_id attribute #404
|
||||
- CHANGED: Improved cell view with GPS latitude, longitude fields
|
||||
- ADDED: SQL: ALTER VIEW and SQL:ALTER PROCEDURE scripts
|
||||
- ADDED: Ctrl+F5 refreshes data grid also with database structure #428
|
||||
@@ -725,8 +813,8 @@ Builds:
|
||||
- ADDED: Rename, remove connection folder, memoize opened state after app restart #425
|
||||
- FIXED: Show SQLServer alter store procedure #435
|
||||
|
||||
|
||||
### 5.1.6
|
||||
|
||||
- ADDED: Connection folders support #274
|
||||
- ADDED: Keyboard shortcut to hide result window and show/hide the side toolbar #406
|
||||
- ADDED: Ability to show/hide query results #406
|
||||
@@ -738,6 +826,7 @@ Builds:
|
||||
- CHANGED: More strict timeouts to kill database and server connections (reduces resource consumption)
|
||||
|
||||
### 5.1.5
|
||||
|
||||
- ADDED: Support perspectives for MongoDB - MongoDB query designer
|
||||
- ADDED: Show JSON content directly in the overview #395
|
||||
- CHANGED: OSX Command H shortcut for hiding window #390
|
||||
@@ -748,6 +837,7 @@ Builds:
|
||||
- ADDED: connect via socket - configurable via environment variables #358
|
||||
|
||||
### 5.1.4
|
||||
|
||||
- ADDED: Drop database commands #384
|
||||
- ADDED: Customizable Redis key separator #379
|
||||
- ADDED: ARM support for docker images
|
||||
@@ -756,6 +846,7 @@ Builds:
|
||||
- ADDED: Unsaved marker for SQL files
|
||||
|
||||
### 5.1.3
|
||||
|
||||
- ADDED: Editing multiline cell values #378 #371 #359
|
||||
- ADDED: Truncate table #333
|
||||
- ADDED: Perspectives - show row count
|
||||
@@ -764,6 +855,7 @@ Builds:
|
||||
- FIXED: Correct error line numbers returned from queries
|
||||
|
||||
### 5.1.2
|
||||
|
||||
- FIXED: MongoDb any export function does not work. #373
|
||||
- ADDED: Query Designer short order more flexibility #372
|
||||
- ADDED: Form View move between records #370
|
||||
@@ -777,6 +869,7 @@ Builds:
|
||||
- ADDED: Perspectives - cells without joined data are gray
|
||||
|
||||
### 5.1.1
|
||||
|
||||
- ADDED: Perspective designer
|
||||
- FIXED: NULL,NOT NULL filter datatime columns #356
|
||||
- FIXED: Recognize computed columns on SQL server #354
|
||||
@@ -786,32 +879,35 @@ Builds:
|
||||
- ADDED: Custom editor font size #345
|
||||
- ADDED: Ability to open perspective files
|
||||
|
||||
|
||||
### 5.1.0
|
||||
|
||||
- ADDED: Perspectives (docs: https://dbgate.org/docs/perspectives.html )
|
||||
- CHANGED: Upgraded SQLite engine version (driver better-sqlite3: 7.6.2)
|
||||
- CHANGED: Upgraded ElectronJS version (from version 13 to version 17)
|
||||
- CHANGED: Upgraded all dependencies with current available minor version updates
|
||||
- CHANGED: By default, connect on click #332˝
|
||||
- CHANGED: Improved keyboard navigation, when editing table data #331
|
||||
- ADDED: Option to skip Save changes dialog #329
|
||||
- ADDED: Option to skip Save changes dialog #329
|
||||
- FIXED: Unsigned column doesn't work correctly. #324
|
||||
- FIXED: Connect to MS SQL with domain user now works also under Linux and Mac #305
|
||||
|
||||
### 5.0.9
|
||||
|
||||
- FIXED: Fixed problem with SSE events on web version
|
||||
- ADDED: Added menu command "New query designer"
|
||||
- ADDED: Added menu command "New ER diagram"
|
||||
|
||||
### 5.0.8
|
||||
|
||||
- ADDED: SQL Server - support using domain logins under Linux and Mac #305
|
||||
- ADDED: Permissions for connections #318
|
||||
- ADDED: Ability to change editor front #308
|
||||
- ADDED: Custom expression in query designer #306
|
||||
- ADDED: OR conditions in query designer #321
|
||||
- ADDED: Ability to configure settings view environment variables #304
|
||||
|
||||
|
||||
### 5.0.7
|
||||
|
||||
- FIXED: Fixed some problems with SSH tunnel (upgraded SSH client) #315
|
||||
- FIXED: Fixed MognoDB executing find query #312
|
||||
- ADDED: Interval filters for date/time columns #311
|
||||
@@ -819,8 +915,9 @@ Builds:
|
||||
- ADDED: connecting option Trust server certificate for SQL Server #305
|
||||
- ADDED: Autorefresh, reload table every x second #303
|
||||
- FIXED(app): Changing editor theme and font size in Editor Themes #300
|
||||
|
||||
|
||||
### 5.0.6
|
||||
|
||||
- ADDED: Search in columns
|
||||
- CHANGED: Upgraded mongodb driver
|
||||
- ADDED: Ability to reset view, when data load fails
|
||||
@@ -828,6 +925,7 @@ Builds:
|
||||
- FIXED: Fixed some NPM package problems
|
||||
|
||||
### 5.0.5
|
||||
|
||||
- ADDED: Visualisation geographics objects on map #288
|
||||
- ADDED: Support for native SQL as default value inside yaml files #296
|
||||
- FIXED: Postgres boolean columns don't filter correctly #298
|
||||
@@ -835,10 +933,11 @@ Builds:
|
||||
- FIXED: Handle error when reading deleted archive
|
||||
|
||||
### 5.0.3
|
||||
|
||||
- CHANGED: Optimalization of loading DB structure for PostgreSQL, MySQL #273
|
||||
- CHANGED: Upgraded mysql driver #293
|
||||
- CHANGED: Better UX when defining SSH port #291
|
||||
- ADDED: Database object menu from tab
|
||||
- ADDED: Database object menu from tab
|
||||
- CHANGED: Ability to close file uploader
|
||||
- FIXED: Correct handling of NUL values in update keys
|
||||
- CHANGED: Upgraded MS SQL tedious driver
|
||||
@@ -848,13 +947,17 @@ Builds:
|
||||
- ADDED: Configurable object actions #255
|
||||
- ADDED: Multiple sort criteria #235
|
||||
- ADDED(app): Open JSON file
|
||||
|
||||
### 5.0.2
|
||||
|
||||
- FIXED: Cannot use SSH Tunnel after update #291
|
||||
|
||||
### 5.0.1
|
||||
|
||||
- FIXED(app): Can't Click Sidebar Menu Item #287
|
||||
|
||||
### 5.0.0
|
||||
|
||||
- CHANGED: Connection workflow, connections are opened on tabs instead of modals
|
||||
- ADDED: Posibility to connect to DB without saving connection
|
||||
- ADDED(mac): Support for SQLite on Mac M1
|
||||
@@ -867,6 +970,7 @@ Builds:
|
||||
- FIXED: Removed SSL tab on Redis connection (SSL is not supported for Redis)
|
||||
|
||||
### 4.8.8
|
||||
|
||||
- CHANGED: New app icon
|
||||
- ADDED: SQL dump, SQL import - also from/to saved queries
|
||||
- FIXED(mac): Fixed crash when reopening main window
|
||||
@@ -875,6 +979,7 @@ Builds:
|
||||
- ADDED(app): Browse tabs in reverse order with Ctrl+Shift+Tab #245
|
||||
|
||||
### 4.8.7
|
||||
|
||||
- ADDED: MySQL dump/backup database
|
||||
- ADDED: Import SQL dump from file or from URL
|
||||
- FIXED(mac): Fixed Cmd+C, Cmd+V, Cmd+X - shortcuts for copy/cut/paste #270
|
||||
@@ -883,6 +988,7 @@ Builds:
|
||||
- ADDED: Support for dockerhost network name under docker #271
|
||||
|
||||
### 4.8.4
|
||||
|
||||
- FIXED(mac): Fixed build for macOS arm64 #259
|
||||
- FIXED(mac): Fixed opening SQLite files on macOS #243
|
||||
- FIXED(mac): Fixed opening PEM certificates on macOS #206
|
||||
@@ -894,6 +1000,7 @@ Builds:
|
||||
- ADDED: Added menu command "Tools/Change to recent database"
|
||||
|
||||
### 4.8.3
|
||||
|
||||
- FIXED: filters in query result and NDJSON/archive viewer
|
||||
- ADDED: Added select values from query result and NDJSON/archive viewer
|
||||
- ADDED: tab navigation in datagrid #254
|
||||
@@ -903,19 +1010,24 @@ Builds:
|
||||
- ADDED: Data type + reference link in column manager
|
||||
- FIXED(win,linux,mac): Unable to change theme after installing plugin #244
|
||||
|
||||
### 4.8.2
|
||||
- ADDED: implemented missing redis search key logic
|
||||
### 4.8.2
|
||||
|
||||
### 4.8.1
|
||||
- FIXED: fixed crash after disconnecting from all DBs
|
||||
- ADDED: implemented missing redis search key logic
|
||||
|
||||
### 4.8.1
|
||||
|
||||
- FIXED: fixed crash after disconnecting from all DBs
|
||||
|
||||
### 4.8.0
|
||||
|
||||
- ADDED: Redis support (support stream type), removed experimental status
|
||||
- ADDED: Redis readonly support
|
||||
- ADDED: Explicit NDJSON support, when opening NDJSON/JSON lines file, table data are immediately shown, without neccesarity to import
|
||||
- ADDED(win,linux,mac): Opening developer tools when crashing without reload app
|
||||
|
||||
### 4.7.4
|
||||
- ADDED: Experimental Redis support (full support is planned to version 4.8.0)
|
||||
|
||||
- ADDED: Experimental Redis support (full support is planned to version 4.8.0)
|
||||
- ADDED: Read-only connections
|
||||
- FIXED: MongoDB filters
|
||||
- ADDED: MongoDB column value selection
|
||||
@@ -923,13 +1035,14 @@ Builds:
|
||||
- ADDED: Fuzzy search #246
|
||||
- ADDED(docker, npm): New permissions
|
||||
- FIXED(npm): NPM build no longer allocates additonal ports
|
||||
- CHANGED(npm): renamed NPM package dbgate => dbgate-serve
|
||||
- CHANGED(npm): renamed NPM package dbgate => dbgate-serve
|
||||
- CHANGED(docker): custom JavaScripts and connections defined in scripts are now prohibited by default, use SHELL_CONNECTION and SHELL_SCRIPTING environment variables for allowing this
|
||||
- ADDED(docker, npm): Better documentation of environment variables configuration, https://dbgate.org/docs/env-variables.html
|
||||
- ADDED(docker): support for multiple users with different permissions
|
||||
- ADDED(docker): logout operation
|
||||
|
||||
### 4.7.3
|
||||
|
||||
- CHANGED: Export menu redesign, quick export menu merged with old export menu
|
||||
- REMOVED: Quick export menu
|
||||
- ADDED: Export column mapping
|
||||
@@ -944,6 +1057,7 @@ Builds:
|
||||
- ADDED: NPM dist accepts .env configuration
|
||||
|
||||
### 4.7.2
|
||||
|
||||
- CHANGED: documentation URL - https://dbgate.org/docs/
|
||||
- CHANGED: Close button available for all tab groups - #238
|
||||
- ADDED: Search function for the Keyboard Shortcuts overview - #239
|
||||
@@ -952,7 +1066,8 @@ Builds:
|
||||
- FIXED: bug in cache subsystem
|
||||
|
||||
### 4.7.1
|
||||
- FIXED: Fixed connecting to MS SQL server running in docker container from DbGate running in docker container #236
|
||||
|
||||
- FIXED: Fixed connecting to MS SQL server running in docker container from DbGate running in docker container #236
|
||||
- FIXED: Fixed export MongoDB collections into Excel and CSV #240
|
||||
- ADDED: Added support for docker volumes to persiste connections, when not using configuration via env variables #232
|
||||
- ADDED: DbGate in Docker can run in subdirectory #228
|
||||
@@ -962,7 +1077,9 @@ Builds:
|
||||
- ADDED: Improved fullscreen state, title bar with menu is hidden, menu is in hamburger menu, like in web version
|
||||
- ADDED: Theme choose dialog (added as tab in settings)
|
||||
- FIXED: Fixed crash when clicking on application layers #231
|
||||
|
||||
### 4.7.0
|
||||
|
||||
- CHANGED: Changed main menu style, menu and title bar is in one line (+ability to switch to system menu)
|
||||
- REMOVED: Removed main toolbar, use main menu or tab related bottom tool instead
|
||||
- ADDED: Added tab related context bottom toolbar
|
||||
@@ -981,11 +1098,13 @@ Builds:
|
||||
- ADDED: Better work with JSON lines file, added JSONL editor with preview
|
||||
|
||||
### 4.6.3
|
||||
|
||||
- FIXED: Fixed Windows build
|
||||
- FIXED: Fixed crash, when there is invalid value in browser local storage
|
||||
- FIXED: Fixed plugin description display, where author name or description is not correctly filled
|
||||
|
||||
### 4.6.2
|
||||
|
||||
- FIXED: Fixed issues of XML import plugin
|
||||
- ADDED: Split columns macro (available in data sheet editor)
|
||||
- CHANGED: Accepting non standard plugins names (which doesn't start with dbgate-plugin-)
|
||||
@@ -997,6 +1116,7 @@ Builds:
|
||||
- FIXED: Fixed configuring connection to SQLite with environment variables #215
|
||||
|
||||
### 4.6.1
|
||||
|
||||
- ADDED: Ability to configure SSH tunnel over environment variables #210 (for docker container)
|
||||
- ADDED: XML export and import
|
||||
- ADDED: Archive file - show and edit source text file
|
||||
@@ -1012,20 +1132,23 @@ Builds:
|
||||
- CHANGED: UX improvements of table editor
|
||||
|
||||
### 4.6.0
|
||||
|
||||
- ADDED: ER diagrams #118
|
||||
- Generate diagram from table or for database
|
||||
- Automatic layout
|
||||
- Diagram styles - colors, select columns to display, optional displaying data type or nullability
|
||||
- Export diagram to HTML file
|
||||
- Generate diagram from table or for database
|
||||
- Automatic layout
|
||||
- Diagram styles - colors, select columns to display, optional displaying data type or nullability
|
||||
- Export diagram to HTML file
|
||||
- FIXED: Mac latest build link #204
|
||||
|
||||
### 4.5.1
|
||||
|
||||
- FIXED: MongoId detection
|
||||
- FIXED: #203 disabled spellchecker
|
||||
- FIXED: Prevented display filters in form view twice
|
||||
- FIXED: Query designer fixes
|
||||
|
||||
### 4.5.0
|
||||
|
||||
- ADDED: #220 functions, materialized views and stored procedures in code completion
|
||||
- ADDED: Query result in statusbar
|
||||
- ADDED: Highlight and execute current query
|
||||
@@ -1043,6 +1166,7 @@ Builds:
|
||||
- FIXED: Fixed delete dependency cycle detection (delete didn't work for some tables)
|
||||
|
||||
### 4.4.4
|
||||
|
||||
- FIXED: Database colors
|
||||
- CHANGED: Precise work with MongoDB ObjectId
|
||||
- FIXED: Run macro works on MongoDB collection data editor
|
||||
@@ -1057,6 +1181,7 @@ Builds:
|
||||
- ADDED: Show change log after app upgrade
|
||||
|
||||
### 4.4.3
|
||||
|
||||
- ADDED: Connection and database colors
|
||||
- ADDED: Ability to pin connection or table
|
||||
- ADDED: MongoDb: create, drop collection from menu
|
||||
@@ -1074,6 +1199,7 @@ Builds:
|
||||
- CHANGED: Save widget visibility and size
|
||||
|
||||
### 4.4.2
|
||||
|
||||
- ADDED: Open SQL script from SQL confirm
|
||||
- CHANGED: Better looking statusbar
|
||||
- ADDED: Create table from database popup menu
|
||||
@@ -1083,6 +1209,7 @@ Builds:
|
||||
- ADDED: Support for Command key on Mac (#199)
|
||||
|
||||
### 4.4.1
|
||||
|
||||
- FIXED: #188 Fixed problem with datetime values in PostgreSQL and mysql
|
||||
- ADDED: #194 Close tabs by DB
|
||||
- FIXED: Improved form view width calculations
|
||||
@@ -1096,6 +1223,7 @@ Builds:
|
||||
- ADDED: Row count information moved into status bar, when only one grid on tab is used (typical case)
|
||||
|
||||
### 4.4.0
|
||||
|
||||
- ADDED: Database structure compare, export report to HTML
|
||||
- ADDED: Experimental: Deploy DB structure changes between databases
|
||||
- ADDED: Lookup dialog, available in table view on columns with foreign key
|
||||
@@ -1112,21 +1240,25 @@ Builds:
|
||||
- FIXED: Fixed import into SQLite and PostgreSQL databases, added integration test for this
|
||||
|
||||
### 4.3.4
|
||||
|
||||
- FIXED: Delete row with binary ID in MySQL (#182)
|
||||
- ADDED: Using 'ODBC Driver 17 for SQL Server' or 'SQL Server Native Client 11.0', when connecting to MS SQL using windows auth #183
|
||||
|
||||
### 4.3.3
|
||||
|
||||
- ADDED: Generate SQL from data (#176 - Copy row as INSERT/UPDATE statement)
|
||||
- ADDED: Datagrid keyboard column operations (Ctrl+F - find column, Ctrl+H - hide column) #180
|
||||
- FIXED: Make window remember that it was maximized
|
||||
- FIXED: Fixed lost focus after copy to clipboard and after inserting SQL join
|
||||
|
||||
### 4.3.2
|
||||
|
||||
- FIXED: Sorted database list in PostgreSQL (#178)
|
||||
- FIXED: Loading stricture of PostgreSQL database, when it contains indexes on expressions (#175)
|
||||
- ADDED: Hotkey Shift+Alt+F for formatting SQL code
|
||||
|
||||
### 4.3.1
|
||||
|
||||
- FIXED: #173 Using key phrase for SSH key file connection
|
||||
- ADDED: #172 Abiloity to quick search within database names
|
||||
- ADDED: Database search added to command palette (Ctrl+P)
|
||||
@@ -1134,24 +1266,28 @@ Builds:
|
||||
- ADDED: DELETE cascade option - ability to delete all referenced rows, when deleting rows
|
||||
|
||||
### 4.3.0
|
||||
|
||||
- ADDED: Table structure editor
|
||||
- ADDED: Index support
|
||||
- ADDED: Unique constraint support
|
||||
- ADDED: Context menu for drop/rename table/columns and for drop view/procedure/function
|
||||
- ADDED: Added support for Windows arm64 platform
|
||||
- FIXED: Search by _id in MongoDB
|
||||
- FIXED: Search by \_id in MongoDB
|
||||
|
||||
### 4.2.6
|
||||
|
||||
- FIXED: Fixed MongoDB import
|
||||
- ADDED: Configurable thousands separator #136
|
||||
- ADDED: Using case insensitive text search in postgres
|
||||
|
||||
### 4.2.5
|
||||
|
||||
- FIXED: Fixed crash when using large model on some installations
|
||||
- FIXED: Postgre SQL CREATE function
|
||||
- FIXED: Postgre SQL CREATE function
|
||||
- FIXED: Analysing of MySQL when modifyDate is not known
|
||||
|
||||
### 4.2.4
|
||||
|
||||
- ADDED: Query history
|
||||
- ADDED: One-click exports in desktop app
|
||||
- ADDED: JSON array export
|
||||
@@ -1163,23 +1299,27 @@ Builds:
|
||||
- CHANGED: Introduced package dbgate-query-splitter, instead of sql-query-identifier and @verycrazydog/mysql-parse
|
||||
|
||||
### 4.2.3
|
||||
|
||||
- ADDED: ARM builds for MacOS and Linux
|
||||
- ADDED: Filter by columns in form view
|
||||
|
||||
### 4.2.2
|
||||
|
||||
- CHANGED: Further startup optimalization (approx. 2 times quicker start of electron app)
|
||||
|
||||
### 4.2.1
|
||||
|
||||
- FIXED: Fixed+optimalized app startup (esp. on Windows)
|
||||
|
||||
### 4.2.0
|
||||
|
||||
- ADDED: Support of SQLite database
|
||||
- ADDED: Support of Amazon Redshift database
|
||||
- ADDED: Support of CockcroachDB
|
||||
- CHANGED: DB Model is not auto-refreshed by default, refresh could be invoked from statusbar
|
||||
- FIXED: Fixed race conditions on startup
|
||||
- FIXED: Fixed broken style in data grid under strange circumstances
|
||||
- ADDED: Configure connections with commandline arguments #108
|
||||
- ADDED: Configure connections with commandline arguments #108
|
||||
- CHANGED: Optimalized algorithm of incremental DB model updates
|
||||
- CHANGED: Loading queries from PostgreSQL doesn't need cursors, using streamed query instead
|
||||
- ADDED: Disconnect command
|
||||
@@ -1188,9 +1328,11 @@ Builds:
|
||||
- ADDED: Cosmetic improvements of MariaDB support
|
||||
|
||||
### 4.1.11
|
||||
|
||||
- FIX: Fixed crash of API process when using SSH tunnel connection (race condition)
|
||||
|
||||
### 4.1.11
|
||||
|
||||
- FIX: fixed processing postgre query containing $$
|
||||
- FIX: fixed postgre analysing procedures & functions
|
||||
- FIX: patched svelte crash #105
|
||||
@@ -1203,6 +1345,7 @@ Builds:
|
||||
- CHANGED: Toolbar design - current tab related commands are delimited
|
||||
|
||||
### 4.1.10
|
||||
|
||||
- ADDED: Default database option in connectin settings #96 #92
|
||||
- FIX: Bundle size optimalization for Windows #97
|
||||
- FIX: Popup menu placement on smaller displays #94
|
||||
@@ -1213,22 +1356,32 @@ Builds:
|
||||
- ADDED: Show database server version in status bar
|
||||
- ADDED: Show detailed info about error, when connect to database fails
|
||||
- ADDED: Portable ZIP distribution for Windows #84
|
||||
|
||||
### 4.1.9
|
||||
|
||||
- FIX: Incorrect row count info in query result #83
|
||||
|
||||
### 4.1.1
|
||||
|
||||
- CHANGED: Default plugins are now part of installation
|
||||
|
||||
### 4.1.0
|
||||
|
||||
- ADDED: MongoDB support
|
||||
- ADDED: Configurable keyboard shortcuts
|
||||
- ADDED: JSON row cell data view
|
||||
- FIX: Fixed some problems from migration to Svelte
|
||||
|
||||
### 4.0.3
|
||||
|
||||
- FIX: fixes for FireFox (mainly incorrent handle of bind:clientHeight, replaces with resizeobserver)
|
||||
|
||||
### 4.0.2
|
||||
|
||||
- FIX: fixed docker and NPM build
|
||||
|
||||
### 4.0.0
|
||||
|
||||
- CHANGED: Excahnged React with Svelte. Changed theme colors. Huge speed and memory optimalization
|
||||
- ADDED: SQL Generator (CREATE, INSERT, DROP)
|
||||
- ADDED: Command palette (F1). Introduced commands, extended some context menus
|
||||
@@ -1240,6 +1393,7 @@ Builds:
|
||||
- FIX: Solved reconnecting expired connection
|
||||
|
||||
### 3.9.6
|
||||
|
||||
- ADDED: Connect using SSH Tunnel
|
||||
- ADDED: Connect using SSL
|
||||
- ADDED: Database connection dialog redesigned
|
||||
@@ -1249,4 +1403,5 @@ Builds:
|
||||
- FIX: #62 - import, export executed from SNAP installs didn't work
|
||||
|
||||
### 3.9.5
|
||||
|
||||
- Start point of changelog
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
DbGate is a cross-platform (no)SQL database manager supporting MySQL, PostgreSQL, SQL Server, Oracle, MongoDB, Redis, SQLite, and more. It runs as a web app (Docker/NPM), an Electron desktop app, or in a browser. The monorepo uses Yarn workspaces.
|
||||
|
||||
## Development Commands
|
||||
|
||||
```sh
|
||||
yarn # install all packages (also builds TS libraries and plugins)
|
||||
yarn start # run API (port 3000) + web (port 5001) concurrently
|
||||
```
|
||||
|
||||
For more control, run these 3 commands in separate terminals:
|
||||
```sh
|
||||
yarn start:api # Express API on port 3000
|
||||
yarn start:web # Svelte frontend on port 5001
|
||||
yarn lib # watch-compile TS libraries and plugins
|
||||
```
|
||||
|
||||
For Electron development:
|
||||
```sh
|
||||
yarn start:web # web on port 5001
|
||||
yarn lib # watch TS libs/plugins
|
||||
yarn start:app # Electron app
|
||||
```
|
||||
|
||||
### Building
|
||||
|
||||
```sh
|
||||
yarn build:lib # build all TS libraries (sqltree, tools, filterparser, datalib, rest)
|
||||
yarn build:api # build API
|
||||
yarn build:web # build web frontend
|
||||
yarn ts # TypeScript type-check API and web
|
||||
yarn prettier # format all source files
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
Unit tests (in packages like `dbgate-tools`):
|
||||
```sh
|
||||
yarn workspace dbgate-tools test
|
||||
```
|
||||
|
||||
Integration tests (requires Docker for database containers):
|
||||
```sh
|
||||
cd integration-tests
|
||||
yarn test:local # run all tests
|
||||
yarn test:local:path __tests__/alter-database.spec.js # run a single test file
|
||||
```
|
||||
|
||||
E2E tests (Cypress):
|
||||
```sh
|
||||
yarn cy:open # open Cypress UI
|
||||
cd e2e-tests && yarn cy:run:browse-data # run a specific spec headlessly
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Monorepo Structure
|
||||
|
||||
| Path | Package | Purpose |
|
||||
|---|---|---|
|
||||
| `packages/api` | `dbgate-api` | Express.js backend server |
|
||||
| `packages/web` | `dbgate-web` | Svelte 4 frontend (built with Rolldown) |
|
||||
| `packages/tools` | `dbgate-tools` | Shared TS utilities: SQL dumping, schema analysis, diffing, driver base classes |
|
||||
| `packages/datalib` | `dbgate-datalib` | Grid display logic, changeset management, perspectives, chart definitions |
|
||||
| `packages/sqltree` | `dbgate-sqltree` | SQL AST representation and dumping |
|
||||
| `packages/filterparser` | `dbgate-filterparser` | Parses filter strings into SQL/Mongo conditions |
|
||||
| `packages/rest` | `dbgate-rest` | REST connection support |
|
||||
| `packages/types` | `dbgate-types` | TypeScript type definitions (`.d.ts` only) |
|
||||
| `packages/aigwmock` | `dbgate-aigwmock` | Mock AI gateway server for E2E testing |
|
||||
| `plugins/dbgate-plugin-*` | — | Database drivers and file format handlers |
|
||||
| `app/` | — | Electron shell |
|
||||
| `integration-tests/` | — | Jest-based DB integration tests (Docker) |
|
||||
| `e2e-tests/` | — | Cypress E2E tests |
|
||||
|
||||
### API Backend (`packages/api`)
|
||||
|
||||
- Express.js server with controllers in `src/controllers/` — each file exposes REST endpoints via the `useController` utility
|
||||
- Database connections run in child processes (`src/proc/`) to isolate crashes and long-running operations
|
||||
- `src/shell/` contains stream-based data pipeline primitives (readers, writers, transforms) used for import/export and replication
|
||||
- Plugin drivers are loaded dynamically via `requireEngineDriver`; each plugin in `plugins/` exports a driver conforming to `DriverBase` from `dbgate-tools`
|
||||
|
||||
### Frontend (`packages/web`)
|
||||
|
||||
- Svelte 4 components; builds with Rolldown (not Vite/Webpack)
|
||||
- Global state in `src/stores.ts` using Svelte writable stores, with `writableWithStorage` / `writableWithForage` helpers for persistence
|
||||
- API calls go through `src/utility/api.ts` (`apiCall`, `apiOff`, etc.) which handles auth, error display, and cache invalidation
|
||||
- Tab system: each open editor/viewer is a "tab" tracked in `openedTabs` store; tab components live in `src/tabs/`
|
||||
- Left-panel tree items are "AppObjects" in `src/appobj/`
|
||||
- Metadata (table lists, column info) is loaded reactively via hooks in `src/utility/metadataLoaders.ts`
|
||||
- Commands/keybindings are registered in `src/commands/`
|
||||
|
||||
### Plugin Architecture
|
||||
|
||||
Each `plugins/dbgate-plugin-*` package provides:
|
||||
- **Frontend build** (`build:frontend`): bundled JS loaded by the web UI for query formatting, data rendering
|
||||
- **Backend build** (`build:backend`): Node.js driver code loaded by the API for actual DB connections
|
||||
|
||||
Plugins are copied to `plugins/dist/` via `plugins:copydist` before building the app or Docker image.
|
||||
|
||||
### Key Conventions
|
||||
|
||||
- Error/message codes use `DBGM-00000` as placeholder — do not introduce new numbered `DBGM-NNNNN` codes
|
||||
- Frontend uses **Svelte 4** (not Svelte 5)
|
||||
- E2E test selectors use `data-testid` attribute with format `ComponentName_identifier`
|
||||
- Prettier config: single quotes, 2-space indent, 120-char line width, trailing commas ES5
|
||||
- Logging via `pinomin`; pipe through `pino-pretty` for human-readable output
|
||||
|
||||
### Translation System
|
||||
|
||||
```sh
|
||||
yarn translations:extract # extract new strings
|
||||
yarn translations:add-missing # add missing translations
|
||||
yarn translations:check # check for issues
|
||||
```
|
||||
@@ -4,5 +4,6 @@ module.exports = {
|
||||
mssql: true,
|
||||
oracle: true,
|
||||
sqlite: true,
|
||||
mongo: true
|
||||
mongo: true,
|
||||
dynamo: true,
|
||||
};
|
||||
|
||||
@@ -512,4 +512,43 @@ describe('Data browser data', () => {
|
||||
cy.testid('DataFilterControl_input_ArtistId.Name').type('mich{enter}');
|
||||
cy.themeshot('data-browser-filter-by-expanded');
|
||||
});
|
||||
|
||||
it('DynamoDB', () => {
|
||||
cy.contains('Dynamo-connection').click();
|
||||
cy.contains('us-east-1').click();
|
||||
|
||||
cy.contains('Album').click();
|
||||
cy.contains('Pearl Jam').click();
|
||||
cy.themeshot('dynamodb-table-data');
|
||||
cy.contains('Switch to JSON').click();
|
||||
cy.themeshot('dynamodb-json-view');
|
||||
|
||||
cy.contains('Customer').click();
|
||||
cy.testid('DataFilterControl_input_CustomerId').type('<=10{enter}');
|
||||
cy.contains('Rows: 10');
|
||||
cy.wait(1000);
|
||||
cy.contains('Helena').click().rightclick();
|
||||
cy.contains('Show cell data').click();
|
||||
cy.contains('City: "Prague"');
|
||||
cy.themeshot('dynamodb-query-json-view');
|
||||
|
||||
cy.contains('Switch to JSON').click();
|
||||
cy.contains('Leonie').rightclick();
|
||||
cy.contains('Edit document').click();
|
||||
|
||||
Array.from({ length: 11 }).forEach(() => cy.realPress('ArrowDown'));
|
||||
Array.from({ length: 14 }).forEach(() => cy.realPress('ArrowRight'));
|
||||
Array.from({ length: 7 }).forEach(() => cy.realPress('Delete'));
|
||||
cy.realType('Italy');
|
||||
cy.testid('EditJsonModal_saveButton').click();
|
||||
|
||||
cy.contains('Helena').rightclick();
|
||||
cy.contains('Delete document').click();
|
||||
cy.contains('Save').click();
|
||||
cy.themeshot('dynamodb-save-changes');
|
||||
|
||||
cy.testid('SqlObjectList_addButton').click();
|
||||
cy.contains('New collection/container').click();
|
||||
cy.themeshot('dynamodb-new-collection');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -52,6 +52,9 @@ function multiTest(testProps, testDefinition) {
|
||||
if (localconfig.mongo && !testProps.skipMongo) {
|
||||
it('MongoDB', () => testDefinition('Mongo-connection', 'my_guitar_shop', 'mongo@dbgate-plugin-mongo'));
|
||||
}
|
||||
if (localconfig.dynamo && !testProps.skipMongo) {
|
||||
it('DynamoDB', () => testDefinition('Dynamo-connection', null, 'dynamodb@dbgate-plugin-dynamodb'));
|
||||
}
|
||||
}
|
||||
|
||||
describe('Transactions', () => {
|
||||
|
||||
@@ -5,14 +5,14 @@ services:
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
ports:
|
||||
- 16000:5432
|
||||
|
||||
mariadb:
|
||||
image: mariadb
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
restart: always
|
||||
ports:
|
||||
ports:
|
||||
- 16004:3306
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=Pwd2020Db
|
||||
@@ -20,21 +20,21 @@ services:
|
||||
mysql-ssh-login:
|
||||
build: containers/mysql-ssh-login
|
||||
restart: always
|
||||
ports:
|
||||
ports:
|
||||
- 16017:3306
|
||||
- "16012:22"
|
||||
- '16012:22'
|
||||
|
||||
mysql-ssh-keyfile:
|
||||
build: containers/mysql-ssh-keyfile
|
||||
restart: always
|
||||
ports:
|
||||
ports:
|
||||
- 16007:3306
|
||||
- "16008:22"
|
||||
- '16008:22'
|
||||
|
||||
dex:
|
||||
build: containers/dex
|
||||
ports:
|
||||
- "16009:5556"
|
||||
- '16009:5556'
|
||||
|
||||
mongo:
|
||||
image: mongo:4.4.29
|
||||
@@ -50,6 +50,11 @@ services:
|
||||
ports:
|
||||
- 16011:6379
|
||||
|
||||
dynamodb:
|
||||
image: amazon/dynamodb-local
|
||||
ports:
|
||||
- 16015:8000
|
||||
|
||||
mssql:
|
||||
image: mcr.microsoft.com/mssql/server
|
||||
restart: always
|
||||
|
||||
Vendored
+7
-1
@@ -1,4 +1,4 @@
|
||||
CONNECTIONS=mysql,postgres,mongo
|
||||
CONNECTIONS=mysql,postgres,mongo,dynamo
|
||||
|
||||
LABEL_mysql=MySql-connection
|
||||
SERVER_mysql=localhost
|
||||
@@ -22,3 +22,9 @@ USER_mongo=root
|
||||
PASSWORD_mongo=Pwd2020Db
|
||||
PORT_mongo=16010
|
||||
ENGINE_mongo=mongo@dbgate-plugin-mongo
|
||||
|
||||
LABEL_dynamo=Dynamo-connection
|
||||
SERVER_dynamo=localhost
|
||||
PORT_dynamo=16015
|
||||
AUTH_TYPE_dynamo=onpremise
|
||||
ENGINE_dynamo=dynamodb@dbgate-plugin-dynamodb
|
||||
|
||||
Vendored
+8
-1
@@ -1,4 +1,4 @@
|
||||
CONNECTIONS=mysql,postgres,mssql,oracle,sqlite,mongo
|
||||
CONNECTIONS=mysql,postgres,mssql,oracle,sqlite,mongo,dynamo
|
||||
LOG_CONNECTION_SENSITIVE_VALUES=true
|
||||
|
||||
LABEL_mysql=MySql-connection
|
||||
@@ -43,3 +43,10 @@ PASSWORD_mongo=Pwd2020Db
|
||||
PORT_mongo=16010
|
||||
ENGINE_mongo=mongo@dbgate-plugin-mongo
|
||||
|
||||
LABEL_dynamo=Dynamo-connection
|
||||
SERVER_dynamo=localhost
|
||||
PORT_dynamo=16015
|
||||
AUTH_TYPE_dynamo=onpremise
|
||||
DATABASE_dynamo=localhost
|
||||
ENGINE_dynamo=dynamodb@dbgate-plugin-dynamodb
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ function ensureDependencies(dir, checkFile) {
|
||||
env: process.env,
|
||||
});
|
||||
if (result.status !== 0) {
|
||||
throw new Error(`DBGM-00000 Failed to install dependencies in ${dir}`);
|
||||
throw new Error(`DBGM-00297 Failed to install dependencies in ${dir}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ async function waitForReady(url, timeoutMs = 30000) {
|
||||
}
|
||||
await delay(500);
|
||||
}
|
||||
throw new Error(`DBGM-00000 Server at ${url} did not start in time`);
|
||||
throw new Error(`DBGM-00305 Server at ${url} did not start in time`);
|
||||
}
|
||||
|
||||
// --- Main ---
|
||||
|
||||
@@ -8,6 +8,8 @@ const dbgatePluginMysql = require('dbgate-plugin-mysql');
|
||||
dbgateApi.registerPlugins(dbgatePluginMysql);
|
||||
const dbgatePluginPostgres = require('dbgate-plugin-postgres');
|
||||
dbgateApi.registerPlugins(dbgatePluginPostgres);
|
||||
const dbgatePluginDynamodb = require('dbgate-plugin-dynamodb');
|
||||
dbgateApi.registerPlugins(dbgatePluginDynamodb);
|
||||
|
||||
async function initMySqlDatabase(dbname, inputFile) {
|
||||
await dbgateApi.executeQuery({
|
||||
@@ -125,6 +127,34 @@ async function initMongoDatabase(dbname, inputDirectory) {
|
||||
// });
|
||||
}
|
||||
|
||||
async function initDynamoDatabase(inputDirectory) {
|
||||
const dynamodbConnection = {
|
||||
server: process.env.SERVER_dynamo,
|
||||
port: process.env.PORT_dynamo,
|
||||
authType: 'onpremise',
|
||||
engine: 'dynamodb@dbgate-plugin-dynamodb',
|
||||
};
|
||||
|
||||
const driver = dbgatePluginDynamodb.drivers.find(d => d.engine === 'dynamodb@dbgate-plugin-dynamodb');
|
||||
const pool = await driver.connect(dynamodbConnection);
|
||||
const collections = await driver.listCollections(pool);
|
||||
for (const collection of collections) {
|
||||
await driver.dropTable(pool, collection);
|
||||
}
|
||||
await driver.disconnect(pool);
|
||||
|
||||
for (const file of fs.readdirSync(inputDirectory)) {
|
||||
const pureName = path.parse(file).name;
|
||||
const src = await dbgateApi.jsonLinesReader({ fileName: path.join(inputDirectory, file) });
|
||||
const dst = await dbgateApi.tableWriter({
|
||||
connection: dynamodbConnection,
|
||||
pureName,
|
||||
createIfNotExists: true,
|
||||
});
|
||||
await dbgateApi.copyStream(src, dst);
|
||||
}
|
||||
}
|
||||
|
||||
const baseDir = path.join(os.homedir(), '.dbgate');
|
||||
|
||||
async function copyFolder(source, target) {
|
||||
@@ -148,6 +178,8 @@ async function run() {
|
||||
await initMongoDatabase('MgChinook', path.resolve(path.join(__dirname, '../data/chinook-jsonl')));
|
||||
await initMongoDatabase('MgRivers', path.resolve(path.join(__dirname, '../data/rivers-jsonl')));
|
||||
|
||||
await initDynamoDatabase(path.resolve(path.join(__dirname, '../data/chinook-jsonl')));
|
||||
|
||||
await copyFolder(
|
||||
path.resolve(path.join(__dirname, '../data/chinook-jsonl')),
|
||||
path.join(baseDir, 'archive-e2etests', 'default')
|
||||
|
||||
@@ -7,6 +7,8 @@ const dbgatePluginMysql = require('dbgate-plugin-mysql');
|
||||
dbgateApi.registerPlugins(dbgatePluginMysql);
|
||||
const dbgatePluginPostgres = require('dbgate-plugin-postgres');
|
||||
dbgateApi.registerPlugins(dbgatePluginPostgres);
|
||||
const dbgatePluginDynamodb = require('dbgate-plugin-dynamodb');
|
||||
dbgateApi.registerPlugins(dbgatePluginDynamodb);
|
||||
|
||||
async function createDb(connection, dropDbSql, createDbSql, database = 'my_guitar_shop', { dropDatabaseName } = {}) {
|
||||
if (dropDbSql) {
|
||||
@@ -125,6 +127,28 @@ async function run() {
|
||||
{ dropDatabaseName: 'my_guitar_shop' }
|
||||
);
|
||||
}
|
||||
|
||||
if (localconfig.dynamo) {
|
||||
const dynamodbConnection = {
|
||||
server: process.env.SERVER_dynamo,
|
||||
port: process.env.PORT_dynamo,
|
||||
authType: 'onpremise',
|
||||
engine: 'dynamodb@dbgate-plugin-dynamodb',
|
||||
};
|
||||
|
||||
const driver = dbgatePluginDynamodb.drivers.find(d => d.engine === 'dynamodb@dbgate-plugin-dynamodb');
|
||||
const pool = await driver.connect(dynamodbConnection);
|
||||
const collections = await driver.listCollections(pool);
|
||||
for (const collection of collections) {
|
||||
await driver.dropTable(pool, collection);
|
||||
}
|
||||
await driver.disconnect(pool);
|
||||
|
||||
await dbgateApi.importDbFromFolder({
|
||||
connection: dynamodbConnection,
|
||||
folder: path.resolve(path.join(__dirname, '../data/my-guitar-shop')),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
dbgateApi.runScript(run);
|
||||
|
||||
@@ -27,7 +27,7 @@ async function waitForApiReady(timeoutMs = 30000) {
|
||||
await delay(500);
|
||||
}
|
||||
|
||||
throw new Error('DBGM-00000 test-api did not start on port 4444 in time');
|
||||
throw new Error('DBGM-00306 test-api did not start on port 4444 in time');
|
||||
}
|
||||
|
||||
function readProcessStartTime(pid) {
|
||||
@@ -116,7 +116,7 @@ function ensureTestApiDependencies() {
|
||||
});
|
||||
|
||||
if (result.status !== 0) {
|
||||
throw new Error('DBGM-00000 Failed to install test-api dependencies');
|
||||
throw new Error('DBGM-00307 Failed to install test-api dependencies');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "7.1.2",
|
||||
"version": "7.1.6",
|
||||
"name": "dbgate-all",
|
||||
"workspaces": [
|
||||
"packages/*",
|
||||
|
||||
@@ -95,10 +95,12 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
handle_response(conid, database, { msgid, ...response }) {
|
||||
const [resolve, reject, additionalData] = this.requests[msgid];
|
||||
resolve(response);
|
||||
if (additionalData?.auditLogger) {
|
||||
additionalData?.auditLogger(response);
|
||||
const [resolve, reject, additionalData] = this.requests[msgid] || [];
|
||||
if (resolve) {
|
||||
resolve(response);
|
||||
if (additionalData?.auditLogger) {
|
||||
additionalData?.auditLogger(response);
|
||||
}
|
||||
}
|
||||
delete this.requests[msgid];
|
||||
},
|
||||
@@ -239,7 +241,7 @@ module.exports = {
|
||||
sendRequest(conn, message, additionalData = {}) {
|
||||
const msgid = crypto.randomUUID();
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
this.requests[msgid] = [resolve, reject, additionalData];
|
||||
this.requests[msgid] = [resolve, reject, additionalData, conn.conid, conn.database];
|
||||
try {
|
||||
const serializedMessage = serializeJsTypesForJsonStringify({ msgid, ...message });
|
||||
conn.subprocess.send(serializedMessage);
|
||||
@@ -264,12 +266,12 @@ module.exports = {
|
||||
},
|
||||
|
||||
sqlSelect_meta: true,
|
||||
async sqlSelect({ conid, database, select, auditLogSessionGroup }, req) {
|
||||
async sqlSelect({ conid, database, select, commandTimeout, auditLogSessionGroup }, req) {
|
||||
await testConnectionPermission(conid, req);
|
||||
const opened = await this.ensureOpened(conid, database);
|
||||
const res = await this.sendRequest(
|
||||
opened,
|
||||
{ msgtype: 'sqlSelect', select },
|
||||
{ msgtype: 'sqlSelect', select, commandTimeout },
|
||||
{
|
||||
auditLogger:
|
||||
auditLogSessionGroup && select?.from?.name?.pureName
|
||||
@@ -344,9 +346,12 @@ module.exports = {
|
||||
},
|
||||
|
||||
collectionData_meta: true,
|
||||
async collectionData({ conid, database, options, auditLogSessionGroup }, req) {
|
||||
async collectionData({ conid, database, options, commandTimeout, auditLogSessionGroup }, req) {
|
||||
await testConnectionPermission(conid, req);
|
||||
const opened = await this.ensureOpened(conid, database);
|
||||
if (commandTimeout && options) {
|
||||
options.commandTimeout = commandTimeout;
|
||||
}
|
||||
const res = await this.sendRequest(
|
||||
opened,
|
||||
{ msgtype: 'collectionData', options },
|
||||
@@ -580,6 +585,24 @@ module.exports = {
|
||||
};
|
||||
},
|
||||
|
||||
pingDatabases_meta: true,
|
||||
async pingDatabases({ databases }, req) {
|
||||
if (!databases || !Array.isArray(databases)) return { status: 'ok' };
|
||||
for (const { conid, database } of databases) {
|
||||
if (!conid || !database) continue;
|
||||
const existing = this.opened.find(x => x.conid == conid && x.database == database);
|
||||
if (existing) {
|
||||
try {
|
||||
existing.subprocess.send({ msgtype: 'ping' });
|
||||
} catch (err) {
|
||||
logger.error(extractErrorLogData(err), 'DBGM-00308 Error pinging DB connection');
|
||||
this.close(conid, database);
|
||||
}
|
||||
}
|
||||
}
|
||||
return { status: 'ok' };
|
||||
},
|
||||
|
||||
refresh_meta: true,
|
||||
async refresh({ conid, database, keepOpen }, req) {
|
||||
await testConnectionPermission(conid, req);
|
||||
@@ -622,6 +645,15 @@ module.exports = {
|
||||
structure: existing.structure,
|
||||
};
|
||||
socket.emitChanged(`database-status-changed`, { conid, database });
|
||||
|
||||
// Reject all pending requests for this connection
|
||||
for (const [msgid, entry] of Object.entries(this.requests)) {
|
||||
const [resolve, reject, additionalData, reqConid, reqDatabase] = entry;
|
||||
if (reqConid === conid && reqDatabase === database) {
|
||||
reject('DBGM-00309 Database connection closed');
|
||||
delete this.requests[msgid];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ const getDiagramExport = require('../utility/getDiagramExport');
|
||||
const apps = require('./apps');
|
||||
const getMapExport = require('../utility/getMapExport');
|
||||
const dbgateApi = require('../shell');
|
||||
const { getLogger } = require('dbgate-tools');
|
||||
const { getLogger, getSqlFrontMatter } = require('dbgate-tools');
|
||||
const yaml = require('js-yaml');
|
||||
const platformInfo = require('../utility/platformInfo');
|
||||
const { checkSecureFilePathsWithoutDirectory, checkSecureDirectories } = require('../utility/security');
|
||||
const { copyAppLogsIntoFile, getRecentAppLogRecords } = require('../utility/appLogStore');
|
||||
@@ -35,13 +36,46 @@ function deserialize(format, text) {
|
||||
|
||||
module.exports = {
|
||||
list_meta: true,
|
||||
async list({ folder }, req) {
|
||||
async list({ folder, parseFrontMatter }, req) {
|
||||
const loadedPermissions = await loadPermissionsFromRequest(req);
|
||||
if (!hasPermission(`files/${folder}/read`, loadedPermissions)) return [];
|
||||
const dir = path.join(filesdir(), folder);
|
||||
if (!(await fs.exists(dir))) return [];
|
||||
const files = (await fs.readdir(dir)).map(file => ({ folder, file }));
|
||||
return files;
|
||||
const fileNames = await fs.readdir(dir);
|
||||
if (!parseFrontMatter) {
|
||||
return fileNames.map(file => ({ folder, file }));
|
||||
}
|
||||
const result = [];
|
||||
for (const file of fileNames) {
|
||||
const item = { folder, file };
|
||||
let fh;
|
||||
try {
|
||||
fh = await require('fs').promises.open(path.join(dir, file), 'r');
|
||||
const buf = new Uint8Array(512);
|
||||
const { bytesRead } = await fh.read(buf, 0, 512, 0);
|
||||
let text = Buffer.from(buf.buffer, 0, bytesRead).toString('utf-8');
|
||||
|
||||
if (text.includes('-- >>>') && !text.includes('-- <<<')) {
|
||||
const stat = await fh.stat();
|
||||
const fullSize = Math.min(stat.size, 4096);
|
||||
if (fullSize > 512) {
|
||||
const fullBuf = new Uint8Array(fullSize);
|
||||
const { bytesRead: fullBytesRead } = await fh.read(fullBuf, 0, fullSize, 0);
|
||||
text = Buffer.from(fullBuf.buffer, 0, fullBytesRead).toString('utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
const fm = getSqlFrontMatter(text, yaml);
|
||||
if (fm?.connectionId) item.connectionId = fm.connectionId;
|
||||
if (fm?.databaseName) item.databaseName = fm.databaseName;
|
||||
} catch (e) {
|
||||
// ignore read errors for individual files
|
||||
} finally {
|
||||
if (fh) await fh.close().catch(() => {});
|
||||
}
|
||||
result.push(item);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
listAll_meta: true,
|
||||
@@ -257,6 +291,13 @@ module.exports = {
|
||||
return true;
|
||||
},
|
||||
|
||||
exportDiagramPng_meta: true,
|
||||
async exportDiagramPng({ filePath, pngBase64 }) {
|
||||
const base64 = pngBase64.replace(/^data:image\/png;base64,/, '');
|
||||
await fs.writeFile(filePath, Buffer.from(base64, 'base64'));
|
||||
return true;
|
||||
},
|
||||
|
||||
getFileRealPath_meta: true,
|
||||
async getFileRealPath({ folder, file }, req) {
|
||||
const loadedPermissions = await loadPermissionsFromRequest(req);
|
||||
|
||||
@@ -228,6 +228,19 @@ module.exports = {
|
||||
return { state: 'ok' };
|
||||
},
|
||||
|
||||
setIsolationLevel_meta: true,
|
||||
async setIsolationLevel({ sesid, level }) {
|
||||
const session = this.opened.find(x => x.sesid == sesid);
|
||||
if (!session) {
|
||||
throw new Error('Invalid session');
|
||||
}
|
||||
|
||||
logger.info({ sesid, level }, 'DBGM-00315 Setting transaction isolation level');
|
||||
session.subprocess.send({ msgtype: 'setIsolationLevel', level });
|
||||
|
||||
return { state: 'ok' };
|
||||
},
|
||||
|
||||
executeReader_meta: true,
|
||||
async executeReader({ conid, database, sql, queryName, appFolder }) {
|
||||
const { sesid } = await this.create({ conid, database });
|
||||
|
||||
@@ -234,12 +234,12 @@ async function handleRunOperation({ msgid, operation, useTransaction }, skipRead
|
||||
}
|
||||
}
|
||||
|
||||
async function handleQueryData({ msgid, sql, range }, skipReadonlyCheck = false) {
|
||||
async function handleQueryData({ msgid, sql, range, commandTimeout }, skipReadonlyCheck = false) {
|
||||
await waitConnected();
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
try {
|
||||
if (!skipReadonlyCheck) ensureExecuteCustomScript(driver);
|
||||
const res = await driver.query(dbhan, sql, { range });
|
||||
const res = await driver.query(dbhan, sql, { range, commandTimeout });
|
||||
process.send({ msgtype: 'response', msgid, ...serializeJsTypesForJsonStringify(res) });
|
||||
} catch (err) {
|
||||
process.send({
|
||||
@@ -250,11 +250,11 @@ async function handleQueryData({ msgid, sql, range }, skipReadonlyCheck = false)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSqlSelect({ msgid, select }) {
|
||||
async function handleSqlSelect({ msgid, select, commandTimeout }) {
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
const dmp = driver.createDumper();
|
||||
dumpSqlSelect(dmp, select);
|
||||
return handleQueryData({ msgid, sql: dmp.s, range: select.range }, true);
|
||||
return handleQueryData({ msgid, sql: dmp.s, range: select.range, commandTimeout }, true);
|
||||
}
|
||||
|
||||
async function handleDriverDataCore(msgid, callMethod, { logName }) {
|
||||
|
||||
@@ -77,6 +77,38 @@ async function handleStopProfiler({ jslid }) {
|
||||
currentProfiler = null;
|
||||
}
|
||||
|
||||
async function handleSetIsolationLevel({ level }) {
|
||||
lastActivity = new Date().getTime();
|
||||
|
||||
await waitConnected();
|
||||
const driver = requireEngineDriver(storedConnection);
|
||||
|
||||
if (!driver.setTransactionIsolationLevel) {
|
||||
process.send({ msgtype: 'done', skipFinishedMessage: true });
|
||||
return;
|
||||
}
|
||||
|
||||
if (driver.isolationLevels && level && !driver.isolationLevels.includes(level)) {
|
||||
process.send({
|
||||
msgtype: 'info',
|
||||
info: {
|
||||
message: `Isolation level "${level}" is not supported by this driver. Supported levels: ${driver.isolationLevels.join(', ')}`,
|
||||
severity: 'error',
|
||||
},
|
||||
});
|
||||
process.send({ msgtype: 'done', skipFinishedMessage: true });
|
||||
return;
|
||||
}
|
||||
|
||||
executingScripts++;
|
||||
try {
|
||||
await driver.setTransactionIsolationLevel(dbhan, level);
|
||||
process.send({ msgtype: 'done', controlCommand: 'setIsolationLevel' });
|
||||
} finally {
|
||||
executingScripts--;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleExecuteControlCommand({ command }) {
|
||||
lastActivity = new Date().getTime();
|
||||
|
||||
@@ -210,6 +242,7 @@ const messageHandlers = {
|
||||
connect: handleConnect,
|
||||
executeQuery: handleExecuteQuery,
|
||||
executeControlCommand: handleExecuteControlCommand,
|
||||
setIsolationLevel: handleSetIsolationLevel,
|
||||
executeReader: handleExecuteReader,
|
||||
startProfiler: handleStartProfiler,
|
||||
stopProfiler: handleStopProfiler,
|
||||
|
||||
@@ -698,6 +698,30 @@ module.exports = {
|
||||
"columnName": "id_original",
|
||||
"dataType": "varchar(250)",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"pureName": "connections",
|
||||
"columnName": "httpProxyUrl",
|
||||
"dataType": "varchar(250)",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"pureName": "connections",
|
||||
"columnName": "httpProxyUser",
|
||||
"dataType": "varchar(250)",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"pureName": "connections",
|
||||
"columnName": "httpProxyPassword",
|
||||
"dataType": "varchar(250)",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"pureName": "connections",
|
||||
"columnName": "defaultIsolationLevel",
|
||||
"dataType": "varchar(250)",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"foreignKeys": [
|
||||
|
||||
@@ -132,7 +132,35 @@ async function connectUtility(driver, storedConnection, connectionMode, addition
|
||||
}
|
||||
|
||||
connection.ssl = await extractConnectionSslParams(connection);
|
||||
connection.axios = axios.default;
|
||||
|
||||
const proxyUrl = String(connection.httpProxyUrl ?? '').trim();
|
||||
const proxyUser = String(connection.httpProxyUser ?? '').trim();
|
||||
const proxyPassword = String(connection.httpProxyPassword ?? '').trim();
|
||||
if (!proxyUrl && (proxyUser || proxyPassword)) {
|
||||
throw new Error('DBGM-00329 Proxy user or password is set but proxy URL is missing');
|
||||
}
|
||||
if (proxyUrl) {
|
||||
let parsedProxy;
|
||||
try {
|
||||
const parsed = new URL(proxyUrl.includes('://') ? proxyUrl : `http://${proxyUrl}`);
|
||||
parsedProxy = {
|
||||
protocol: parsed.protocol.replace(':', ''),
|
||||
host: parsed.hostname,
|
||||
port: parsed.port ? parseInt(parsed.port, 10) : (parsed.protocol === 'https:' ? 443 : 80),
|
||||
};
|
||||
const username = connection.httpProxyUser ?? parsed.username;
|
||||
const rawPassword = connection.httpProxyPassword ?? parsed.password;
|
||||
const password = decryptPasswordString(rawPassword);
|
||||
if (username) {
|
||||
parsedProxy.auth = { username, password: password ?? '' };
|
||||
}
|
||||
} catch (err) {
|
||||
throw new Error(`DBGM-00334 Invalid proxy URL "${proxyUrl}": ${err && err.message ? err.message : err}`);
|
||||
}
|
||||
connection.axios = axios.default.create({ proxy: parsedProxy });
|
||||
} else {
|
||||
connection.axios = axios.default;
|
||||
}
|
||||
|
||||
const conn = await driver.connect({ conid: connectionLoaded?._id, ...connection, ...additionalOptions });
|
||||
return conn;
|
||||
|
||||
@@ -101,7 +101,7 @@ function decryptObjectPasswordField(obj, field, encryptor = null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
const fieldsToEncrypt = ['password', 'sshPassword', 'sshKeyfilePassword', 'connectionDefinition'];
|
||||
const fieldsToEncrypt = ['password', 'sshPassword', 'sshKeyfilePassword', 'connectionDefinition', 'httpProxyPassword'];
|
||||
const additionalFieldsToMask = [
|
||||
'databaseUrl',
|
||||
'server',
|
||||
|
||||
@@ -30,7 +30,7 @@ export const graphQlDriver: EngineDriver = {
|
||||
icon: '<svg version="1.1" id="GraphQL_Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 400 400" enable-background="new 0 0 400 400" xml:space="preserve"><g><g><g><rect x="122" y="-0.4" transform="matrix(-0.866 -0.5 0.5 -0.866 163.3196 363.3136)" fill="#E535AB" width="16.6" height="320.3"/></g></g><g><g><rect x="39.8" y="272.2" fill="#E535AB" width="320.3" height="16.6"/></g></g><g><g><rect x="37.9" y="312.2" transform="matrix(-0.866 -0.5 0.5 -0.866 83.0693 663.3409)" fill="#E535AB" width="185" height="16.6"/></g></g><g><g><rect x="177.1" y="71.1" transform="matrix(-0.866 -0.5 0.5 -0.866 463.3409 283.0693)" fill="#E535AB" width="185" height="16.6"/></g></g><g><g><rect x="122.1" y="-13" transform="matrix(-0.5 -0.866 0.866 -0.5 126.7903 232.1221)" fill="#E535AB" width="16.6" height="185"/></g></g><g><g><rect x="109.6" y="151.6" transform="matrix(-0.5 -0.866 0.866 -0.5 266.0828 473.3766)" fill="#E535AB" width="320.3" height="16.6"/></g></g><g><g><rect x="52.5" y="107.5" fill="#E535AB" width="16.6" height="185"/></g></g><g><g><rect x="330.9" y="107.5" fill="#E535AB" width="16.6" height="185"/></g></g><g><g><rect x="262.4" y="240.1" transform="matrix(-0.5 -0.866 0.866 -0.5 126.7953 714.2875)" fill="#E535AB" width="14.5" height="160.9"/></g></g><path fill="#E535AB" d="M369.5,297.9c-9.6,16.7-31,22.4-47.7,12.8c-16.7-9.6-22.4-31-12.8-47.7c9.6-16.7,31-22.4,47.7-12.8 C373.5,259.9,379.2,281.2,369.5,297.9"/><path fill="#E535AB" d="M90.9,137c-9.6,16.7-31,22.4-47.7,12.8c-16.7-9.6-22.4-31-12.8-47.7c9.6-16.7,31-22.4,47.7-12.8 C94.8,99,100.5,120.3,90.9,137"/><path fill="#E535AB" d="M30.5,297.9c-9.6-16.7-3.9-38,12.8-47.7c16.7-9.6,38-3.9,47.7,12.8c9.6,16.7,3.9,38-12.8,47.7 C61.4,320.3,40.1,314.6,30.5,297.9"/><path fill="#E535AB" d="M309.1,137c-9.6-16.7-3.9-38,12.8-47.7c16.7-9.6,38-3.9,47.7,12.8c9.6-16.7,3.9-38-12.8,47.7 C340.1,159.4,318.7,153.7,309.1,137"/><path fill="#E535AB" d="M200,395.8c-19.3,0-34.9-15.6-34.9-34.9c0-19.3,15.6-34.9,34.9-34.9c19.3,0,34.9,15.6,34.9,34.9 C234.9,380.1,219.3,395.8,200,395.8"/><path fill="#E535AB" d="M200,74c-19.3,0-34.9-15.6-34.9-34.9c0-19.3,15.6-34.9,34.9-34.9c19.3,0,34.9,15.6,34.9,34.9 C234.9,58.4,219.3,74,200,74"/></g></svg>',
|
||||
|
||||
showConnectionField: (field, values) => {
|
||||
if (apiDriverBase.showAuthConnectionField(field, values)) return true;
|
||||
if (apiDriverBase.showConnectionField(field, values)) return true;
|
||||
if (field === 'apiServerUrl1') return true;
|
||||
return false;
|
||||
},
|
||||
|
||||
@@ -24,7 +24,7 @@ function resolveServiceRoot(contextUrl: string | undefined, fallbackUrl: string)
|
||||
|
||||
async function loadODataServiceDocument(dbhan: any) {
|
||||
if (!dbhan?.connection?.apiServerUrl1) {
|
||||
throw new Error('DBGM-00000 OData endpoint URL is not configured');
|
||||
throw new Error('DBGM-00330 OData endpoint URL is not configured');
|
||||
}
|
||||
|
||||
const response = await dbhan.axios.get(dbhan.connection.apiServerUrl1, {
|
||||
@@ -33,11 +33,11 @@ async function loadODataServiceDocument(dbhan: any) {
|
||||
|
||||
const document = response?.data;
|
||||
if (!document || typeof document !== 'object') {
|
||||
throw new Error('DBGM-00000 OData service document is empty or invalid');
|
||||
throw new Error('DBGM-00331 OData service document is empty or invalid');
|
||||
}
|
||||
|
||||
if (!document['@odata.context']) {
|
||||
throw new Error('DBGM-00000 OData service document does not contain @odata.context');
|
||||
throw new Error('DBGM-00332 OData service document does not contain @odata.context');
|
||||
}
|
||||
|
||||
return document;
|
||||
@@ -60,7 +60,7 @@ export const oDataDriver: EngineDriver = {
|
||||
apiServerUrl1Label: 'OData Service URL',
|
||||
|
||||
showConnectionField: (field, values) => {
|
||||
if (apiDriverBase.showAuthConnectionField(field, values)) return true;
|
||||
if (apiDriverBase.showConnectionField(field, values)) return true;
|
||||
if (field === 'apiServerUrl1') return true;
|
||||
return false;
|
||||
},
|
||||
|
||||
@@ -39,7 +39,7 @@ export const openApiDriver: EngineDriver = {
|
||||
loadApiServerUrl2Options: true,
|
||||
|
||||
showConnectionField: (field, values) => {
|
||||
if (apiDriverBase.showAuthConnectionField(field, values)) return true;
|
||||
if (apiDriverBase.showConnectionField(field, values)) return true;
|
||||
if (field === 'apiServerUrl1') return true;
|
||||
if (field === 'apiServerUrl2') return true;
|
||||
return false;
|
||||
|
||||
@@ -39,4 +39,12 @@ export const apiDriverBase = {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
showConnectionField: (field, values) => {
|
||||
if (apiDriverBase.showAuthConnectionField(field, values)) return true;
|
||||
if (field === 'httpProxyUrl') return true;
|
||||
if (field === 'httpProxyUser') return true;
|
||||
if (field === 'httpProxyPassword') return true;
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -12,6 +12,13 @@ import isPlainObject from 'lodash/isPlainObject';
|
||||
import md5 from 'blueimp-md5';
|
||||
|
||||
export const MAX_GRID_TEXT_LENGTH = 1000; // maximum length of text in grid cell, longer text is truncated
|
||||
export const MAX_GRID_BINARY_SIZE = 10000; // maximum binary size (base64 chars or byte count) before showing 'too large' in grid cell
|
||||
|
||||
function formatByteSize(bytes: number): string {
|
||||
if (bytes >= 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
||||
if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
||||
return `${bytes} B`;
|
||||
}
|
||||
|
||||
export type EditorDataType =
|
||||
| 'null'
|
||||
@@ -49,6 +56,26 @@ export function base64ToHex(base64String) {
|
||||
return '0x' + hexString.toUpperCase();
|
||||
}
|
||||
|
||||
export function base64ToUuid(base64String): string | null {
|
||||
let binaryString: string;
|
||||
try {
|
||||
binaryString = atob(base64String);
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
if (binaryString.length !== 16) {
|
||||
return null;
|
||||
}
|
||||
const hex = Array.from(binaryString, c => c.charCodeAt(0).toString(16).padStart(2, '0')).join('');
|
||||
return [
|
||||
hex.slice(0, 8),
|
||||
hex.slice(8, 12),
|
||||
hex.slice(12, 16),
|
||||
hex.slice(16, 20),
|
||||
hex.slice(20, 32),
|
||||
].join('-');
|
||||
}
|
||||
|
||||
export function hexToBase64(hexString) {
|
||||
const binaryString = hexString
|
||||
.match(/.{1,2}/g)
|
||||
@@ -57,6 +84,23 @@ export function hexToBase64(hexString) {
|
||||
return btoa(binaryString);
|
||||
}
|
||||
|
||||
const uuidPattern = '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
|
||||
const uuidRegex = new RegExp(`^${uuidPattern}$`);
|
||||
const uuid3WrapperRegex = new RegExp(`^UUID3\\("(${uuidPattern})"\\)$`);
|
||||
const uuid4WrapperRegex = new RegExp(`^UUID\\("(${uuidPattern})"\\)$`);
|
||||
|
||||
export function uuidToBase64(uuid: string): string | null {
|
||||
if (!uuid || !uuidRegex.test(uuid)) {
|
||||
return null;
|
||||
}
|
||||
const hex = uuid.replace(/-/g, '');
|
||||
const binaryString = hex
|
||||
.match(/.{1,2}/g)
|
||||
.map(byte => String.fromCharCode(parseInt(byte, 16)))
|
||||
.join('');
|
||||
return btoa(binaryString);
|
||||
}
|
||||
|
||||
export function parseCellValue(value, editorTypes?: DataEditorTypesBehaviour) {
|
||||
if (!_isString(value)) return value;
|
||||
|
||||
@@ -65,6 +109,20 @@ export function parseCellValue(value, editorTypes?: DataEditorTypesBehaviour) {
|
||||
}
|
||||
|
||||
if (editorTypes?.parseHexAsBuffer) {
|
||||
const mUuid3 = value.match(uuid3WrapperRegex);
|
||||
if (mUuid3) {
|
||||
const base64Uuid3 = uuidToBase64(mUuid3[1]);
|
||||
if (base64Uuid3 != null) return { $binary: { base64: base64Uuid3, subType: '03' } };
|
||||
}
|
||||
const mUuid4 = value.match(uuid4WrapperRegex);
|
||||
if (mUuid4) {
|
||||
const base64Uuid4 = uuidToBase64(mUuid4[1]);
|
||||
if (base64Uuid4 != null) return { $binary: { base64: base64Uuid4, subType: '04' } };
|
||||
}
|
||||
if (uuidRegex.test(value)) {
|
||||
const base64UuidPlain = uuidToBase64(value);
|
||||
if (base64UuidPlain != null) return { $binary: { base64: base64UuidPlain, subType: '04' } };
|
||||
}
|
||||
const mHex = value.match(/^0x([0-9a-fA-F][0-9a-fA-F])+$/);
|
||||
if (mHex) {
|
||||
return {
|
||||
@@ -266,6 +324,21 @@ export function stringifyCellValue(
|
||||
if (value === false) return { value: 'false', gridStyle: 'valueCellStyle' };
|
||||
|
||||
if (value?.$binary?.base64) {
|
||||
const subType = value.$binary.subType;
|
||||
if (subType === '03' || subType === '04') {
|
||||
const uuidStr = base64ToUuid(value.$binary.base64);
|
||||
if (uuidStr != null) {
|
||||
if (intent === 'gridCellIntent' || intent === 'exportIntent' || intent === 'clipboardIntent' || intent === 'stringConversionIntent') {
|
||||
return { value: uuidStr, gridStyle: 'valueCellStyle' };
|
||||
}
|
||||
// For editing intents: tag with subType so parseCellValue can round-trip it
|
||||
const tag = subType === '03' ? 'UUID3' : 'UUID';
|
||||
return { value: `${tag}("${uuidStr}")`, gridStyle: 'valueCellStyle' };
|
||||
}
|
||||
}
|
||||
if (intent === 'gridCellIntent' && value.$binary.base64.length > MAX_GRID_BINARY_SIZE) {
|
||||
return { value: `(Field too large, ${formatByteSize(Math.round(value.$binary.base64.length * 3 / 4))})`, gridStyle: 'nullCellStyle' };
|
||||
}
|
||||
return {
|
||||
value: base64ToHex(value.$binary.base64),
|
||||
gridStyle: 'valueCellStyle',
|
||||
@@ -354,6 +427,14 @@ export function stringifyCellValue(
|
||||
}
|
||||
}
|
||||
|
||||
if (value?.type === 'Buffer' && _isArray(value.data)) {
|
||||
if (intent === 'gridCellIntent') {
|
||||
return value.data.length > MAX_GRID_BINARY_SIZE
|
||||
? { value: `(Field too large, ${formatByteSize(value.data.length)})`, gridStyle: 'nullCellStyle' }
|
||||
: { value: '0x' + arrayToHexString(value.data), gridStyle: 'valueCellStyle' };
|
||||
}
|
||||
}
|
||||
|
||||
if (_isArray(value)) {
|
||||
switch (intent) {
|
||||
case 'gridCellIntent':
|
||||
@@ -482,7 +563,7 @@ export function shouldOpenMultilineDialog(value) {
|
||||
}
|
||||
|
||||
export function isJsonLikeLongString(value) {
|
||||
return _isString(value) && value.length > 100 && value.match(/^\s*\{.*\}\s*$|^\s*\[.*\]\s*$/m);
|
||||
return _isString(value) && value.length > 100 && value.length <= MAX_GRID_BINARY_SIZE && value.match(/^\s*\{.*\}\s*$|^\s*\[.*\]\s*$/m);
|
||||
}
|
||||
|
||||
export function getIconForRedisType(type) {
|
||||
|
||||
Vendored
+5
@@ -59,6 +59,7 @@ export interface QueryOptions {
|
||||
importSqlDump?: boolean;
|
||||
range?: { offset: number; limit: number };
|
||||
readonly?: boolean;
|
||||
commandTimeout?: number;
|
||||
}
|
||||
|
||||
export interface WriteTableOptions {
|
||||
@@ -423,6 +424,10 @@ export interface EngineDriver<TClient = any, TDataBase = any> extends FilterBeha
|
||||
engine: string;
|
||||
conid?: string;
|
||||
};
|
||||
|
||||
setTransactionIsolationLevel?(dbhan: DatabaseHandle<TClient, TDataBase>, level: string): Promise<void>;
|
||||
isolationLevels?: string[];
|
||||
defaultIsolationLevel?: string;
|
||||
}
|
||||
|
||||
export interface DatabaseModification {
|
||||
|
||||
@@ -69,6 +69,8 @@
|
||||
"chartjs-plugin-zoom": "^1.2.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"debug": "^4.3.4",
|
||||
"dom-to-image": "^2.6.0",
|
||||
"dompurify": "^3.3.2",
|
||||
"flatpickr": "^4.6.13",
|
||||
"fuzzy": "^0.1.3",
|
||||
"highlight.js": "^11.11.1",
|
||||
|
||||
@@ -1,286 +1,307 @@
|
||||
<script context="module" lang="ts">
|
||||
import { __t } from '../translations';
|
||||
const getCurrentEditor = () => getActiveComponent('CollectionDataGridCore');
|
||||
|
||||
registerCommand({
|
||||
id: 'collectionDataGrid.openQuery',
|
||||
category: __t('command.dataGrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('command.dataGrid.openQuery', { defaultMessage: 'Open query' }),
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().openQuery(),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'collectionDataGrid.export',
|
||||
category: __t('command.dataGrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('command.dataGrid.export', { defaultMessage: 'Export' }),
|
||||
keyText: 'CtrlOrCommand+E',
|
||||
icon: 'icon export',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().exportGrid(),
|
||||
});
|
||||
|
||||
function buildConditionForGrid(props) {
|
||||
const filters = props?.display?.config?.filters;
|
||||
const filterBehaviour =
|
||||
props?.display?.driver?.getFilterBehaviour(null, standardFilterBehaviours) ?? mongoFilterBehaviour;
|
||||
|
||||
// console.log('USED FILTER BEHAVIOUR', filterBehaviour);
|
||||
|
||||
const conditions = [];
|
||||
for (const uniqueName in filters || {}) {
|
||||
if (!filters[uniqueName]) continue;
|
||||
try {
|
||||
const ast = parseFilter(filters[uniqueName], filterBehaviour);
|
||||
// console.log('AST', ast);
|
||||
const cond = _.cloneDeepWith(ast, expr => {
|
||||
if (expr.exprType == 'placeholder') {
|
||||
return {
|
||||
exprType: 'column',
|
||||
columnName: uniqueName,
|
||||
};
|
||||
}
|
||||
|
||||
// if (expr.__placeholder__) {
|
||||
// return {
|
||||
// [uniqueName]: expr.__placeholder__,
|
||||
// };
|
||||
// }
|
||||
});
|
||||
conditions.push(cond);
|
||||
} catch (err) {
|
||||
// error in filter
|
||||
}
|
||||
}
|
||||
|
||||
return conditions.length > 0
|
||||
? {
|
||||
conditionType: 'and',
|
||||
conditions,
|
||||
}
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function buildSortForGrid(props) {
|
||||
const sort = props?.display?.config?.sort;
|
||||
|
||||
if (sort?.length > 0) {
|
||||
return sort.map(col => ({
|
||||
columnName: col.uniqueName,
|
||||
direction: col.order,
|
||||
}));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function loadCollectionDataPage(props, offset, limit) {
|
||||
const { conid, database } = props;
|
||||
|
||||
const response = await apiCall('database-connections/collection-data', {
|
||||
conid,
|
||||
database,
|
||||
options: {
|
||||
pureName: props.pureName,
|
||||
limit,
|
||||
skip: offset,
|
||||
condition: buildConditionForGrid(props),
|
||||
sort: buildSortForGrid(props),
|
||||
},
|
||||
auditLogSessionGroup: 'data-grid',
|
||||
});
|
||||
|
||||
if (response.errorMessage) return response;
|
||||
return response.rows;
|
||||
}
|
||||
|
||||
function dataPageAvailable(props) {
|
||||
return true;
|
||||
// const { display } = props;
|
||||
// const sql = display.getPageQuery(0, 1);
|
||||
// return !!sql;
|
||||
}
|
||||
|
||||
async function loadRowCount(props) {
|
||||
const { conid, database } = props;
|
||||
|
||||
const response = await apiCall('database-connections/collection-data', {
|
||||
conid,
|
||||
database,
|
||||
options: {
|
||||
pureName: props.pureName,
|
||||
countDocuments: true,
|
||||
condition: buildConditionForGrid(props),
|
||||
},
|
||||
});
|
||||
|
||||
return response.count;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { parseFilter } from 'dbgate-filterparser';
|
||||
import _ from 'lodash';
|
||||
import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
|
||||
import registerCommand from '../commands/registerCommand';
|
||||
import {
|
||||
extractShellConnection,
|
||||
extractShellConnectionHostable,
|
||||
extractShellHostConnection,
|
||||
} from '../impexp/createImpExpScript';
|
||||
import { apiCall } from '../utility/api';
|
||||
|
||||
import { registerMenu } from '../utility/contextMenu';
|
||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||
import createQuickExportMenu from '../utility/createQuickExportMenu';
|
||||
import { exportQuickExportFile } from '../utility/exportFileTools';
|
||||
import { getConnectionInfo } from '../utility/metadataLoaders';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import ChangeSetGrider from './ChangeSetGrider';
|
||||
|
||||
import LoadingDataGridCore from './LoadingDataGridCore.svelte';
|
||||
import { mongoFilterBehaviour, standardFilterBehaviours } from 'dbgate-tools';
|
||||
import { openImportExportTab } from '../utility/importExportTools';
|
||||
export let conid;
|
||||
export let display;
|
||||
export let database;
|
||||
export let schemaName;
|
||||
export let pureName;
|
||||
export let config;
|
||||
export let changeSetState;
|
||||
export let dispatchChangeSet;
|
||||
|
||||
export let macroPreview;
|
||||
export let macroValues;
|
||||
export let setLoadedRows = null;
|
||||
export let onPublishedCellsChanged;
|
||||
|
||||
// export let onChangeGrider = undefined;
|
||||
|
||||
let loadedRows = [];
|
||||
let publishedCells = [];
|
||||
|
||||
export const activator = createActivator('CollectionDataGridCore', false);
|
||||
|
||||
// $: console.log('loadedRows BIND', loadedRows);
|
||||
$: grider = new ChangeSetGrider(
|
||||
loadedRows,
|
||||
changeSetState,
|
||||
dispatchChangeSet,
|
||||
display,
|
||||
macroPreview,
|
||||
macroValues,
|
||||
publishedCells
|
||||
);
|
||||
// $: console.log('GRIDER', grider);
|
||||
// $: if (onChangeGrider) onChangeGrider(grider);
|
||||
|
||||
function getExportQuery() {
|
||||
return display?.driver?.getCollectionExportQueryScript?.(
|
||||
pureName,
|
||||
buildConditionForGrid($$props),
|
||||
buildSortForGrid($$props)
|
||||
);
|
||||
// return `db.collection('${pureName}')
|
||||
// .find(${JSON.stringify(buildConditionForGrid($$props) || {})})
|
||||
// .sort(${JSON.stringify(buildMongoSort($$props) || {})})`;
|
||||
}
|
||||
|
||||
function getExportQueryJson() {
|
||||
return display?.driver?.getCollectionExportQueryJson?.(
|
||||
pureName,
|
||||
buildConditionForGrid($$props),
|
||||
buildSortForGrid($$props)
|
||||
);
|
||||
// return {
|
||||
// collection: pureName,
|
||||
// condition: buildConditionForGrid($$props) || {},
|
||||
// sort: buildMongoSort($$props) || {},
|
||||
// };
|
||||
}
|
||||
|
||||
export async function exportGrid() {
|
||||
const coninfo = await getConnectionInfo({ conid });
|
||||
const initialValues: any = {};
|
||||
initialValues.sourceStorageType = 'query';
|
||||
initialValues.sourceConnectionId = conid;
|
||||
initialValues.sourceDatabaseName = database;
|
||||
initialValues.sourceQuery = coninfo.isReadOnly
|
||||
? JSON.stringify(getExportQueryJson(), undefined, 2)
|
||||
: getExportQuery();
|
||||
initialValues.sourceQueryType = coninfo.isReadOnly ? 'json' : 'native';
|
||||
initialValues.sourceList = [pureName];
|
||||
initialValues[`columns_${pureName}`] = display.getExportColumnMap();
|
||||
openImportExportTab(initialValues);
|
||||
// showModal(ImportExportModal, { initialValues });
|
||||
}
|
||||
|
||||
export function openQuery() {
|
||||
openNewTab(
|
||||
{
|
||||
title: 'Query #',
|
||||
icon: 'img sql-file',
|
||||
tabComponent: 'QueryTab',
|
||||
focused: true,
|
||||
props: {
|
||||
conid,
|
||||
database,
|
||||
},
|
||||
},
|
||||
{
|
||||
editor: getExportQuery(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const quickExportHandler = fmt => async () => {
|
||||
const coninfo = await getConnectionInfo({ conid });
|
||||
exportQuickExportFile(
|
||||
pureName || 'Data',
|
||||
{
|
||||
functionName: 'queryReader',
|
||||
props: {
|
||||
...extractShellConnectionHostable(coninfo, database),
|
||||
queryType: coninfo.isReadOnly ? 'json' : 'native',
|
||||
query: coninfo.isReadOnly ? getExportQueryJson() : getExportQuery(),
|
||||
},
|
||||
hostConnection: extractShellHostConnection(coninfo, database),
|
||||
},
|
||||
fmt,
|
||||
display.getExportColumnMap()
|
||||
);
|
||||
};
|
||||
|
||||
registerQuickExportHandler(quickExportHandler);
|
||||
|
||||
registerMenu({ command: 'collectionDataGrid.openQuery', tag: 'export' }, () =>
|
||||
createQuickExportMenu(
|
||||
quickExportHandler,
|
||||
{
|
||||
command: 'collectionDataGrid.export',
|
||||
},
|
||||
{ tag: 'export' }
|
||||
)
|
||||
);
|
||||
|
||||
function handleSetLoadedRows(rows) {
|
||||
loadedRows = rows;
|
||||
if (setLoadedRows) setLoadedRows(rows);
|
||||
}
|
||||
</script>
|
||||
|
||||
<LoadingDataGridCore
|
||||
{...$$props}
|
||||
loadDataPage={loadCollectionDataPage}
|
||||
{dataPageAvailable}
|
||||
{loadRowCount}
|
||||
setLoadedRows={handleSetLoadedRows}
|
||||
onPublishedCellsChanged={value => {
|
||||
publishedCells = value;
|
||||
if (onPublishedCellsChanged) {
|
||||
onPublishedCellsChanged(value);
|
||||
}
|
||||
}}
|
||||
frameSelection={!!macroPreview}
|
||||
onOpenQuery={openQuery}
|
||||
{grider}
|
||||
const getCurrentEditor = () => getActiveComponent('CollectionDataGridCore');
|
||||
|
||||
registerCommand({
|
||||
id: 'collectionDataGrid.openQuery',
|
||||
category: __t('command.dataGrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('command.dataGrid.openQuery', { defaultMessage: 'Open query' }),
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().openQuery(),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'collectionDataGrid.export',
|
||||
category: __t('command.dataGrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('command.dataGrid.export', { defaultMessage: 'Export' }),
|
||||
keyText: 'CtrlOrCommand+E',
|
||||
icon: 'icon export',
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => getCurrentEditor().exportGrid(),
|
||||
});
|
||||
|
||||
function buildConditionForGrid(props) {
|
||||
const filters = props?.display?.config?.filters;
|
||||
const filterBehaviour =
|
||||
props?.display?.driver?.getFilterBehaviour(null, standardFilterBehaviours) ?? mongoFilterBehaviour;
|
||||
|
||||
// console.log('USED FILTER BEHAVIOUR', filterBehaviour);
|
||||
|
||||
const conditions = [];
|
||||
for (const uniqueName in filters || {}) {
|
||||
if (!filters[uniqueName]) continue;
|
||||
try {
|
||||
const ast = parseFilter(filters[uniqueName], filterBehaviour);
|
||||
// console.log('AST', ast);
|
||||
const cond = _.cloneDeepWith(ast, expr => {
|
||||
if (expr.exprType == 'placeholder') {
|
||||
return {
|
||||
exprType: 'column',
|
||||
columnName: uniqueName,
|
||||
};
|
||||
}
|
||||
|
||||
// if (expr.__placeholder__) {
|
||||
// return {
|
||||
// [uniqueName]: expr.__placeholder__,
|
||||
// };
|
||||
// }
|
||||
});
|
||||
conditions.push(cond);
|
||||
} catch (err) {
|
||||
// error in filter
|
||||
}
|
||||
}
|
||||
|
||||
return conditions.length > 0
|
||||
? {
|
||||
conditionType: 'and',
|
||||
conditions,
|
||||
}
|
||||
: undefined;
|
||||
}
|
||||
|
||||
function buildSortForGrid(props) {
|
||||
const sort = props?.display?.config?.sort;
|
||||
|
||||
if (sort?.length > 0) {
|
||||
return sort.map(col => ({
|
||||
columnName: col.uniqueName,
|
||||
direction: col.order,
|
||||
}));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export async function loadCollectionDataPage(props, offset, limit) {
|
||||
const { conid, database } = props;
|
||||
|
||||
const response = await apiCall('database-connections/collection-data', {
|
||||
conid,
|
||||
database,
|
||||
options: {
|
||||
pureName: props.pureName,
|
||||
limit,
|
||||
skip: offset,
|
||||
condition: buildConditionForGrid(props),
|
||||
sort: buildSortForGrid(props),
|
||||
},
|
||||
auditLogSessionGroup: 'data-grid',
|
||||
});
|
||||
|
||||
if (response.errorMessage) return response;
|
||||
return response.rows;
|
||||
}
|
||||
|
||||
function dataPageAvailable(props) {
|
||||
return true;
|
||||
// const { display } = props;
|
||||
// const sql = display.getPageQuery(0, 1);
|
||||
// return !!sql;
|
||||
}
|
||||
|
||||
async function loadRowCount(props) {
|
||||
const { conid, database } = props;
|
||||
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Row count query timed out')), 3000)
|
||||
);
|
||||
|
||||
try {
|
||||
const response = await Promise.race([
|
||||
apiCall('database-connections/collection-data', {
|
||||
conid,
|
||||
database,
|
||||
commandTimeout: 3000,
|
||||
options: {
|
||||
pureName: props.pureName,
|
||||
countDocuments: true,
|
||||
condition: buildConditionForGrid(props),
|
||||
},
|
||||
}),
|
||||
timeoutPromise,
|
||||
]);
|
||||
|
||||
if (response && typeof response === 'object' && (response as any).errorMessage) {
|
||||
return { errorMessage: (response as any).errorMessage };
|
||||
}
|
||||
|
||||
if (response && typeof response === 'object' && typeof (response as any).count === 'number') {
|
||||
return (response as any).count;
|
||||
}
|
||||
|
||||
return { errorMessage: 'Error loading row count' };
|
||||
} catch (err) {
|
||||
return { errorMessage: err.message || 'Error loading row count' };
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { parseFilter } from 'dbgate-filterparser';
|
||||
import _ from 'lodash';
|
||||
import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
|
||||
import registerCommand from '../commands/registerCommand';
|
||||
import {
|
||||
extractShellConnection,
|
||||
extractShellConnectionHostable,
|
||||
extractShellHostConnection,
|
||||
} from '../impexp/createImpExpScript';
|
||||
import { apiCall } from '../utility/api';
|
||||
|
||||
import { registerMenu } from '../utility/contextMenu';
|
||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||
import createQuickExportMenu from '../utility/createQuickExportMenu';
|
||||
import { exportQuickExportFile } from '../utility/exportFileTools';
|
||||
import { getConnectionInfo } from '../utility/metadataLoaders';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import ChangeSetGrider from './ChangeSetGrider';
|
||||
|
||||
import LoadingDataGridCore from './LoadingDataGridCore.svelte';
|
||||
import { mongoFilterBehaviour, standardFilterBehaviours } from 'dbgate-tools';
|
||||
import { openImportExportTab } from '../utility/importExportTools';
|
||||
export let conid;
|
||||
export let display;
|
||||
export let database;
|
||||
export let schemaName;
|
||||
export let pureName;
|
||||
export let config;
|
||||
export let changeSetState;
|
||||
export let dispatchChangeSet;
|
||||
|
||||
export let macroPreview;
|
||||
export let macroValues;
|
||||
export let setLoadedRows = null;
|
||||
export let onPublishedCellsChanged;
|
||||
|
||||
// export let onChangeGrider = undefined;
|
||||
|
||||
let loadedRows = [];
|
||||
let publishedCells = [];
|
||||
|
||||
export const activator = createActivator('CollectionDataGridCore', false);
|
||||
|
||||
// $: console.log('loadedRows BIND', loadedRows);
|
||||
$: grider = new ChangeSetGrider(
|
||||
loadedRows,
|
||||
changeSetState,
|
||||
dispatchChangeSet,
|
||||
display,
|
||||
macroPreview,
|
||||
macroValues,
|
||||
publishedCells
|
||||
);
|
||||
// $: console.log('GRIDER', grider);
|
||||
// $: if (onChangeGrider) onChangeGrider(grider);
|
||||
|
||||
function getExportQuery() {
|
||||
return display?.driver?.getCollectionExportQueryScript?.(
|
||||
pureName,
|
||||
buildConditionForGrid($$props),
|
||||
buildSortForGrid($$props)
|
||||
);
|
||||
// return `db.collection('${pureName}')
|
||||
// .find(${JSON.stringify(buildConditionForGrid($$props) || {})})
|
||||
// .sort(${JSON.stringify(buildMongoSort($$props) || {})})`;
|
||||
}
|
||||
|
||||
function getExportQueryJson() {
|
||||
return display?.driver?.getCollectionExportQueryJson?.(
|
||||
pureName,
|
||||
buildConditionForGrid($$props),
|
||||
buildSortForGrid($$props)
|
||||
);
|
||||
// return {
|
||||
// collection: pureName,
|
||||
// condition: buildConditionForGrid($$props) || {},
|
||||
// sort: buildMongoSort($$props) || {},
|
||||
// };
|
||||
}
|
||||
|
||||
export async function exportGrid() {
|
||||
const coninfo = await getConnectionInfo({ conid });
|
||||
const initialValues: any = {};
|
||||
initialValues.sourceStorageType = 'query';
|
||||
initialValues.sourceConnectionId = conid;
|
||||
initialValues.sourceDatabaseName = database;
|
||||
initialValues.sourceQuery = coninfo.isReadOnly
|
||||
? JSON.stringify(getExportQueryJson(), undefined, 2)
|
||||
: getExportQuery();
|
||||
initialValues.sourceQueryType = coninfo.isReadOnly ? 'json' : 'native';
|
||||
initialValues.sourceList = [pureName];
|
||||
initialValues[`columns_${pureName}`] = display.getExportColumnMap();
|
||||
openImportExportTab(initialValues);
|
||||
// showModal(ImportExportModal, { initialValues });
|
||||
}
|
||||
|
||||
export function openQuery() {
|
||||
openNewTab(
|
||||
{
|
||||
title: 'Query #',
|
||||
icon: 'img sql-file',
|
||||
tabComponent: 'QueryTab',
|
||||
focused: true,
|
||||
props: {
|
||||
conid,
|
||||
database,
|
||||
},
|
||||
},
|
||||
{
|
||||
editor: getExportQuery(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const quickExportHandler = fmt => async () => {
|
||||
const coninfo = await getConnectionInfo({ conid });
|
||||
exportQuickExportFile(
|
||||
pureName || 'Data',
|
||||
{
|
||||
functionName: 'queryReader',
|
||||
props: {
|
||||
...extractShellConnectionHostable(coninfo, database),
|
||||
queryType: coninfo.isReadOnly ? 'json' : 'native',
|
||||
query: coninfo.isReadOnly ? getExportQueryJson() : getExportQuery(),
|
||||
},
|
||||
hostConnection: extractShellHostConnection(coninfo, database),
|
||||
},
|
||||
fmt,
|
||||
display.getExportColumnMap()
|
||||
);
|
||||
};
|
||||
|
||||
registerQuickExportHandler(quickExportHandler);
|
||||
|
||||
registerMenu({ command: 'collectionDataGrid.openQuery', tag: 'export' }, () =>
|
||||
createQuickExportMenu(
|
||||
quickExportHandler,
|
||||
{
|
||||
command: 'collectionDataGrid.export',
|
||||
},
|
||||
{ tag: 'export' }
|
||||
)
|
||||
);
|
||||
|
||||
function handleSetLoadedRows(rows) {
|
||||
loadedRows = rows;
|
||||
if (setLoadedRows) setLoadedRows(rows);
|
||||
}
|
||||
</script>
|
||||
|
||||
<LoadingDataGridCore
|
||||
{...$$props}
|
||||
loadDataPage={loadCollectionDataPage}
|
||||
{dataPageAvailable}
|
||||
{loadRowCount}
|
||||
setLoadedRows={handleSetLoadedRows}
|
||||
onPublishedCellsChanged={value => {
|
||||
publishedCells = value;
|
||||
if (onPublishedCellsChanged) {
|
||||
onPublishedCellsChanged(value);
|
||||
}
|
||||
}}
|
||||
frameSelection={!!macroPreview}
|
||||
onOpenQuery={openQuery}
|
||||
{grider}
|
||||
/>
|
||||
|
||||
@@ -461,6 +461,8 @@
|
||||
export let frameSelection = undefined;
|
||||
export let isLoading = false;
|
||||
export let allRowCount = undefined;
|
||||
export let allRowCountError = undefined;
|
||||
export let onReloadRowCount = undefined;
|
||||
export let onReferenceSourceChanged = undefined;
|
||||
export let onPublishedCellsChanged = undefined;
|
||||
export let onReferenceClick = undefined;
|
||||
@@ -2400,6 +2402,15 @@
|
||||
<div class="row-count-label">
|
||||
{_t('datagrid.rows', { defaultMessage: 'Rows' })}: {allRowCount.toLocaleString()}
|
||||
</div>
|
||||
{:else if allRowCountError && multipleGridsOnTab}
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div
|
||||
class="row-count-label row-count-error"
|
||||
title={allRowCountError}
|
||||
on:click={onReloadRowCount}
|
||||
>
|
||||
{_t('datagrid.rows', { defaultMessage: 'Rows' })}: {_t('datagrid.rowCountMany', { defaultMessage: 'Many' })}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if isLoading}
|
||||
@@ -2408,6 +2419,13 @@
|
||||
|
||||
{#if !tabControlHiddenTab && !multipleGridsOnTab && allRowCount != null}
|
||||
<StatusBarTabItem text={`${_t('datagrid.rows', { defaultMessage: 'Rows' })}: ${allRowCount.toLocaleString()}`} />
|
||||
{:else if !tabControlHiddenTab && !multipleGridsOnTab && allRowCountError}
|
||||
<StatusBarTabItem
|
||||
text={`${_t('datagrid.rows', { defaultMessage: 'Rows' })}: ${_t('datagrid.rowCountMany', { defaultMessage: 'Many' })}`}
|
||||
title={allRowCountError}
|
||||
clickable
|
||||
onClick={onReloadRowCount}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -2472,6 +2490,15 @@
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.row-count-error {
|
||||
cursor: pointer;
|
||||
color: var(--theme-font-3);
|
||||
}
|
||||
|
||||
.row-count-error:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.selection-menu {
|
||||
position: absolute;
|
||||
background-color: var(--theme-datagrid-corner-label-background);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
let isLoadedAll = false;
|
||||
let loadedTime = new Date().getTime();
|
||||
let allRowCount = null;
|
||||
let allRowCountError = null;
|
||||
let errorMessage = null;
|
||||
let domGrid;
|
||||
|
||||
@@ -37,8 +38,14 @@
|
||||
}
|
||||
|
||||
const handleLoadRowCount = async () => {
|
||||
const rowCount = await loadRowCount($$props);
|
||||
allRowCount = rowCount;
|
||||
const result = await loadRowCount($$props);
|
||||
if (result != null && typeof result === 'object' && result.errorMessage) {
|
||||
allRowCount = null;
|
||||
allRowCountError = result.errorMessage;
|
||||
} else {
|
||||
allRowCount = result;
|
||||
allRowCountError = null;
|
||||
}
|
||||
};
|
||||
|
||||
async function loadNextData() {
|
||||
@@ -103,6 +110,7 @@
|
||||
|
||||
function reload() {
|
||||
allRowCount = null;
|
||||
allRowCountError = null;
|
||||
isLoading = false;
|
||||
loadedRows = [];
|
||||
isLoadedAll = false;
|
||||
@@ -132,6 +140,8 @@
|
||||
{errorMessage}
|
||||
{isLoading}
|
||||
allRowCount={rowCountLoaded || allRowCount}
|
||||
allRowCountError={allRowCountError}
|
||||
onReloadRowCount={handleLoadRowCount}
|
||||
{isLoadedAll}
|
||||
{loadedTime}
|
||||
{grider}
|
||||
|
||||
@@ -2,238 +2,253 @@
|
||||
import { getActiveComponent } from '../utility/createActivator';
|
||||
import registerCommand from '../commands/registerCommand';
|
||||
import hasPermission from '../utility/hasPermission';
|
||||
import { __t, _t } from '../translations'
|
||||
const getCurrentEditor = () => getActiveComponent('SqlDataGridCore');
|
||||
|
||||
registerCommand({
|
||||
id: 'sqlDataGrid.openQuery',
|
||||
category: __t('command.datagrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('command.openQuery', { defaultMessage : 'Open query' }),
|
||||
testEnabled: () => getCurrentEditor() != null && hasPermission('dbops/query'),
|
||||
onClick: () => getCurrentEditor().openQuery(),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'sqlDataGrid.export',
|
||||
category: __t('command.datagrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('common.export', { defaultMessage : 'Export' }),
|
||||
icon: 'icon export',
|
||||
keyText: 'CtrlOrCommand+E',
|
||||
testEnabled: () => getCurrentEditor() != null && hasPermission('dbops/export'),
|
||||
onClick: () => getCurrentEditor().exportGrid(),
|
||||
});
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import _ from 'lodash';
|
||||
import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
import {
|
||||
extractShellConnection,
|
||||
extractShellConnectionHostable,
|
||||
extractShellHostConnection,
|
||||
} from '../impexp/createImpExpScript';
|
||||
import { apiCall } from '../utility/api';
|
||||
|
||||
import { registerMenu } from '../utility/contextMenu';
|
||||
import createActivator from '../utility/createActivator';
|
||||
import createQuickExportMenu from '../utility/createQuickExportMenu';
|
||||
import { exportQuickExportFile } from '../utility/exportFileTools';
|
||||
import { getConnectionInfo } from '../utility/metadataLoaders';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import ChangeSetGrider from './ChangeSetGrider';
|
||||
|
||||
import LoadingDataGridCore from './LoadingDataGridCore.svelte';
import { openImportExportTab } from '../utility/importExportTools';
|
||||
import { getIntSettingsValue } from '../settings/settingsTools';
|
||||
import OverlayDiffGrider from './OverlayDiffGrider';
|
||||
|
||||
export let conid;
|
||||
export let display;
|
||||
export let database;
|
||||
export let schemaName;
|
||||
export let pureName;
|
||||
export let config;
|
||||
export let changeSetState;
|
||||
export let dispatchChangeSet;
|
||||
export let overlayDefinition = null;
|
||||
|
||||
export let macroPreview;
|
||||
export let macroValues;
|
||||
export let onPublishedCellsChanged;
|
||||
|
||||
let publishedCells = [];
|
||||
|
||||
// export let onChangeGrider = undefined;
|
||||
|
||||
export const activator = createActivator('SqlDataGridCore', false);
|
||||
|
||||
let loadedRows = [];
|
||||
|
||||
let grider;
|
||||
|
||||
// $: console.log('loadedRows BIND', loadedRows);
|
||||
|
||||
$: {
|
||||
if (!overlayDefinition && macroPreview) {
|
||||
grider = new ChangeSetGrider(
|
||||
loadedRows,
|
||||
changeSetState,
|
||||
dispatchChangeSet,
|
||||
display,
|
||||
macroPreview,
|
||||
macroValues,
|
||||
publishedCells
|
||||
);
|
||||
}
|
||||
}
|
||||
// prevent recreate grider, if no macro is selected, so there is no need to selectedcells in macro
|
||||
$: {
|
||||
if (!overlayDefinition && !macroPreview) {
|
||||
grider = new ChangeSetGrider(loadedRows, changeSetState, dispatchChangeSet, display);
|
||||
}
|
||||
}
|
||||
// $: console.log('GRIDER', grider);
|
||||
// $: if (onChangeGrider) onChangeGrider(grider);
|
||||
|
||||
$: {
|
||||
if (overlayDefinition) {
|
||||
grider = new OverlayDiffGrider(
|
||||
loadedRows,
|
||||
display,
|
||||
overlayDefinition.matchColumns,
|
||||
overlayDefinition.overlayData,
|
||||
overlayDefinition.matchedDbKeys
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function exportGrid() {
|
||||
const coninfo = await getConnectionInfo({ conid });
|
||||
|
||||
const initialValues: any = {};
|
||||
initialValues.sourceStorageType = 'query';
|
||||
initialValues.sourceConnectionId = conid;
|
||||
initialValues.sourceDatabaseName = database;
|
||||
initialValues.sourceQuery = coninfo.isReadOnly
|
||||
? JSON.stringify(display.getExportQueryJson(), undefined, 2)
|
||||
: display.getExportQuery();
|
||||
initialValues.sourceQueryType = coninfo.isReadOnly ? 'json' : 'native';
|
||||
initialValues.sourceList = display.baseTableOrSimilar ? [display.baseTableOrSimilar.pureName] : [];
|
||||
initialValues[`columns_${pureName}`] = display.getExportColumnMap();
|
||||
openImportExportTab(initialValues);
|
||||
// showModal(ImportExportModal, { initialValues });
|
||||
}
|
||||
|
||||
export function openQuery(sql?) {
|
||||
openNewTab(
|
||||
{
|
||||
title: _t('common.queryNumber', { defaultMessage: 'Query #' }),
|
||||
icon: 'img sql-file',
|
||||
tabComponent: 'QueryTab',
|
||||
focused: true,
|
||||
props: {
|
||||
schemaName: display.baseTableOrSimilar?.schemaName,
|
||||
pureName: display.baseTableOrSimilar?.pureName,
|
||||
conid,
|
||||
database,
|
||||
},
|
||||
},
|
||||
{
|
||||
editor: sql ?? display.getExportQuery(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function openQueryOnError() {
|
||||
openQuery(display.getPageQueryText(0, getIntSettingsValue('dataGrid.pageSize', 100, 5, 50000)));
|
||||
}
|
||||
|
||||
const quickExportHandler = fmt => async () => {
|
||||
const coninfo = await getConnectionInfo({ conid });
|
||||
exportQuickExportFile(
|
||||
pureName || 'Data',
|
||||
{
|
||||
functionName: 'queryReader',
|
||||
props: {
|
||||
...extractShellConnectionHostable(coninfo, database),
|
||||
queryType: coninfo.isReadOnly ? 'json' : 'native',
|
||||
query: coninfo.isReadOnly ? display.getExportQueryJson() : display.getExportQuery(),
|
||||
},
|
||||
hostConnection: extractShellHostConnection(coninfo, database),
|
||||
},
|
||||
fmt,
|
||||
display.getExportColumnMap()
|
||||
);
|
||||
};
|
||||
registerQuickExportHandler(quickExportHandler);
|
||||
|
||||
registerMenu(
|
||||
{ command: 'sqlDataGrid.openActiveChart', tag: 'chart' },
|
||||
{ command: 'sqlDataGrid.openQuery', tag: 'export' },
|
||||
() =>
|
||||
createQuickExportMenu(
|
||||
quickExportHandler,
|
||||
{
|
||||
command: 'sqlDataGrid.export',
|
||||
},
|
||||
{ tag: 'export' }
|
||||
)
|
||||
);
|
||||
|
||||
function handleSetLoadedRows(rows) {
|
||||
loadedRows = rows;
|
||||
}
|
||||
|
||||
async function loadDataPage(props, offset, limit) {
|
||||
const { display, conid, database } = props;
|
||||
|
||||
const select = display.getPageQuery(offset, limit);
|
||||
|
||||
const response = await apiCall('database-connections/sql-select', {
|
||||
conid,
|
||||
database,
|
||||
select,
|
||||
auditLogSessionGroup: 'data-grid',
|
||||
});
|
||||
|
||||
if (response.errorMessage) return response;
|
||||
return response.rows;
|
||||
}
|
||||
|
||||
function dataPageAvailable(props) {
|
||||
const { display } = props;
|
||||
const select = display.getPageQuery(0, 1);
|
||||
return !!select;
|
||||
}
|
||||
|
||||
async function loadRowCount(props) {
|
||||
const { display, conid, database } = props;
|
||||
|
||||
const select = display.getCountQuery();
|
||||
|
||||
const response = await apiCall('database-connections/sql-select', {
|
||||
conid,
|
||||
database,
|
||||
select,
|
||||
});
|
||||
|
||||
return parseInt(response.rows[0].count);
|
||||
}
|
||||
</script>
|
||||
|
||||
<LoadingDataGridCore
|
||||
{...$$props}
|
||||
{loadDataPage}
|
||||
{dataPageAvailable}
|
||||
{loadRowCount}
|
||||
setLoadedRows={handleSetLoadedRows}
|
||||
onPublishedCellsChanged={value => {
|
||||
publishedCells = value;
|
||||
if (onPublishedCellsChanged) {
|
||||
onPublishedCellsChanged(value);
|
||||
}
|
||||
}}
|
||||
frameSelection={!!macroPreview}
|
||||
{grider}
|
||||
{display}
|
||||
onOpenQuery={openQuery}
|
||||
onOpenQueryOnError={openQueryOnError}
|
||||
/>
|
||||
import { __t, _t } from '../translations'
|
||||
const getCurrentEditor = () => getActiveComponent('SqlDataGridCore');
|
||||
|
||||
registerCommand({
|
||||
id: 'sqlDataGrid.openQuery',
|
||||
category: __t('command.datagrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('command.openQuery', { defaultMessage : 'Open query' }),
|
||||
testEnabled: () => getCurrentEditor() != null && hasPermission('dbops/query'),
|
||||
onClick: () => getCurrentEditor().openQuery(),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'sqlDataGrid.export',
|
||||
category: __t('command.datagrid', { defaultMessage: 'Data grid' }),
|
||||
name: __t('common.export', { defaultMessage : 'Export' }),
|
||||
icon: 'icon export',
|
||||
keyText: 'CtrlOrCommand+E',
|
||||
testEnabled: () => getCurrentEditor() != null && hasPermission('dbops/export'),
|
||||
onClick: () => getCurrentEditor().exportGrid(),
|
||||
});
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import _ from 'lodash';
|
||||
import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
|
||||
import {
|
||||
extractShellConnection,
|
||||
extractShellConnectionHostable,
|
||||
extractShellHostConnection,
|
||||
} from '../impexp/createImpExpScript';
|
||||
import { apiCall } from '../utility/api';
|
||||
|
||||
import { registerMenu } from '../utility/contextMenu';
|
||||
import createActivator from '../utility/createActivator';
|
||||
import createQuickExportMenu from '../utility/createQuickExportMenu';
|
||||
import { exportQuickExportFile } from '../utility/exportFileTools';
|
||||
import { getConnectionInfo } from '../utility/metadataLoaders';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import ChangeSetGrider from './ChangeSetGrider';
|
||||
|
||||
import LoadingDataGridCore from './LoadingDataGridCore.svelte';
|
||||
import { openImportExportTab } from '../utility/importExportTools';
|
||||
import { getIntSettingsValue } from '../settings/settingsTools';
|
||||
import OverlayDiffGrider from './OverlayDiffGrider';
|
||||
|
||||
export let conid;
|
||||
export let display;
|
||||
export let database;
|
||||
export let schemaName;
|
||||
export let pureName;
|
||||
export let config;
|
||||
export let changeSetState;
|
||||
export let dispatchChangeSet;
|
||||
export let overlayDefinition = null;
|
||||
|
||||
export let macroPreview;
|
||||
export let macroValues;
|
||||
export let onPublishedCellsChanged;
|
||||
|
||||
let publishedCells = [];
|
||||
|
||||
// export let onChangeGrider = undefined;
|
||||
|
||||
export const activator = createActivator('SqlDataGridCore', false);
|
||||
|
||||
let loadedRows = [];
|
||||
|
||||
let grider;
|
||||
|
||||
// $: console.log('loadedRows BIND', loadedRows);
|
||||
|
||||
$: {
|
||||
if (!overlayDefinition && macroPreview) {
|
||||
grider = new ChangeSetGrider(
|
||||
loadedRows,
|
||||
changeSetState,
|
||||
dispatchChangeSet,
|
||||
display,
|
||||
macroPreview,
|
||||
macroValues,
|
||||
publishedCells
|
||||
);
|
||||
}
|
||||
}
|
||||
// prevent recreate grider, if no macro is selected, so there is no need to selectedcells in macro
|
||||
$: {
|
||||
if (!overlayDefinition && !macroPreview) {
|
||||
grider = new ChangeSetGrider(loadedRows, changeSetState, dispatchChangeSet, display);
|
||||
}
|
||||
}
|
||||
// $: console.log('GRIDER', grider);
|
||||
// $: if (onChangeGrider) onChangeGrider(grider);
|
||||
|
||||
$: {
|
||||
if (overlayDefinition) {
|
||||
grider = new OverlayDiffGrider(
|
||||
loadedRows,
|
||||
display,
|
||||
overlayDefinition.matchColumns,
|
||||
overlayDefinition.overlayData,
|
||||
overlayDefinition.matchedDbKeys
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export async function exportGrid() {
|
||||
const coninfo = await getConnectionInfo({ conid });
|
||||
|
||||
const initialValues: any = {};
|
||||
initialValues.sourceStorageType = 'query';
|
||||
initialValues.sourceConnectionId = conid;
|
||||
initialValues.sourceDatabaseName = database;
|
||||
initialValues.sourceQuery = coninfo.isReadOnly
|
||||
? JSON.stringify(display.getExportQueryJson(), undefined, 2)
|
||||
: display.getExportQuery();
|
||||
initialValues.sourceQueryType = coninfo.isReadOnly ? 'json' : 'native';
|
||||
initialValues.sourceList = display.baseTableOrSimilar ? [display.baseTableOrSimilar.pureName] : [];
|
||||
initialValues[`columns_${pureName}`] = display.getExportColumnMap();
|
||||
openImportExportTab(initialValues);
|
||||
// showModal(ImportExportModal, { initialValues });
|
||||
}
|
||||
|
||||
export function openQuery(sql?) {
|
||||
openNewTab(
|
||||
{
|
||||
title: _t('common.queryNumber', { defaultMessage: 'Query #' }),
|
||||
icon: 'img sql-file',
|
||||
tabComponent: 'QueryTab',
|
||||
focused: true,
|
||||
props: {
|
||||
schemaName: display.baseTableOrSimilar?.schemaName,
|
||||
pureName: display.baseTableOrSimilar?.pureName,
|
||||
conid,
|
||||
database,
|
||||
},
|
||||
},
|
||||
{
|
||||
editor: sql ?? display.getExportQuery(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function openQueryOnError() {
|
||||
openQuery(display.getPageQueryText(0, getIntSettingsValue('dataGrid.pageSize', 100, 5, 50000)));
|
||||
}
|
||||
|
||||
const quickExportHandler = fmt => async () => {
|
||||
const coninfo = await getConnectionInfo({ conid });
|
||||
exportQuickExportFile(
|
||||
pureName || 'Data',
|
||||
{
|
||||
functionName: 'queryReader',
|
||||
props: {
|
||||
...extractShellConnectionHostable(coninfo, database),
|
||||
queryType: coninfo.isReadOnly ? 'json' : 'native',
|
||||
query: coninfo.isReadOnly ? display.getExportQueryJson() : display.getExportQuery(),
|
||||
},
|
||||
hostConnection: extractShellHostConnection(coninfo, database),
|
||||
},
|
||||
fmt,
|
||||
display.getExportColumnMap()
|
||||
);
|
||||
};
|
||||
registerQuickExportHandler(quickExportHandler);
|
||||
|
||||
registerMenu(
|
||||
{ command: 'sqlDataGrid.openActiveChart', tag: 'chart' },
|
||||
{ command: 'sqlDataGrid.openQuery', tag: 'export' },
|
||||
() =>
|
||||
createQuickExportMenu(
|
||||
quickExportHandler,
|
||||
{
|
||||
command: 'sqlDataGrid.export',
|
||||
},
|
||||
{ tag: 'export' }
|
||||
)
|
||||
);
|
||||
|
||||
function handleSetLoadedRows(rows) {
|
||||
loadedRows = rows;
|
||||
}
|
||||
|
||||
async function loadDataPage(props, offset, limit) {
|
||||
const { display, conid, database } = props;
|
||||
|
||||
const select = display.getPageQuery(offset, limit);
|
||||
|
||||
const response = await apiCall('database-connections/sql-select', {
|
||||
conid,
|
||||
database,
|
||||
select,
|
||||
auditLogSessionGroup: 'data-grid',
|
||||
});
|
||||
|
||||
if (response.errorMessage) return response;
|
||||
return response.rows;
|
||||
}
|
||||
|
||||
function dataPageAvailable(props) {
|
||||
const { display } = props;
|
||||
const select = display.getPageQuery(0, 1);
|
||||
return !!select;
|
||||
}
|
||||
|
||||
async function loadRowCount(props) {
|
||||
const { display, conid, database } = props;
|
||||
|
||||
const select = display.getCountQuery();
|
||||
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Row count query timed out')), 3000)
|
||||
);
|
||||
|
||||
try {
|
||||
const response = await Promise.race([
|
||||
apiCall('database-connections/sql-select', {
|
||||
conid,
|
||||
database,
|
||||
select,
|
||||
commandTimeout: 3000,
|
||||
}),
|
||||
timeoutPromise,
|
||||
]);
|
||||
|
||||
if (response.errorMessage) return { errorMessage: response.errorMessage };
|
||||
return parseInt(response.rows[0].count);
|
||||
} catch (err) {
|
||||
return { errorMessage: err.message || 'Error loading row count' };
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<LoadingDataGridCore
|
||||
{...$$props}
|
||||
{loadDataPage}
|
||||
{dataPageAvailable}
|
||||
{loadRowCount}
|
||||
setLoadedRows={handleSetLoadedRows}
|
||||
onPublishedCellsChanged={value => {
|
||||
publishedCells = value;
|
||||
if (onPublishedCellsChanged) {
|
||||
onPublishedCellsChanged(value);
|
||||
}
|
||||
}}
|
||||
frameSelection={!!macroPreview}
|
||||
{grider}
|
||||
{display}
|
||||
onOpenQuery={openQuery}
|
||||
onOpenQueryOnError={openQueryOnError}
|
||||
/>
|
||||
|
||||
+1237
-1196
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@
|
||||
let isLoadedCount = false;
|
||||
let loadedTime = new Date().getTime();
|
||||
let allRowCount = null;
|
||||
let allRowCountError = null;
|
||||
let errorMessage = null;
|
||||
|
||||
const handleLoadCurrentRow = async () => {
|
||||
@@ -38,7 +39,14 @@
|
||||
|
||||
const handleLoadRowCount = async () => {
|
||||
isLoadingCount = true;
|
||||
allRowCount = await loadRowCountFunc();
|
||||
const result = await loadRowCountFunc();
|
||||
if (result != null && typeof result === 'object' && result.errorMessage) {
|
||||
allRowCount = null;
|
||||
allRowCountError = result.errorMessage;
|
||||
} else {
|
||||
allRowCount = result;
|
||||
allRowCountError = null;
|
||||
}
|
||||
isLoadedCount = true;
|
||||
isLoadingCount = false;
|
||||
};
|
||||
@@ -55,6 +63,7 @@
|
||||
rowData = null;
|
||||
loadedTime = new Date().getTime();
|
||||
allRowCount = null;
|
||||
allRowCountError = null;
|
||||
errorMessage = null;
|
||||
}
|
||||
|
||||
@@ -82,4 +91,4 @@
|
||||
$: if (onReferenceSourceChanged && rowData) onReferenceSourceChanged([rowData], loadedTime);
|
||||
</script>
|
||||
|
||||
<FormView {...$$props} {grider} isLoading={isLoadingData} {allRowCount} onNavigate={handleNavigate} />
|
||||
<FormView {...$$props} {grider} isLoading={isLoadingData} {allRowCount} {allRowCountError} onReloadRowCount={handleLoadRowCount} onNavigate={handleNavigate} />
|
||||
|
||||
@@ -1,35 +1,47 @@
|
||||
<script lang="ts" context="module">
|
||||
import { apiCall } from '../utility/api';
|
||||
async function loadRow(props, select) {
|
||||
const { conid, database } = props;
|
||||
|
||||
if (!select) return null;
|
||||
|
||||
const response = await apiCall('database-connections/sql-select', {
|
||||
conid,
|
||||
database,
|
||||
select,
|
||||
auditLogSessionGroup: 'data-form',
|
||||
});
|
||||
|
||||
if (response.errorMessage) return response;
|
||||
return response.rows[0];
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
import _ from 'lodash';
|
||||
import LoadingFormView from './LoadingFormView.svelte';
|
||||
|
||||
export let display;
|
||||
|
||||
async function handleLoadRow() {
|
||||
return await loadRow($$props, display.getPageQuery(display.config.formViewRecordNumber || 0, 1));
|
||||
}
|
||||
|
||||
async function handleLoadRowCount() {
|
||||
const countRow = await loadRow($$props, display.getCountQuery());
|
||||
return countRow ? parseInt(countRow.count) : null;
|
||||
}
|
||||
</script>
|
||||
|
||||
<LoadingFormView {...$$props} loadRowFunc={handleLoadRow} loadRowCountFunc={handleLoadRowCount} />
|
||||
async function loadRow(props, select, options = {}) {
|
||||
const { conid, database } = props;
|
||||
|
||||
if (!select) return null;
|
||||
|
||||
const response = await apiCall('database-connections/sql-select', {
|
||||
conid,
|
||||
database,
|
||||
select,
|
||||
auditLogSessionGroup: 'data-form',
|
||||
...options,
|
||||
});
|
||||
|
||||
if (response.errorMessage) return response;
|
||||
return response.rows[0];
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import _ from 'lodash';
|
||||
import LoadingFormView from './LoadingFormView.svelte';
|
||||
|
||||
export let display;
|
||||
|
||||
async function handleLoadRow() {
|
||||
return await loadRow($$props, display.getPageQuery(display.config.formViewRecordNumber || 0, 1));
|
||||
}
|
||||
|
||||
async function handleLoadRowCount() {
|
||||
const timeoutPromise = new Promise((_, reject) =>
|
||||
setTimeout(() => reject(new Error('Row count query timed out')), 3000)
|
||||
);
|
||||
try {
|
||||
const countRow = await Promise.race([
|
||||
loadRow($$props, display.getCountQuery(), { commandTimeout: 3000 }),
|
||||
timeoutPromise,
|
||||
]);
|
||||
return countRow ? parseInt(countRow.count) : null;
|
||||
} catch (err) {
|
||||
return { errorMessage: err.message || 'Error loading row count' };
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<LoadingFormView {...$$props} loadRowFunc={handleLoadRow} loadRowCountFunc={handleLoadRowCount} />
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
export let icon;
|
||||
export let title = null;
|
||||
export let padLeft = false;
|
||||
@@ -34,6 +36,7 @@
|
||||
export let colorClass = null;
|
||||
$: iconValue = typeof icon === 'string' ? icon : icon?.light || icon?.dark || '';
|
||||
$: isSvgString = iconValue.trim().startsWith('<svg');
|
||||
$: sanitizedSvg = isSvgString ? DOMPurify.sanitize(iconValue, { USE_PROFILES: { svg: true, svgFilters: true } }) : '';
|
||||
$: isTextIcon = iconValue.trim().startsWith('text ');
|
||||
|
||||
const iconNames = {
|
||||
@@ -379,7 +382,7 @@
|
||||
|
||||
{#if isSvgString}
|
||||
<span class="svg-inline" class:padLeft class:padRight {title} {style} on:click data-testid={$$props['data-testid']}>
|
||||
{@html iconValue}
|
||||
{@html sanitizedSvg}
|
||||
</span>
|
||||
{:else if isTextIcon}
|
||||
{@const textIconParts = iconValue.trim().split(' ')}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import LoadingInfo from '../elements/LoadingInfo.svelte';
|
||||
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
||||
import { addFilesToSourceList } from './ImportExportConfigurator.svelte';
|
||||
import getElectron from '../utility/getElectron';
|
||||
|
||||
let isLoading = false;
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
<script lang="ts">
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import FormSelectField from '../forms/FormSelectField.svelte';
|
||||
import FormPasswordField from '../forms/FormPasswordField.svelte';
|
||||
import { extensions, openedConnections, openedSingleDatabaseConnections } from '../stores';
|
||||
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
||||
import FormTextAreaField from '../forms/FormTextAreaField.svelte';
|
||||
import FormArgumentList from '../forms/FormArgumentList.svelte';
|
||||
import { _t } from '../translations';
|
||||
import { useConfig } from '../utility/metadataLoaders';
|
||||
|
||||
export let isFormReadOnly;
|
||||
|
||||
@@ -17,20 +20,81 @@
|
||||
$: isConnected = $openedConnections.includes($values._id) || $openedSingleDatabaseConnections.includes($values._id);
|
||||
|
||||
$: advancedFields = driver?.getAdvancedConnectionFields ? driver?.getAdvancedConnectionFields() : null;
|
||||
|
||||
$: config = useConfig();
|
||||
$: showConnectionFieldArgs = { config: $config };
|
||||
|
||||
$: showAllowedDatabases =
|
||||
driver?.showConnectionField?.('allowedDatabases', $values, showConnectionFieldArgs) === true;
|
||||
$: showProxy = driver?.showConnectionField?.('httpProxyUrl', $values, showConnectionFieldArgs) === true;
|
||||
</script>
|
||||
|
||||
<FormTextAreaField
|
||||
label={_t('connection.allowedDatabases', { defaultMessage: 'Allowed databases, one per line' })}
|
||||
name="allowedDatabases"
|
||||
disabled={isConnected || isFormReadOnly}
|
||||
rows={8}
|
||||
/>
|
||||
<FormTextField
|
||||
label={_t('connection.allowedDatabasesRegex', { defaultMessage: 'Allowed databases regular expression' })}
|
||||
name="allowedDatabasesRegex"
|
||||
disabled={isConnected || isFormReadOnly}
|
||||
/>
|
||||
{#if showAllowedDatabases}
|
||||
<FormTextAreaField
|
||||
label={_t('connection.allowedDatabases', { defaultMessage: 'Allowed databases, one per line' })}
|
||||
name="allowedDatabases"
|
||||
disabled={isConnected || isFormReadOnly}
|
||||
rows={8}
|
||||
/>
|
||||
<FormTextField
|
||||
label={_t('connection.allowedDatabasesRegex', { defaultMessage: 'Allowed databases regular expression' })}
|
||||
name="allowedDatabasesRegex"
|
||||
disabled={isConnected || isFormReadOnly}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if showProxy}
|
||||
<FormTextField
|
||||
label={_t('connection.httpProxyUrl', { defaultMessage: 'HTTP Proxy URL' })}
|
||||
name="httpProxyUrl"
|
||||
data-testid="ConnectionDriverFields_httpProxyUrl"
|
||||
placeholder="http://proxy.example.com:8080"
|
||||
disabled={isConnected || isFormReadOnly}
|
||||
/>
|
||||
<div class="row">
|
||||
<div class="col-6 mr-1">
|
||||
<FormTextField
|
||||
label={_t('connection.httpProxyUser', { defaultMessage: 'HTTP Proxy User' })}
|
||||
name="httpProxyUser"
|
||||
data-testid="ConnectionDriverFields_httpProxyUser"
|
||||
disabled={isConnected || isFormReadOnly}
|
||||
templateProps={{ noMargin: true }}
|
||||
/>
|
||||
</div>
|
||||
<div class="col-6 mr-1">
|
||||
<FormPasswordField
|
||||
label={_t('connection.httpProxyPassword', { defaultMessage: 'HTTP Proxy Password' })}
|
||||
name="httpProxyPassword"
|
||||
data-testid="ConnectionDriverFields_httpProxyPassword"
|
||||
disabled={isConnected || isFormReadOnly}
|
||||
templateProps={{ noMargin: true }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if driver?.showConnectionField('defaultIsolationLevel', $values, showConnectionFieldArgs) && driver?.isolationLevels}
|
||||
<FormSelectField
|
||||
label={_t('connection.defaultIsolationLevel', { defaultMessage: 'Default isolation level' })}
|
||||
isNative
|
||||
name="defaultIsolationLevel"
|
||||
defaultValue={driver.defaultIsolationLevel}
|
||||
options={driver.isolationLevels.map(level => ({ label: level, value: level }))}
|
||||
disabled={isConnected || isFormReadOnly}
|
||||
data-testid="ConnectionAdvancedDriverFields_defaultIsolationLevel"
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if advancedFields}
|
||||
<FormArgumentList args={advancedFields} isReadOnly={isFormReadOnly} />
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.row {
|
||||
margin: var(--dim-large-form-margin);
|
||||
display: flex;
|
||||
}
|
||||
.col-6 {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,7 +11,13 @@
|
||||
import FormSelectField from '../forms/FormSelectField.svelte';
|
||||
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import { extensions, getCurrentConfig, openedConnections, openedSingleDatabaseConnections, toggledDatabases } from '../stores';
|
||||
import {
|
||||
extensions,
|
||||
getCurrentConfig,
|
||||
openedConnections,
|
||||
openedSingleDatabaseConnections,
|
||||
toggledDatabases,
|
||||
} from '../stores';
|
||||
import getElectron from '../utility/getElectron';
|
||||
import { useAuthTypes, useConfig } from '../utility/metadataLoaders';
|
||||
import FormColorField from '../forms/FormColorField.svelte';
|
||||
@@ -100,7 +106,7 @@
|
||||
$extensions.drivers
|
||||
// .filter(driver => !driver.isElectronOnly || electron)
|
||||
.filter(driver => $toggledDatabases.get(driver.title))
|
||||
.map((driver) => ({
|
||||
.map(driver => ({
|
||||
value: driver.engine,
|
||||
label: driver.title,
|
||||
})),
|
||||
|
||||
@@ -68,6 +68,12 @@
|
||||
$: driver = $extensions.drivers.find(x => x.engine == engine);
|
||||
$: config = useConfig();
|
||||
|
||||
$: showConnectionFieldArgs = { config: $config };
|
||||
$: showAdvancedTab =
|
||||
driver?.showConnectionField?.('allowedDatabases', $values, showConnectionFieldArgs) === true ||
|
||||
driver?.showConnectionField?.('httpProxyUrl', $values, showConnectionFieldArgs) === true ||
|
||||
!!driver?.getAdvancedConnectionFields?.();
|
||||
|
||||
const testIdRef = createRef(0);
|
||||
|
||||
function handleTest(requestDbList = false) {
|
||||
@@ -97,7 +103,7 @@
|
||||
if (resp?.missingCredentials && resp?.detail?.redirectToDbLogin) {
|
||||
// Keep isTesting = true, wait for the event
|
||||
const eventName = `connection-test-result-${connection._id}`;
|
||||
const handleTestResult = (result) => {
|
||||
const handleTestResult = result => {
|
||||
if (testIdRef.get() != testid) {
|
||||
apiOff(eventName, handleTestResult);
|
||||
return;
|
||||
@@ -336,7 +342,7 @@
|
||||
props: { isFormReadOnly },
|
||||
testid: 'ConnectionTab_tabSsl',
|
||||
},
|
||||
{
|
||||
showAdvancedTab && {
|
||||
label: _t('common.advanced', { defaultMessage: 'Advanced' }),
|
||||
component: ConnectionAdvancedDriverFields,
|
||||
props: { isFormReadOnly },
|
||||
|
||||
@@ -2,173 +2,181 @@
|
||||
import { getActiveComponent } from '../utility/createActivator';
|
||||
import { registerFileCommands } from '../commands/stdCommands';
|
||||
import { __t } from '../translations';
|
||||
const getCurrentEditor = () => getActiveComponent('DiagramTab');
|
||||
|
||||
registerFileCommands({
|
||||
idPrefix: 'diagram',
|
||||
category: __t('command.diagram', { defaultMessage: 'Diagram' }),
|
||||
getCurrentEditor,
|
||||
folder: 'diagrams',
|
||||
format: 'json',
|
||||
fileExtension: 'diagram',
|
||||
defaultTeamFolder: true,
|
||||
|
||||
undoRedo: true,
|
||||
});
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import useEditorData from '../query/useEditorData';
import createUndoReducer from '../utility/createUndoReducer';
|
||||
import _ from 'lodash';
|
||||
import createActivator from '../utility/createActivator';
|
||||
import DiagramDesigner from '../designer/DiagramDesigner.svelte';
|
||||
import ToolStripContainer from '../buttons/ToolStripContainer.svelte';
|
||||
import ToolStripCommandButton from '../buttons/ToolStripCommandButton.svelte';
|
||||
import invalidateCommands from '../commands/invalidateCommands';
|
||||
import ToolStripSaveButton from '../buttons/ToolStripSaveButton.svelte';
|
||||
import HorizontalSplitter from '../elements/HorizontalSplitter.svelte';
|
||||
import WidgetColumnBar from '../widgets/WidgetColumnBar.svelte';
|
||||
import WidgetColumnBarItem from '../widgets/WidgetColumnBarItem.svelte';
|
||||
import WidgetsInnerContainer from '../widgets/WidgetsInnerContainer.svelte';
|
||||
import ToolStripButton from '../buttons/ToolStripButton.svelte';
|
||||
import DiagramSettings from '../designer/DiagramSettings.svelte';
|
||||
import { derived } from 'svelte/store';
|
||||
import { isProApp } from '../utility/proTools';
export let tabid;
|
||||
export let conid;
|
||||
export let database;
|
||||
|
||||
let tableCounts = {};
|
||||
|
||||
export const activator = createActivator('DiagramTab', true);
|
||||
|
||||
$: setEditorData($modelState.value);
|
||||
|
||||
export function getTabId() {
|
||||
return tabid;
|
||||
}
|
||||
|
||||
export function getData() {
|
||||
return $editorState.value || '';
|
||||
}
|
||||
|
||||
export function canUndo() {
|
||||
return $modelState.canUndo;
|
||||
}
|
||||
|
||||
export function undo() {
|
||||
dispatchModel({ type: 'undo' });
|
||||
invalidateCommands();
|
||||
}
|
||||
|
||||
export function canRedo() {
|
||||
return $modelState.canRedo;
|
||||
}
|
||||
|
||||
export function redo() {
|
||||
dispatchModel({ type: 'redo' });
|
||||
invalidateCommands();
|
||||
}
|
||||
|
||||
const handleChange = (value, skipUndoChain) => {
|
||||
// @ts-ignore
|
||||
dispatchModel({
|
||||
type: 'compute',
|
||||
useMerge: skipUndoChain,
|
||||
compute: v => (_.isFunction(value) ? value(v) : value),
|
||||
});
|
||||
invalidateCommands();
|
||||
};
|
||||
|
||||
const { editorState, editorValue, setEditorData } = useEditorData({
|
||||
tabid,
|
||||
onInitialData: value => {
|
||||
dispatchModel({ type: 'reset', value });
|
||||
invalidateCommands();
|
||||
},
|
||||
});
|
||||
|
||||
const [modelState, dispatchModel] = createUndoReducer({
|
||||
tables: [],
|
||||
references: [],
|
||||
});
|
||||
|
||||
const setStyle = style =>
|
||||
// @ts-ignore
|
||||
dispatchModel({
|
||||
type: 'compute',
|
||||
compute: v => ({ ...v, style: _.isFunction(style) ? style(v.style) : style }),
|
||||
});
|
||||
|
||||
const styleDerivedStore = derived(modelState, ($modelState: any) =>
|
||||
$modelState.value ? $modelState.value.style || {} : {}
|
||||
);
|
||||
const styleStore = {
|
||||
...styleDerivedStore,
|
||||
update: setStyle,
|
||||
set: setStyle,
|
||||
};
|
||||
|
||||
function createMenu() {
|
||||
return [
|
||||
{ command: 'diagram.save' },
|
||||
{ command: 'diagram.saveAs' },
|
||||
{ command: 'designer.arrange' },
|
||||
{ command: 'diagram.export' },
|
||||
{ divider: true },
|
||||
{ command: 'diagram.undo' },
|
||||
{ command: 'diagram.redo' },
|
||||
];
|
||||
}
|
||||
|
||||
function handleReportCounts(counts) {
|
||||
tableCounts = counts;
|
||||
}
|
||||
</script>
|
||||
|
||||
<ToolStripContainer>
|
||||
<HorizontalSplitter isSplitter={isProApp() ? ($styleStore.settingsVisible ?? true) : false} initialSizeRight={300}>
|
||||
<svelte:fragment slot="1">
|
||||
<DiagramDesigner
|
||||
value={$modelState.value || {}}
|
||||
{conid}
|
||||
{database}
|
||||
onChange={handleChange}
|
||||
menu={createMenu}
|
||||
columnFilter={$styleStore.columnFilter}
|
||||
onReportCounts={handleReportCounts}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="2">
|
||||
<WidgetColumnBar storageName="diagramSettingsWidget">
|
||||
<WidgetColumnBarItem
|
||||
title="Settings"
|
||||
name="diagramSettings"
|
||||
onClose={() => {
|
||||
styleStore.update(x => ({ ...x, settingsVisible: false }));
|
||||
}}
|
||||
>
|
||||
<WidgetsInnerContainer skipDefineWidth>
|
||||
<DiagramSettings values={styleStore} {tableCounts} />
|
||||
</WidgetsInnerContainer>
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
</svelte:fragment>
|
||||
</HorizontalSplitter>
|
||||
|
||||
<svelte:fragment slot="toolstrip">
|
||||
<ToolStripCommandButton command="designer.arrange" />
|
||||
<ToolStripSaveButton idPrefix="diagram" />
|
||||
<ToolStripCommandButton command="diagram.export" />
|
||||
<ToolStripCommandButton command="diagram.undo" />
|
||||
<ToolStripCommandButton command="diagram.redo" />
|
||||
<ToolStripCommandButton command="diagram.deleteSelectedTables" />
|
||||
{#if isProApp()}
|
||||
<ToolStripButton
|
||||
icon="icon settings"
|
||||
on:click={() => {
|
||||
styleStore.update(x => ({ ...x, settingsVisible: !x.settingsVisible }));
|
||||
}}>Settings</ToolStripButton
|
||||
>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</ToolStripContainer>
|
||||
const getCurrentEditor = () => getActiveComponent('DiagramTab');
|
||||
|
||||
registerFileCommands({
|
||||
idPrefix: 'diagram',
|
||||
category: __t('command.diagram', { defaultMessage: 'Diagram' }),
|
||||
getCurrentEditor,
|
||||
folder: 'diagrams',
|
||||
format: 'json',
|
||||
fileExtension: 'diagram',
|
||||
defaultTeamFolder: true,
|
||||
|
||||
undoRedo: true,
|
||||
});
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import useEditorData from '../query/useEditorData';
|
||||
import createUndoReducer from '../utility/createUndoReducer';
|
||||
import _ from 'lodash';
|
||||
import createActivator from '../utility/createActivator';
|
||||
import DiagramDesigner from '../designer/DiagramDesigner.svelte';
|
||||
import ToolStripContainer from '../buttons/ToolStripContainer.svelte';
|
||||
import ToolStripCommandButton from '../buttons/ToolStripCommandButton.svelte';
|
||||
import invalidateCommands from '../commands/invalidateCommands';
|
||||
import ToolStripSaveButton from '../buttons/ToolStripSaveButton.svelte';
|
||||
import HorizontalSplitter from '../elements/HorizontalSplitter.svelte';
|
||||
import WidgetColumnBar from '../widgets/WidgetColumnBar.svelte';
|
||||
import WidgetColumnBarItem from '../widgets/WidgetColumnBarItem.svelte';
|
||||
import WidgetsInnerContainer from '../widgets/WidgetsInnerContainer.svelte';
|
||||
import ToolStripButton from '../buttons/ToolStripButton.svelte';
|
||||
import ToolStripDropDownButton from '../buttons/ToolStripDropDownButton.svelte';
|
||||
import DiagramSettings from '../designer/DiagramSettings.svelte';
|
||||
import { derived } from 'svelte/store';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import { _t } from '../translations';
|
||||
export let tabid;
|
||||
export let conid;
|
||||
export let database;
|
||||
|
||||
let tableCounts = {};
|
||||
|
||||
export const activator = createActivator('DiagramTab', true);
|
||||
|
||||
$: setEditorData($modelState.value);
|
||||
|
||||
export function getTabId() {
|
||||
return tabid;
|
||||
}
|
||||
|
||||
export function getData() {
|
||||
return $editorState.value || '';
|
||||
}
|
||||
|
||||
export function canUndo() {
|
||||
return $modelState.canUndo;
|
||||
}
|
||||
|
||||
export function undo() {
|
||||
dispatchModel({ type: 'undo' });
|
||||
invalidateCommands();
|
||||
}
|
||||
|
||||
export function canRedo() {
|
||||
return $modelState.canRedo;
|
||||
}
|
||||
|
||||
export function redo() {
|
||||
dispatchModel({ type: 'redo' });
|
||||
invalidateCommands();
|
||||
}
|
||||
|
||||
const handleChange = (value, skipUndoChain) => {
|
||||
// @ts-ignore
|
||||
dispatchModel({
|
||||
type: 'compute',
|
||||
useMerge: skipUndoChain,
|
||||
compute: v => (_.isFunction(value) ? value(v) : value),
|
||||
});
|
||||
invalidateCommands();
|
||||
};
|
||||
|
||||
const { editorState, editorValue, setEditorData } = useEditorData({
|
||||
tabid,
|
||||
onInitialData: value => {
|
||||
dispatchModel({ type: 'reset', value });
|
||||
invalidateCommands();
|
||||
},
|
||||
});
|
||||
|
||||
const [modelState, dispatchModel] = createUndoReducer({
|
||||
tables: [],
|
||||
references: [],
|
||||
});
|
||||
|
||||
const setStyle = style =>
|
||||
// @ts-ignore
|
||||
dispatchModel({
|
||||
type: 'compute',
|
||||
compute: v => ({ ...v, style: _.isFunction(style) ? style(v.style) : style }),
|
||||
});
|
||||
|
||||
const styleDerivedStore = derived(modelState, ($modelState: any) =>
|
||||
$modelState.value ? $modelState.value.style || {} : {}
|
||||
);
|
||||
const styleStore = {
|
||||
...styleDerivedStore,
|
||||
update: setStyle,
|
||||
set: setStyle,
|
||||
};
|
||||
|
||||
function createMenu() {
|
||||
return [
|
||||
{ command: 'diagram.save' },
|
||||
{ command: 'diagram.saveAs' },
|
||||
{ command: 'designer.arrange' },
|
||||
{ command: 'diagram.export' },
|
||||
{ divider: true },
|
||||
{ command: 'diagram.undo' },
|
||||
{ command: 'diagram.redo' },
|
||||
];
|
||||
}
|
||||
|
||||
function handleReportCounts(counts) {
|
||||
tableCounts = counts;
|
||||
}
|
||||
</script>
|
||||
|
||||
<ToolStripContainer>
|
||||
<HorizontalSplitter isSplitter={isProApp() ? ($styleStore.settingsVisible ?? true) : false} initialSizeRight={300}>
|
||||
<svelte:fragment slot="1">
|
||||
<DiagramDesigner
|
||||
value={$modelState.value || {}}
|
||||
{conid}
|
||||
{database}
|
||||
onChange={handleChange}
|
||||
menu={createMenu}
|
||||
columnFilter={$styleStore.columnFilter}
|
||||
onReportCounts={handleReportCounts}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="2">
|
||||
<WidgetColumnBar storageName="diagramSettingsWidget">
|
||||
<WidgetColumnBarItem
|
||||
title="Settings"
|
||||
name="diagramSettings"
|
||||
onClose={() => {
|
||||
styleStore.update(x => ({ ...x, settingsVisible: false }));
|
||||
}}
|
||||
>
|
||||
<WidgetsInnerContainer skipDefineWidth>
|
||||
<DiagramSettings values={styleStore} {tableCounts} />
|
||||
</WidgetsInnerContainer>
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
</svelte:fragment>
|
||||
</HorizontalSplitter>
|
||||
|
||||
<svelte:fragment slot="toolstrip">
|
||||
<ToolStripCommandButton command="designer.arrange" />
|
||||
<ToolStripSaveButton idPrefix="diagram" />
|
||||
<ToolStripDropDownButton
|
||||
icon="icon report"
|
||||
label={_t('common.export', { defaultMessage: 'Export' })}
|
||||
menu={[{ command: 'diagram.export' }, { command: 'diagram.exportPng' }]}
|
||||
/>
|
||||
<ToolStripCommandButton command="diagram.undo" />
|
||||
<ToolStripCommandButton command="diagram.redo" />
|
||||
<ToolStripCommandButton command="diagram.deleteSelectedTables" />
|
||||
{#if isProApp()}
|
||||
<ToolStripButton
|
||||
icon="icon settings"
|
||||
on:click={() => {
|
||||
styleStore.update(x => ({ ...x, settingsVisible: !x.settingsVisible }));
|
||||
}}>Settings</ToolStripButton
|
||||
>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
</ToolStripContainer>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,11 @@
|
||||
import _ from 'lodash';
|
||||
import { currentDatabase, openedConnectionsWithTemporary, getCurrentConfig, getOpenedConnections } from '../stores';
|
||||
import {
|
||||
currentDatabase,
|
||||
openedConnectionsWithTemporary,
|
||||
getCurrentConfig,
|
||||
getOpenedConnections,
|
||||
getOpenedTabs,
|
||||
} from '../stores';
|
||||
import { apiCall, getVolatileConnections, strmid } from './api';
|
||||
import hasPermission from '../utility/hasPermission';
|
||||
import { getConfig } from './metadataLoaders';
|
||||
@@ -37,9 +43,29 @@ const doDatabasePing = value => {
|
||||
}
|
||||
};
|
||||
|
||||
function pingAllOpenedDatabases() {
|
||||
const tabs = getOpenedTabs() || [];
|
||||
const allDbs = tabs
|
||||
.filter(tab => !tab.closedTime && tab.props?.conid && tab.props?.database)
|
||||
.map(tab => ({ conid: tab.props.conid as string, database: tab.props.database as string }));
|
||||
const seen = new Set<string>();
|
||||
const databases: { conid: string; database: string }[] = [];
|
||||
for (const db of allDbs) {
|
||||
const key = `${db.conid}/${db.database}`;
|
||||
if (!seen.has(key)) {
|
||||
seen.add(key);
|
||||
databases.push(db);
|
||||
}
|
||||
}
|
||||
if (databases.length > 0) {
|
||||
apiCall('database-connections/ping-databases', { databases });
|
||||
}
|
||||
}
|
||||
|
||||
let openedConnectionsHandle = null;
|
||||
|
||||
let currentDatabaseHandle = null;
|
||||
let allDatabasesHandle = null;
|
||||
|
||||
export function subscribeConnectionPingers() {
|
||||
openedConnectionsWithTemporary.subscribe(value => {
|
||||
@@ -53,6 +79,11 @@ export function subscribeConnectionPingers() {
|
||||
if (currentDatabaseHandle) window.clearInterval(currentDatabaseHandle);
|
||||
currentDatabaseHandle = window.setInterval(() => doDatabasePing(value), 20 * 1000);
|
||||
});
|
||||
|
||||
// Ping all databases that have open (non-closed) tabs, not just the current one
|
||||
pingAllOpenedDatabases();
|
||||
if (allDatabasesHandle) window.clearInterval(allDatabasesHandle);
|
||||
allDatabasesHandle = window.setInterval(() => pingAllOpenedDatabases(), 20 * 1000);
|
||||
}
|
||||
|
||||
export function callServerPing() {
|
||||
|
||||
@@ -2,6 +2,7 @@ import _ from 'lodash';
|
||||
import { isFileDragActive } from '../stores';
|
||||
import { fromEvent } from 'file-selector';
|
||||
import uploadFiles from './uploadFiles';
|
||||
import getElectron from './getElectron';
|
||||
|
||||
function isEvtWithFiles(event) {
|
||||
if (!event.dataTransfer) {
|
||||
@@ -65,8 +66,22 @@ export default function dragDropFileTarget(node, items) {
|
||||
isFileDragActive.set(false);
|
||||
|
||||
if (isEvtWithFiles(event)) {
|
||||
const files = await fromEvent(event);
|
||||
uploadFiles(files);
|
||||
const electron = getElectron();
|
||||
if (electron && event.dataTransfer?.files?.length) {
|
||||
// Electron 37+ removed File.path in favour of webUtils.getPathForFile().
|
||||
// Older Electron sets file.path automatically; newer requires webUtils.
|
||||
const electronModule = window['require']('electron');
|
||||
const files = Array.from(event.dataTransfer.files).map((file: any) => {
|
||||
if (!file.path && electronModule?.webUtils) {
|
||||
file.path = electronModule.webUtils.getPathForFile(file);
|
||||
}
|
||||
return file;
|
||||
});
|
||||
uploadFiles(files);
|
||||
} else {
|
||||
const files = await fromEvent(event);
|
||||
uploadFiles(files);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
unsubscribeCachePeek,
|
||||
} from './cache';
|
||||
import stableStringify from 'json-stable-stringify';
|
||||
import { derived } from 'svelte/store';
|
||||
import { derived, writable } from 'svelte/store';
|
||||
import { extendDatabaseInfo } from 'dbgate-tools';
|
||||
import { setLocalStorage } from '../utility/storageCache';
|
||||
import { apiCall, apiOff, apiOn } from './api';
|
||||
@@ -171,15 +171,17 @@ const installedPluginsLoader = () => ({
|
||||
reloadTrigger: { key: `installed-plugins-changed` },
|
||||
});
|
||||
|
||||
const filesLoader = ({ folder }) => ({
|
||||
const filesLoader = ({ folder, parseFrontMatter = false }) => ({
|
||||
url: 'files/list',
|
||||
params: { folder },
|
||||
params: parseFrontMatter ? { folder, parseFrontMatter: true } : { folder },
|
||||
reloadTrigger: { key: `files-changed`, folder },
|
||||
errorValue: [],
|
||||
});
|
||||
const allFilesLoader = () => ({
|
||||
url: 'files/list-all',
|
||||
params: {},
|
||||
reloadTrigger: { key: `all-files-changed` },
|
||||
errorValue: [],
|
||||
});
|
||||
const authTypesLoader = ({ engine }) => ({
|
||||
url: 'plugins/auth-types',
|
||||
@@ -188,25 +190,34 @@ const authTypesLoader = ({ engine }) => ({
|
||||
errorValue: null,
|
||||
});
|
||||
|
||||
const publicCloudErrorStore = writable(false);
|
||||
const cloudContentErrorStore = writable(false);
|
||||
|
||||
const publicCloudFilesLoader = () => ({
|
||||
url: 'cloud/public-files',
|
||||
params: {},
|
||||
reloadTrigger: { key: `public-cloud-changed` },
|
||||
errorValue: [],
|
||||
onError: err => publicCloudErrorStore.set(!!err),
|
||||
});
|
||||
const cloudContentListLoader = () => ({
|
||||
url: 'cloud/content-list',
|
||||
params: {},
|
||||
reloadTrigger: { key: `cloud-content-changed` },
|
||||
errorValue: [],
|
||||
onError: err => cloudContentErrorStore.set(!!err),
|
||||
});
|
||||
const teamFilesLoader = () => ({
|
||||
url: 'team-files/list',
|
||||
params: {},
|
||||
reloadTrigger: { key: `team-files-changed` },
|
||||
errorValue: [],
|
||||
});
|
||||
const teamFoldersLoader = () => ({
|
||||
url: 'team-files/list-folders',
|
||||
params: {},
|
||||
reloadTrigger: { key: `team-folders-changed` },
|
||||
errorValue: [],
|
||||
});
|
||||
const promoWidgetLoader = () => ({
|
||||
url: 'cloud/premium-promo-widget',
|
||||
@@ -220,15 +231,17 @@ const fileThemesLoader = () => ({
|
||||
});
|
||||
|
||||
async function getCore(loader, args) {
|
||||
const { url, params, reloadTrigger, transform, onLoaded, errorValue } = loader(args);
|
||||
const { url, params, reloadTrigger, transform, onLoaded, onError, errorValue } = loader(args);
|
||||
const key = stableStringify({ url, ...params });
|
||||
|
||||
async function doLoad() {
|
||||
const resp = await apiCall(url, params);
|
||||
if (resp?.errorMessage && errorValue !== undefined) {
|
||||
if (onError) onError(resp.errorMessage);
|
||||
if (onLoaded) onLoaded(errorValue);
|
||||
return errorValue;
|
||||
}
|
||||
if (onError) onError(null);
|
||||
const res = (transform || (x => x))(resp);
|
||||
if (onLoaded) onLoaded(res);
|
||||
return res;
|
||||
@@ -551,6 +564,9 @@ export function getPublicCloudFiles(args) {
|
||||
export function usePublicCloudFiles(args = {}) {
|
||||
return useCore(publicCloudFilesLoader, args);
|
||||
}
|
||||
export function usePublicCloudError() {
|
||||
return publicCloudErrorStore;
|
||||
}
|
||||
|
||||
export function getCloudContentList(args) {
|
||||
return getCore(cloudContentListLoader, args);
|
||||
@@ -558,6 +574,9 @@ export function getCloudContentList(args) {
|
||||
export function useCloudContentList(args = {}) {
|
||||
return useCore(cloudContentListLoader, args);
|
||||
}
|
||||
export function useCloudContentError() {
|
||||
return cloudContentErrorStore;
|
||||
}
|
||||
|
||||
export function getTeamFiles(args) {
|
||||
return getCore(teamFilesLoader, args);
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
|
||||
import AppObjectList from '../appobj/AppObjectList.svelte';
|
||||
import * as cloudContentAppObject from '../appobj/CloudContentAppObject.svelte';
|
||||
import { useCloudContentList, usePublicCloudFiles, useServerStatus } from '../utility/metadataLoaders';
|
||||
import {
|
||||
useCloudContentList,
|
||||
usePublicCloudFiles,
|
||||
useServerStatus,
|
||||
useCloudContentError,
|
||||
} from '../utility/metadataLoaders';
|
||||
import { _t } from '../translations';
|
||||
|
||||
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
||||
@@ -47,6 +52,7 @@
|
||||
|
||||
const cloudContentList = useCloudContentList();
|
||||
const serverStatus = useServerStatus();
|
||||
const cloudContentError = useCloudContentError();
|
||||
const cloudContentColorFactory = useCloudContentColorFactory();
|
||||
const connectionColorFactory = useConnectionColorFactory();
|
||||
|
||||
@@ -259,16 +265,19 @@
|
||||
icon="icon plus-thick"
|
||||
menu={createAddItemMenu}
|
||||
title={_t('privateCloudWidget.addNewConnectionOrFile', { defaultMessage: 'Add new connection or file' })}
|
||||
disabled={$cloudContentError}
|
||||
/>
|
||||
<DropDownButton
|
||||
icon="icon add-folder"
|
||||
menu={createAddFolderMenu}
|
||||
title={_t('privateCloudWidget.addNewFolder', { defaultMessage: 'Add new folder' })}
|
||||
disabled={$cloudContentError}
|
||||
/>
|
||||
<InlineButton
|
||||
on:click={handleRefreshContent}
|
||||
title={_t('privateCloudWidget.refreshFiles', { defaultMessage: 'Refresh files' })}
|
||||
data-testid="CloudItemsWidget_buttonRefreshContent"
|
||||
disabled={$cloudContentError}
|
||||
>
|
||||
<FontIcon icon="icon refresh" />
|
||||
</InlineButton>
|
||||
@@ -300,7 +309,14 @@
|
||||
groupContextMenu={createGroupContextMenu}
|
||||
/>
|
||||
|
||||
{#if !cloudContentFlat?.length}
|
||||
{#if $cloudContentError}
|
||||
<ErrorInfo
|
||||
message={_t('privateCloudWidget.cloudUnavailable', {
|
||||
defaultMessage: 'DbGate Cloud is temporarily unavailable',
|
||||
})}
|
||||
icon="img warn"
|
||||
/>
|
||||
{:else if !cloudContentFlat?.length}
|
||||
<ErrorInfo
|
||||
message={_t('privateCloudWidget.noContent', { defaultMessage: 'You have no content on DbGate cloud' })}
|
||||
icon="img info"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import AppObjectList from '../appobj/AppObjectList.svelte';
|
||||
import * as publicCloudFileAppObject from '../appobj/PublicCloudFileAppObject.svelte';
|
||||
import { usePublicCloudFiles } from '../utility/metadataLoaders';
|
||||
import { usePublicCloudFiles, usePublicCloudError } from '../utility/metadataLoaders';
|
||||
import { _t } from '../translations';
|
||||
|
||||
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
||||
@@ -20,6 +20,7 @@
|
||||
let filter = '';
|
||||
|
||||
const publicFiles = usePublicCloudFiles();
|
||||
const publicCloudError = usePublicCloudError();
|
||||
|
||||
function handleRefreshPublic() {
|
||||
refreshPublicCloudFiles(true);
|
||||
@@ -42,6 +43,7 @@
|
||||
on:click={handleRefreshPublic}
|
||||
title={_t('publicCloudWidget.refreshFiles', { defaultMessage: 'Refresh files' })}
|
||||
data-testid="CloudItemsWidget_buttonRefreshPublic"
|
||||
disabled={$publicCloudError}
|
||||
>
|
||||
<FontIcon icon="icon refresh" />
|
||||
</InlineButton>
|
||||
@@ -54,7 +56,14 @@
|
||||
{filter}
|
||||
/>
|
||||
|
||||
{#if !$publicFiles?.length}
|
||||
{#if $publicCloudError}
|
||||
<ErrorInfo
|
||||
message={_t('publicCloudWidget.cloudUnavailable', {
|
||||
defaultMessage: 'DbGate Cloud is temporarily unavailable',
|
||||
})}
|
||||
icon="img warn"
|
||||
/>
|
||||
{:else if !$publicFiles?.length}
|
||||
<ErrorInfo
|
||||
message={_t('publicCloudWidget.noFilesFound', { defaultMessage: 'No files found for your configuration' })}
|
||||
/>
|
||||
|
||||
@@ -8,16 +8,20 @@
|
||||
import SearchInput from '../elements/SearchInput.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { useFiles, useTeamFiles } from '../utility/metadataLoaders';
|
||||
import { useFiles, useTeamFiles, useConnectionList, useCloudContentList } from '../utility/metadataLoaders';
|
||||
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import InlineUploadButton from '../buttons/InlineUploadButton.svelte';
|
||||
import { DATA_FOLDER_NAMES } from 'dbgate-tools';
|
||||
import { DATA_FOLDER_NAMES, getConnectionLabel } from 'dbgate-tools';
|
||||
import { _t } from '../translations';
|
||||
import { currentDatabase } from '../stores';
|
||||
|
||||
let filter = '';
|
||||
let selectedConnectionId = '';
|
||||
|
||||
const sqlFiles = useFiles({ folder: 'sql' });
|
||||
const connectionList = useConnectionList();
|
||||
const cloudContentList = useCloudContentList();
|
||||
const sqlFiles = useFiles({ folder: 'sql', parseFrontMatter: true });
|
||||
const shellFiles = useFiles({ folder: 'shell' });
|
||||
const markdownFiles = useFiles({ folder: 'markdown' });
|
||||
const chartFiles = useFiles({ folder: 'charts' });
|
||||
@@ -33,22 +37,105 @@
|
||||
const appFiles = useFiles({ folder: 'apps' });
|
||||
const teamFiles = useTeamFiles({});
|
||||
|
||||
function makeConnectionKey(connectionId: string, databaseName: string | undefined) {
|
||||
return databaseName ? `${connectionId}::${databaseName}` : connectionId;
|
||||
}
|
||||
|
||||
$: cloudIdToLabel = _.fromPairs(
|
||||
(($cloudContentList || []) as any[])
|
||||
.flatMap(fld => fld.items ?? [])
|
||||
.filter(item => item.type === 'connection' && item.folid && item.cntid)
|
||||
.map(item => [`cloud://${item.folid}/${item.cntid}`, item.name as string])
|
||||
);
|
||||
|
||||
$: connectionDbOptions = _.uniqBy(
|
||||
(($sqlFiles || []) as any[])
|
||||
.filter(f => f.connectionId)
|
||||
.map(f => {
|
||||
const conn = (($connectionList || []) as any[]).find(c => c._id === f.connectionId);
|
||||
const connLabel = (conn && getConnectionLabel(conn)) || cloudIdToLabel[f.connectionId] || f.connectionId;
|
||||
const label = f.databaseName ? `${connLabel} - ${f.databaseName}` : connLabel;
|
||||
return {
|
||||
value: makeConnectionKey(f.connectionId, f.databaseName),
|
||||
label: label as string,
|
||||
connectionId: f.connectionId,
|
||||
databaseName: f.databaseName,
|
||||
};
|
||||
}),
|
||||
x => x.value
|
||||
);
|
||||
|
||||
$: connectionOptions = (() => {
|
||||
const grouped = _.groupBy(connectionDbOptions, o => o.connectionId);
|
||||
const connectionGroups = Object.entries(grouped)
|
||||
.map(([connId, items]) => {
|
||||
const conn = (($connectionList || []) as any[]).find(c => c._id === connId);
|
||||
const connLabel = (conn && getConnectionLabel(conn)) || cloudIdToLabel[connId] || connId;
|
||||
const hasMultipleDbs = items.length > 1 || items.some(i => i.databaseName);
|
||||
const dbItems = [...items].sort((a, b) => (a.databaseName || '').localeCompare(b.databaseName || ''));
|
||||
|
||||
return {
|
||||
sortLabel: connLabel || connId,
|
||||
options: [
|
||||
...(hasMultipleDbs
|
||||
? [
|
||||
{
|
||||
value: `conn-all::${connId}`,
|
||||
label: `${connLabel} - ${_t('files.allDatabases', { defaultMessage: 'all databases' })}`,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...dbItems,
|
||||
],
|
||||
};
|
||||
})
|
||||
.sort((a, b) => a.sortLabel.localeCompare(b.sortLabel));
|
||||
|
||||
return connectionGroups.flatMap(group => group.options);
|
||||
})();
|
||||
|
||||
$: currentDbFilterOption = (() => {
|
||||
if (!$currentDatabase?.connection?._id) return null;
|
||||
const connId = $currentDatabase.connection._id;
|
||||
const dbName = $currentDatabase.name;
|
||||
const hasFiles = (($sqlFiles || []) as any[]).some(f => f.connectionId === connId && f.databaseName === dbName);
|
||||
if (!hasFiles) return null;
|
||||
const conn = (($connectionList || []) as any[]).find(c => c._id === connId);
|
||||
const connLabel = (conn && getConnectionLabel(conn)) || cloudIdToLabel[connId] || connId;
|
||||
const label = dbName ? `${connLabel} - ${dbName}` : connLabel;
|
||||
return { value: `current-db`, label };
|
||||
})();
|
||||
|
||||
$: filteredSqlFiles = (() => {
|
||||
if (!selectedConnectionId) return $sqlFiles || [];
|
||||
if (selectedConnectionId === 'current-db') {
|
||||
const connId = $currentDatabase?.connection?._id;
|
||||
const dbName = $currentDatabase?.name;
|
||||
return ($sqlFiles || []).filter(f => f.connectionId === connId && f.databaseName === dbName);
|
||||
}
|
||||
if (selectedConnectionId.startsWith('conn-all::')) {
|
||||
const connId = selectedConnectionId.slice('conn-all::'.length);
|
||||
return ($sqlFiles || []).filter(f => f.connectionId === connId);
|
||||
}
|
||||
return ($sqlFiles || []).filter(f => makeConnectionKey(f.connectionId, f.databaseName) === selectedConnectionId);
|
||||
})();
|
||||
|
||||
$: files = [
|
||||
...($sqlFiles || []),
|
||||
...($shellFiles || []),
|
||||
...($markdownFiles || []),
|
||||
...($chartFiles || []),
|
||||
...($queryFiles || []),
|
||||
...($sqliteFiles || []),
|
||||
...($diagramFiles || []),
|
||||
...($perspectiveFiles || []),
|
||||
...($importExportJobFiles || []),
|
||||
...($modelTransformFiles || []),
|
||||
...($themeFiles || []),
|
||||
...((isProApp() && $dataDeployJobFiles) || []),
|
||||
...((isProApp() && $dbCompareJobFiles) || []),
|
||||
...((isProApp() && $appFiles) || []),
|
||||
...($teamFiles || []),
|
||||
...filteredSqlFiles,
|
||||
...(selectedConnectionId ? [] : $shellFiles || []),
|
||||
...(selectedConnectionId ? [] : $markdownFiles || []),
|
||||
...(selectedConnectionId ? [] : $chartFiles || []),
|
||||
...(selectedConnectionId ? [] : $queryFiles || []),
|
||||
...(selectedConnectionId ? [] : $sqliteFiles || []),
|
||||
...(selectedConnectionId ? [] : $diagramFiles || []),
|
||||
...(selectedConnectionId ? [] : $perspectiveFiles || []),
|
||||
...(selectedConnectionId ? [] : $importExportJobFiles || []),
|
||||
...(selectedConnectionId ? [] : $modelTransformFiles || []),
|
||||
...(selectedConnectionId ? [] : $themeFiles || []),
|
||||
...((isProApp() && !selectedConnectionId && $dataDeployJobFiles) || []),
|
||||
...((isProApp() && !selectedConnectionId && $dbCompareJobFiles) || []),
|
||||
...((isProApp() && !selectedConnectionId && $appFiles) || []),
|
||||
...(selectedConnectionId ? [] : $teamFiles || []),
|
||||
];
|
||||
|
||||
function handleRefreshFiles() {
|
||||
@@ -92,6 +179,41 @@
|
||||
</InlineButton>
|
||||
</SearchBoxWrapper>
|
||||
|
||||
{#if connectionOptions.length > 0}
|
||||
<div class="connection-filter">
|
||||
<div class="mr-1">{_t('files.connection', { defaultMessage: 'Connection' })}:</div>
|
||||
<select
|
||||
class="connection-select"
|
||||
value={selectedConnectionId}
|
||||
on:change={e => {
|
||||
selectedConnectionId = e.currentTarget.value;
|
||||
}}
|
||||
data-testid="SavedFilesList_connectionFilter"
|
||||
>
|
||||
<option value="">{_t('files.allConnections', { defaultMessage: 'All connections' })}</option>
|
||||
{#if currentDbFilterOption}
|
||||
<option value="current-db"
|
||||
>{_t('files.currentDatabase', { defaultMessage: 'Current database' })}: {currentDbFilterOption.label}</option
|
||||
>
|
||||
{/if}
|
||||
{#each connectionOptions as opt}
|
||||
<option value={opt.value}>{opt.label}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{#if selectedConnectionId}
|
||||
<InlineButton
|
||||
on:click={() => {
|
||||
selectedConnectionId = '';
|
||||
}}
|
||||
title={_t('files.clearConnectionFilter', { defaultMessage: 'Clear connection filter' })}
|
||||
data-testid="SavedFilesList_clearConnectionFilter"
|
||||
>
|
||||
<FontIcon icon="icon close" />
|
||||
</InlineButton>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<WidgetsInnerContainer>
|
||||
<AppObjectList
|
||||
list={files}
|
||||
@@ -103,3 +225,29 @@
|
||||
{filter}
|
||||
/>
|
||||
</WidgetsInnerContainer>
|
||||
|
||||
<style>
|
||||
.connection-filter {
|
||||
display: flex;
|
||||
border-bottom: var(--theme-card-border);
|
||||
margin-bottom: 5px;
|
||||
align-items: center;
|
||||
padding-left: 5px;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.connection-select {
|
||||
flex: 1 1 0%;
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
height: 24px;
|
||||
background-color: var(--theme-searchbox-background);
|
||||
border: var(--theme-searchbox-border);
|
||||
box-shadow: none;
|
||||
cursor: pointer;
|
||||
color: var(--theme-font-1);
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
margin-right: 4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -310,7 +310,7 @@
|
||||
data-testid="SqlObjectList_searchMenuDropDown"
|
||||
/>
|
||||
{#if !filter}
|
||||
<DropDownButton icon="icon plus-thick" menu={createAddMenu} />
|
||||
<DropDownButton icon="icon plus-thick" menu={createAddMenu} data-testid="SqlObjectList_addButton" />
|
||||
{/if}
|
||||
<DropDownButton
|
||||
menu={createRefreshDatabaseMenu}
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
</div>
|
||||
<div class="container">
|
||||
{#each contextItems || [] as item}
|
||||
<div class="item" class:clickable={item.clickable} on:click={item.onClick}>
|
||||
<div class="item" class:clickable={item.clickable} on:click={item.onClick} title={item.title || null}>
|
||||
{#if item.icon}
|
||||
<FontIcon icon={item.icon} padRight />
|
||||
{/if}
|
||||
|
||||
@@ -8,14 +8,15 @@
|
||||
export let clickable = false;
|
||||
export let icon = null;
|
||||
export let onClick = null;
|
||||
export let title = null;
|
||||
|
||||
const key = uuidv1();
|
||||
const tabid = getContext('tabid');
|
||||
|
||||
onMount(() => {
|
||||
updateStatuBarInfoItem(tabid, key, { text, icon, clickable, onClick });
|
||||
updateStatuBarInfoItem(tabid, key, { text, icon, clickable, onClick, title });
|
||||
});
|
||||
onDestroy(() => updateStatuBarInfoItem(tabid, key, null));
|
||||
|
||||
$: updateStatuBarInfoItem(tabid, key, { text, icon, clickable, onClick });
|
||||
$: updateStatuBarInfoItem(tabid, key, { text, icon, clickable, onClick, title });
|
||||
</script>
|
||||
|
||||
@@ -71,14 +71,19 @@ const driver = {
|
||||
// called for retrieve data (eg. browse in data grid) and for update database
|
||||
async query(dbhan, query, options) {
|
||||
const offset = options?.range?.offset;
|
||||
const commandTimeout = options?.commandTimeout;
|
||||
const executeOptions = {};
|
||||
if (commandTimeout) {
|
||||
executeOptions.readTimeout = parseInt(commandTimeout);
|
||||
}
|
||||
if (options?.discardResult) {
|
||||
await dbhan.client.execute(query);
|
||||
await dbhan.client.execute(query, [], executeOptions);
|
||||
return {
|
||||
rows: [],
|
||||
columns: [],
|
||||
};
|
||||
}
|
||||
const result = await dbhan.client.execute(query);
|
||||
const result = await dbhan.client.execute(query, [], executeOptions);
|
||||
if (!result.rows?.[0]) {
|
||||
return {
|
||||
rows: [],
|
||||
|
||||
@@ -89,7 +89,7 @@ const driver = {
|
||||
title: 'Cassandra',
|
||||
icon: cassandraIcon,
|
||||
showConnectionField: (field, values) =>
|
||||
['server', 'singleDatabase', 'localDataCenter', 'isReadOnly', 'user', 'password'].includes(field),
|
||||
['server', 'singleDatabase', 'localDataCenter', 'isReadOnly', 'user', 'password', 'allowedDatabases', 'allowedDatabasesRegex'].includes(field),
|
||||
getQuerySplitterOptions: (usage) =>
|
||||
usage == 'editor'
|
||||
? { ...mysqlSplitterOptions, ignoreComments: true, preventSingleLineSplit: true }
|
||||
|
||||
@@ -25,6 +25,7 @@ const driver = {
|
||||
},
|
||||
// called for retrieve data (eg. browse in data grid) and for update database
|
||||
async query(dbhan, query, options) {
|
||||
const commandTimeout = options?.commandTimeout;
|
||||
if (options?.discardResult) {
|
||||
await dbhan.client.command({
|
||||
query,
|
||||
@@ -34,10 +35,14 @@ const driver = {
|
||||
columns: [],
|
||||
};
|
||||
} else {
|
||||
const resultSet = await dbhan.client.query({
|
||||
const queryOptions = {
|
||||
query,
|
||||
format: 'JSONCompactEachRowWithNamesAndTypes',
|
||||
});
|
||||
};
|
||||
if (commandTimeout) {
|
||||
queryOptions.settings = { max_execution_time: Math.ceil(parseInt(commandTimeout) / 1000) };
|
||||
}
|
||||
const resultSet = await dbhan.client.query(queryOptions);
|
||||
|
||||
const dataSet = await resultSet.json();
|
||||
if (!dataSet?.[0]) {
|
||||
|
||||
@@ -152,7 +152,7 @@ const driver = {
|
||||
supportsIncrementalAnalysis: true,
|
||||
icon: clickhouseIcon,
|
||||
showConnectionField: (field, values) => {
|
||||
return ['databaseUrl', 'defaultDatabase', 'singleDatabase', 'isReadOnly', 'user', 'password'].includes(field);
|
||||
return ['databaseUrl', 'defaultDatabase', 'singleDatabase', 'isReadOnly', 'user', 'password', 'allowedDatabases', 'allowedDatabasesRegex'].includes(field);
|
||||
},
|
||||
getQuerySplitterOptions: (usage) =>
|
||||
usage == 'editor'
|
||||
|
||||
@@ -40,6 +40,6 @@
|
||||
"dbgate-query-splitter": "^4.12.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@duckdb/node-api": "^1.2.1-alpha.16"
|
||||
"@duckdb/node-api": "^1.5.0-r.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,11 +48,12 @@ const driver = {
|
||||
|
||||
return {
|
||||
client: connection,
|
||||
instance,
|
||||
};
|
||||
},
|
||||
async close(dbhan) {
|
||||
dbhan.client.disconnect();
|
||||
dbhan.client.close();
|
||||
dbhan.client.disconnectSync();
|
||||
dbhan.instance.closeSync();
|
||||
},
|
||||
async query(dbhan, sql, { readonly } = {}) {
|
||||
const res = await dbhan.client.runAndReadAll(sql);
|
||||
|
||||
@@ -15,7 +15,7 @@ const {
|
||||
function getColumnsInfo(columnNames, columnTypes) {
|
||||
const columns = [];
|
||||
|
||||
for (let i = columnNames.length - 1; i >= 0; i--) {
|
||||
for (let i = 0; i < columnNames.length; i++) {
|
||||
columns.push({
|
||||
columnName: columnNames[i],
|
||||
dataType: columnTypes[i].toString(),
|
||||
|
||||
@@ -6,7 +6,7 @@ const Analyser = require('./Analyser');
|
||||
const isPromise = require('is-promise');
|
||||
const mongodb = require('mongodb');
|
||||
const { ObjectId } = require('mongodb');
|
||||
const { EJSON } = require('bson');
|
||||
const { EJSON, Binary } = require('bson');
|
||||
const { serializeJsTypesForJsonStringify, deserializeJsTypesFromJsonParse, getLogger } = require('dbgate-tools');
|
||||
const createBulkInsertStream = require('./createBulkInsertStream');
|
||||
const {
|
||||
@@ -53,8 +53,18 @@ function findArrayResult(resValue) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function BinData(_subType, base64) {
|
||||
return Buffer.from(base64, 'base64');
|
||||
function BinData(subType, base64) {
|
||||
let numericSubType;
|
||||
if (typeof subType === 'string') {
|
||||
const hex = subType.startsWith('0x') || subType.startsWith('0X') ? subType.slice(2) : subType;
|
||||
numericSubType = parseInt(hex, 16);
|
||||
} else {
|
||||
numericSubType = subType;
|
||||
}
|
||||
if (!Number.isInteger(numericSubType) || numericSubType < 0 || numericSubType > 255) {
|
||||
throw new TypeError(`BinData subType must be an integer between 0 and 255, got: ${subType}`);
|
||||
}
|
||||
return new Binary(Buffer.from(base64, 'base64'), numericSubType);
|
||||
}
|
||||
|
||||
async function getScriptableDb(dbhan) {
|
||||
@@ -487,7 +497,11 @@ const drivers = driverBases.map((driverBase) => ({
|
||||
|
||||
const collection = dbhan.getDatabase().collection(options.pureName);
|
||||
if (options.countDocuments) {
|
||||
const count = await collection.countDocuments(deserializeMongoData(mongoCondition) || {});
|
||||
const countOptions = {};
|
||||
if (options.commandTimeout) {
|
||||
countOptions.maxTimeMS = parseInt(options.commandTimeout);
|
||||
}
|
||||
const count = await collection.countDocuments(deserializeMongoData(mongoCondition) || {}, countOptions);
|
||||
return { count };
|
||||
} else if (options.aggregate) {
|
||||
let cursor = await collection.aggregate(deserializeMongoData(convertToMongoAggregate(options.aggregate)));
|
||||
|
||||
@@ -74,6 +74,7 @@ const mongoDriverBase = {
|
||||
|
||||
showConnectionField: (field, values) => {
|
||||
if (field == 'useDatabaseUrl') return true;
|
||||
if (field == 'allowedDatabases' || field == 'allowedDatabasesRegex') return true;
|
||||
if (values.useDatabaseUrl) {
|
||||
return ['databaseUrl', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field);
|
||||
}
|
||||
|
||||
@@ -93,12 +93,16 @@ const driver = {
|
||||
platformInfo?.isWindows && (authType == 'sspi' || authType == 'sql') ? 'msnodesqlv8' : 'tedious';
|
||||
const client = connectionType == 'msnodesqlv8' ? await nativeConnect(conn) : await tediousConnect(conn);
|
||||
|
||||
return {
|
||||
const dbhan = {
|
||||
client,
|
||||
connectionType,
|
||||
database: conn.database,
|
||||
conid: conn.conid,
|
||||
};
|
||||
if (conn.defaultIsolationLevel) {
|
||||
await this.setTransactionIsolationLevel(dbhan, conn.defaultIsolationLevel);
|
||||
}
|
||||
return dbhan;
|
||||
},
|
||||
async close(dbhan) {
|
||||
return dbhan.client.close();
|
||||
@@ -173,6 +177,13 @@ const driver = {
|
||||
await this.query(dbhan, `KILL ${processId}`);
|
||||
},
|
||||
|
||||
async setTransactionIsolationLevel(dbhan, level) {
|
||||
if (this.isolationLevels && level && !this.isolationLevels.includes(level)) {
|
||||
throw new Error(`Isolation level "${level}" is not supported. Supported levels: ${this.isolationLevels.join(', ')}`);
|
||||
}
|
||||
await this.query(dbhan, `SET TRANSACTION ISOLATION LEVEL ${level}`);
|
||||
},
|
||||
|
||||
async serverSummary(dbhan) {
|
||||
const [variables, processes, databases] = await Promise.all([
|
||||
this.listVariables(dbhan),
|
||||
|
||||
@@ -119,7 +119,7 @@ async function tediousQueryCore(dbhan, sql, options) {
|
||||
columns: [],
|
||||
});
|
||||
}
|
||||
const { addDriverNativeColumn, discardResult } = options || {};
|
||||
const { addDriverNativeColumn, discardResult, commandTimeout } = options || {};
|
||||
return new Promise((resolve, reject) => {
|
||||
const result = {
|
||||
rows: [],
|
||||
@@ -129,6 +129,9 @@ async function tediousQueryCore(dbhan, sql, options) {
|
||||
if (err) reject(err);
|
||||
else resolve(result);
|
||||
});
|
||||
if (commandTimeout) {
|
||||
request.setTimeout(parseInt(commandTimeout));
|
||||
}
|
||||
request.on('columnMetadata', function (columns) {
|
||||
result.columns = extractTediousColumns(columns, addDriverNativeColumn);
|
||||
});
|
||||
|
||||
@@ -165,6 +165,9 @@ const driver = {
|
||||
'singleDatabase',
|
||||
'isReadOnly',
|
||||
'useSeparateSchemas',
|
||||
'defaultIsolationLevel',
|
||||
'allowedDatabases',
|
||||
'allowedDatabasesRegex',
|
||||
].includes(field) ||
|
||||
(field == 'trustServerCertificate' && values.authType != 'sql' && values.authType != 'sspi') ||
|
||||
(field == 'windowsDomain' && values.authType != 'sql' && values.authType != 'sspi' && values.authType != 'msentra'),
|
||||
@@ -179,7 +182,9 @@ const driver = {
|
||||
defaultPort: 1433,
|
||||
defaultAuthTypeName: 'tedious',
|
||||
supportsTransactions: true,
|
||||
isolationLevels: ['READ UNCOMMITTED', 'READ COMMITTED', 'REPEATABLE READ', 'SNAPSHOT', 'SERIALIZABLE'],
|
||||
supportsIncrementalAnalysis: true,
|
||||
defaultIsolationLevel: 'READ COMMITTED',
|
||||
// databaseUrlPlaceholder: 'e.g. server=localhost&authentication.type=default&authentication.type.user=myuser&authentication.type.password=pwd&options.database=mydb',
|
||||
|
||||
getNewObjectTemplates() {
|
||||
|
||||
@@ -78,6 +78,9 @@ const drivers = driverBases.map(driverBase => ({
|
||||
if (isReadOnly) {
|
||||
await this.query(dbhan, 'SET SESSION TRANSACTION READ ONLY');
|
||||
}
|
||||
if (props.defaultIsolationLevel) {
|
||||
await this.setTransactionIsolationLevel(dbhan, props.defaultIsolationLevel);
|
||||
}
|
||||
return dbhan;
|
||||
},
|
||||
close(dbhan) {
|
||||
@@ -105,9 +108,18 @@ const drivers = driverBases.map(driverBase => ({
|
||||
};
|
||||
}
|
||||
|
||||
const commandTimeout = options?.commandTimeout;
|
||||
const queryOptions = {};
|
||||
if (commandTimeout) {
|
||||
queryOptions.timeout = parseInt(commandTimeout);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
dbhan.client.query(sql, function (error, results, fields) {
|
||||
if (error) reject(error);
|
||||
dbhan.client.query({ sql, ...queryOptions }, function (error, results, fields) {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
const columns = extractColumns(fields);
|
||||
resolve({ rows: results && columns && results.map && results.map(row => modifyRow(zipDataRow(row, columns), columns)), columns });
|
||||
});
|
||||
@@ -244,6 +256,13 @@ const drivers = driverBases.map(driverBase => ({
|
||||
await this.query(dbhan, `KILL ${processId}`);
|
||||
},
|
||||
|
||||
async setTransactionIsolationLevel(dbhan, level) {
|
||||
if (this.isolationLevels && level && !this.isolationLevels.includes(level)) {
|
||||
throw new Error(`Isolation level "${level}" is not supported. Supported levels: ${this.isolationLevels.join(', ')}`);
|
||||
}
|
||||
await this.query(dbhan, `SET SESSION TRANSACTION ISOLATION LEVEL ${level}`);
|
||||
},
|
||||
|
||||
async serverSummary(dbhan) {
|
||||
const [variables, processes, databases] = await Promise.all([
|
||||
this.listVariables(dbhan),
|
||||
|
||||
@@ -162,7 +162,7 @@ const mysqlDialect = {
|
||||
const mysqlDriverBase = {
|
||||
...driverBase,
|
||||
showConnectionField: (field, values) => {
|
||||
if (['authType', 'user', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field)) {
|
||||
if (['authType', 'user', 'defaultDatabase', 'singleDatabase', 'isReadOnly', 'allowedDatabases', 'allowedDatabasesRegex', 'defaultIsolationLevel'].includes(field)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -194,7 +194,9 @@ const mysqlDriverBase = {
|
||||
defaultAuthTypeName: 'hostPort',
|
||||
defaultSocketPath: '/var/run/mysqld/mysqld.sock',
|
||||
supportsTransactions: true,
|
||||
isolationLevels: ['READ UNCOMMITTED', 'READ COMMITTED', 'REPEATABLE READ', 'SERIALIZABLE'],
|
||||
supportsIncrementalAnalysis: true,
|
||||
defaultIsolationLevel: 'REPEATABLE READ',
|
||||
|
||||
getNewObjectTemplates() {
|
||||
return [
|
||||
|
||||
@@ -37,10 +37,18 @@ function zipDataRow(rowArray, columns) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
function nativeDateToIsoString(date) {
|
||||
const pad = n => String(n).padStart(2, '0');
|
||||
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
|
||||
}
|
||||
|
||||
function modifyRow(row, columns) {
|
||||
columns.forEach(col => {
|
||||
if (Buffer.isBuffer(row[col.columnName])) {
|
||||
row[col.columnName] = { $binary: { base64: row[col.columnName].toString('base64') } };
|
||||
const val = row[col.columnName];
|
||||
if (val instanceof Date) {
|
||||
row[col.columnName] = nativeDateToIsoString(val);
|
||||
} else if (Buffer.isBuffer(val)) {
|
||||
row[col.columnName] = { $binary: { base64: val.toString('base64') } };
|
||||
}
|
||||
});
|
||||
return row;
|
||||
@@ -99,7 +107,7 @@ const driver = {
|
||||
async close(dbhan) {
|
||||
return dbhan.client.close();
|
||||
},
|
||||
async query(dbhan, sql) {
|
||||
async query(dbhan, sql, options) {
|
||||
if (sql == null || sql.trim() == '') {
|
||||
return {
|
||||
rows: [],
|
||||
@@ -112,7 +120,21 @@ const driver = {
|
||||
sql = mtrim[1];
|
||||
}
|
||||
|
||||
const res = await dbhan.client.execute(sql);
|
||||
const commandTimeout = options?.commandTimeout;
|
||||
let previousCallTimeout;
|
||||
if (commandTimeout) {
|
||||
previousCallTimeout = dbhan.client.callTimeout;
|
||||
dbhan.client.callTimeout = parseInt(commandTimeout);
|
||||
}
|
||||
|
||||
let res;
|
||||
try {
|
||||
res = await dbhan.client.execute(sql);
|
||||
} finally {
|
||||
if (commandTimeout) {
|
||||
dbhan.client.callTimeout = previousCallTimeout || 0;
|
||||
}
|
||||
}
|
||||
try {
|
||||
const columns = extractOracleColumns(res.metaData);
|
||||
return { rows: (res.rows || []).map(row => modifyRow(zipDataRow(row, columns), columns)), columns };
|
||||
|
||||
@@ -112,6 +112,7 @@ const oracleDriver = {
|
||||
showConnectionField: (field, values, { config }) => {
|
||||
if (field == 'useDatabaseUrl') return true;
|
||||
if (field == 'authType') return true;
|
||||
if (field == 'allowedDatabases' || field == 'allowedDatabasesRegex') return true;
|
||||
if (field == 'clientLibraryPath') return config?.isElectron && values.authType == 'thick';
|
||||
|
||||
if (values.useDatabaseUrl) {
|
||||
|
||||
@@ -115,6 +115,7 @@ const drivers = driverBases.map(driverBase => ({
|
||||
isReadOnly,
|
||||
authType,
|
||||
socketPath,
|
||||
defaultIsolationLevel,
|
||||
} = props;
|
||||
let options = null;
|
||||
|
||||
@@ -172,20 +173,34 @@ const drivers = driverBases.map(driverBase => ({
|
||||
if (isReadOnly) {
|
||||
await this.query(dbhan, 'SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY');
|
||||
}
|
||||
if (defaultIsolationLevel) {
|
||||
await this.setTransactionIsolationLevel(dbhan, defaultIsolationLevel);
|
||||
}
|
||||
|
||||
return dbhan;
|
||||
},
|
||||
async close(dbhan) {
|
||||
return dbhan.client.end();
|
||||
},
|
||||
async query(dbhan, sql) {
|
||||
async query(dbhan, sql, options) {
|
||||
if (sql == null) {
|
||||
return {
|
||||
rows: [],
|
||||
columns: [],
|
||||
};
|
||||
}
|
||||
const res = await dbhan.client.query({ text: sql, rowMode: 'array' });
|
||||
const commandTimeout = options?.commandTimeout;
|
||||
if (commandTimeout) {
|
||||
await dbhan.client.query({ text: `SET statement_timeout = ${parseInt(commandTimeout)}` });
|
||||
}
|
||||
let res;
|
||||
try {
|
||||
res = await dbhan.client.query({ text: sql, rowMode: 'array' });
|
||||
} finally {
|
||||
if (commandTimeout) {
|
||||
await dbhan.client.query({ text: 'SET statement_timeout = 0' }).catch(() => {});
|
||||
}
|
||||
}
|
||||
const columns = extractPostgresColumns(res, dbhan);
|
||||
|
||||
const transormableTypeNames = Object.values(dbhan.typeIdToName ?? {});
|
||||
@@ -413,6 +428,13 @@ const drivers = driverBases.map(driverBase => ({
|
||||
return result;
|
||||
},
|
||||
|
||||
async setTransactionIsolationLevel(dbhan, level) {
|
||||
if (this.isolationLevels && level && !this.isolationLevels.includes(level)) {
|
||||
throw new Error(`Isolation level "${level}" is not supported. Supported levels: ${this.isolationLevels.join(', ')}`);
|
||||
}
|
||||
await this.query(dbhan, `SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ${level}`);
|
||||
},
|
||||
|
||||
async listDatabasesFull(dbhan) {
|
||||
const { rows } = await this.query(dbhan, sql.listDatabases);
|
||||
return rows;
|
||||
|
||||
@@ -123,7 +123,9 @@ const dialect = {
|
||||
const postgresDriverBase = {
|
||||
...driverBase,
|
||||
supportsTransactions: true,
|
||||
isolationLevels: ['READ COMMITTED', 'REPEATABLE READ', 'SERIALIZABLE'],
|
||||
supportsIncrementalAnalysis: true,
|
||||
defaultIsolationLevel: 'READ COMMITTED',
|
||||
dumperClass: Dumper,
|
||||
dialect,
|
||||
// showConnectionField: (field, values) =>
|
||||
@@ -142,7 +144,7 @@ const postgresDriverBase = {
|
||||
databaseUrlPlaceholder: 'e.g. postgresql://user:password@localhost:5432/default_database',
|
||||
|
||||
showConnectionField: (field, values) => {
|
||||
const allowedFields = ['useDatabaseUrl', 'authType', 'user', 'isReadOnly', 'useSeparateSchemas'];
|
||||
const allowedFields = ['useDatabaseUrl', 'authType', 'user', 'isReadOnly', 'useSeparateSchemas', 'allowedDatabases', 'allowedDatabasesRegex', 'defaultIsolationLevel'];
|
||||
|
||||
if (values.authType == 'awsIam') {
|
||||
allowedFields.push('awsRegion', 'secretAccessKey', 'accessKeyId');
|
||||
@@ -424,7 +426,7 @@ const redshiftDriver = {
|
||||
databaseUrlPlaceholder: 'e.g. redshift-cluster-1.xxxx.redshift.amazonaws.com:5439/dev',
|
||||
icon: redshiftIcon,
|
||||
showConnectionField: (field, values) =>
|
||||
['databaseUrl', 'user', 'password', 'isReadOnly', 'useSeparateSchemas'].includes(field),
|
||||
['databaseUrl', 'user', 'password', 'isReadOnly', 'useSeparateSchemas', 'allowedDatabases', 'allowedDatabasesRegex'].includes(field),
|
||||
beforeConnectionSave: connection => {
|
||||
const { databaseUrl } = connection;
|
||||
if (databaseUrl) {
|
||||
|
||||
@@ -5,7 +5,7 @@ function changeDependencies(deps, version) {
|
||||
if (!deps) return;
|
||||
for (const key of Object.keys(deps)) {
|
||||
if (key.startsWith('dbgate-') && key != 'dbgate-plugin-tools' && key != 'dbgate-query-splitter') {
|
||||
deps[key] = `^${version}`;
|
||||
deps[key] = `${version}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ changePackageFile('packages/datalib', json.version);
|
||||
changePackageFile('packages/serve', json.version);
|
||||
changePackageFile('packages/filterparser', json.version);
|
||||
changePackageFile('packages/dbmodel', json.version);
|
||||
changePackageFile('packages/rest', json.version);
|
||||
|
||||
if (fs.existsSync('packer/azure-ubuntu.pkr.hcl')) {
|
||||
const text = fs.readFileSync('packer/azure-ubuntu.pkr.hcl', { encoding: 'utf-8' });
|
||||
|
||||
+52
-2
@@ -113,6 +113,7 @@
|
||||
"command.about": "O aplikaci",
|
||||
"command.about.show": "Zobrazit",
|
||||
"command.about.toolbar": "O aplikaci",
|
||||
"command.apiQuery": "API dotaz",
|
||||
"command.app.checkForUpdates": "Zkontrolovat dostupné aktualizace",
|
||||
"command.app.disconnect": "Odpojit",
|
||||
"command.app.loggedUser": "Přihlášený uživatel",
|
||||
@@ -245,6 +246,7 @@
|
||||
"command.designer": "Návrhář",
|
||||
"command.designer.arrange": "Uspořádat",
|
||||
"command.designer.exportDiagram": "Exportovat diagram",
|
||||
"command.designer.exportDiagramPng": "Exportovat diagram jako PNG",
|
||||
"command.designer.openSql": "Otevřít SQL",
|
||||
"command.designer.remove": "Odebrat",
|
||||
"command.designer.removeSelectedTables": "Odebrat vybrané tabulky",
|
||||
@@ -272,6 +274,11 @@
|
||||
"command.folder": "Složka",
|
||||
"command.folder.openData": "Otevřít složku dat",
|
||||
"command.folder.openLogs": "Otevřít logy",
|
||||
"command.gqlConnection": "GraphQL připojení",
|
||||
"command.gqlConnection.toggleCellDataView": "Přepnout zobrazení dat buňky",
|
||||
"command.gqlConnection.toggleCellDataView.menu": "Zobrazit data buňky",
|
||||
"command.gqlConnection.toggleCellDataView.toolbar": "Data buňky",
|
||||
"command.graphql.chat": "GraphQL chat",
|
||||
"command.internal": "Interní",
|
||||
"command.internal.loadCampaigns": "Načíst seznam kampaní",
|
||||
"command.internal.showCampaigns": "Zobrazit kampaně",
|
||||
@@ -294,12 +301,14 @@
|
||||
"command.new.connectionFolderToolbar": "Přidat složku připojení",
|
||||
"command.new.diagram": "ER Diagram",
|
||||
"command.new.duckdbDatabase": "Nová DuckDB databáze",
|
||||
"command.new.graphqlQuery": "GraphQL dotaz",
|
||||
"command.new.jsonl": "JSON Lines",
|
||||
"command.new.markdown": "Markdown stránka",
|
||||
"command.new.modelCompare": "Porovnat DB",
|
||||
"command.new.modelTransform": "Transformace modelu",
|
||||
"command.new.newApplication": "Nová aplikace",
|
||||
"command.new.newDiagram": "Nový ER diagram",
|
||||
"command.new.newGraphqlQuery": "Nový GraphQL dotaz",
|
||||
"command.new.newJsonl": "Nový JSON lines soubor",
|
||||
"command.new.newModelTransform": "Nová transformace modelu",
|
||||
"command.new.newPerspective": "Nová perspektiva",
|
||||
@@ -342,6 +351,8 @@
|
||||
"command.redisLikeData.save": "Uložit",
|
||||
"command.redo": "Znovu",
|
||||
"command.replace": "Nahradit",
|
||||
"command.restApi": "REST API",
|
||||
"command.restApi.execute": "Spustit",
|
||||
"command.save": "Uložit",
|
||||
"command.saveAs": "Uložit jako",
|
||||
"command.saveToDisk": "Uložit na disk",
|
||||
@@ -432,6 +443,8 @@
|
||||
"common.fileType": "{extension} soubory",
|
||||
"common.files.allFiles": "Všechny soubory",
|
||||
"common.general": "Obecné",
|
||||
"common.graphqlChat": "GraphQL chat",
|
||||
"common.graphqlQuery": "GraphQL dotaz",
|
||||
"common.import": "Import",
|
||||
"common.kill": "Ukončit",
|
||||
"common.loadingData": "Načítání dat",
|
||||
@@ -534,6 +547,11 @@
|
||||
"connection.accessKeyId": "ID přístupového klíče",
|
||||
"connection.allowedDatabases": "Povolené databáze, jedna na řádek",
|
||||
"connection.allowedDatabasesRegex": "Regulární výraz pro povolené databáze",
|
||||
"connection.apiKeyHeader": "Hlavička API klíče",
|
||||
"connection.apiKeyValue": "Hodnota API klíče",
|
||||
"connection.apiQuery": "API dotaz",
|
||||
"connection.apiServerUrl1": "URL API serveru",
|
||||
"connection.apiServerUrl2": "URL sekundárního API serveru",
|
||||
"connection.askPassword": "Neukládat, ptát se na heslo",
|
||||
"connection.askUser": "Neukládat, ptát se na přihlašovací jméno a heslo",
|
||||
"connection.authToken": "Autorizační token",
|
||||
@@ -555,6 +573,7 @@
|
||||
"connection.databaseFilePath": "Soubor databáze (cesta na serveru)",
|
||||
"connection.databaseUrl": "URL databáze",
|
||||
"connection.defaultDatabase": "Výchozí databáze",
|
||||
"connection.defaultIsolationLevel": "Výchozí úroveň izolace",
|
||||
"connection.delete": "Odstranit",
|
||||
"connection.deleteConfirm": "Opravdu smazat připojení {name}?",
|
||||
"connection.deleteFolderConfirm": "Opravdu smazat složku {folder}? Připojení ve složce budou přesunuta do kořenové složky.",
|
||||
@@ -567,6 +586,9 @@
|
||||
"connection.engine": "Typ databáze",
|
||||
"connection.engineDriverNotFound": "Ovladač databáze {engine} nebyl nalezen, zkontrolujte nainstalované pluginy a změňte typ databáze v dialogu úpravy připojení",
|
||||
"connection.fillDetails": "Vyplňte detaily připojení k databázi",
|
||||
"connection.httpProxyPassword": "Heslo HTTP proxy",
|
||||
"connection.httpProxyUrl": "URL HTTP proxy",
|
||||
"connection.httpProxyUser": "Uživatel HTTP proxy",
|
||||
"connection.isReadOnly": "Je pouze pro čtení",
|
||||
"connection.keySeparator": "Oddělovač klíčů",
|
||||
"connection.localDataCenter": "Lokální datové centrum",
|
||||
@@ -626,6 +648,7 @@
|
||||
"dataForm.noData": "Žádná data",
|
||||
"dataForm.outOfBounds": "Mimo rozsah: {current} / {total}",
|
||||
"dataForm.rowCount": "Řádek: {current} / {total}",
|
||||
"dataForm.rowCountMany": "Řádek: {current} / mnoho",
|
||||
"dataGrid.chooseValue": "Vybrat hodnotu z {field}",
|
||||
"dataGrid.codeHighlighting": "Zvýraznění kódu:",
|
||||
"dataGrid.codeHighlighting.none": "Žádné (neformátovaný text)",
|
||||
@@ -664,6 +687,7 @@
|
||||
"database.export": "Export",
|
||||
"database.exportDbModel": "Export DB model",
|
||||
"database.generateScript": "Vygenerovat skript",
|
||||
"database.graphqlChat": "GraphQL chat",
|
||||
"database.import": "Import",
|
||||
"database.newApplication": "Nová aplikace",
|
||||
"database.newCollection": "Nová kolekce/kontejner",
|
||||
@@ -764,6 +788,7 @@
|
||||
"datagrid.openQuery": "Otevřít dotaz",
|
||||
"datagrid.resetFilter": "Resetovat filtr",
|
||||
"datagrid.resetView": "Resetovat zobrazení",
|
||||
"datagrid.rowCountMany": "Mnoho",
|
||||
"datagrid.rows": "Řádky",
|
||||
"datagrid.searchMacros": "Hledat makra",
|
||||
"datagrid.selectedInfo.count": "Počet",
|
||||
@@ -771,6 +796,7 @@
|
||||
"datagrid.selectedInfo.sum": "Součet",
|
||||
"datagrid.setFormat": "Nastavit formát: ",
|
||||
"datagrid.structure": "Struktura",
|
||||
"datagrid.structure.notLoaded": "Nebyla načtena žádná struktura, pravděpodobně tabulka v aktuální databázi neexistuje",
|
||||
"datagrid.structure.waiting": "Čekání na strukturu",
|
||||
"datagrid.useMacro": "Použít makro",
|
||||
"dbKeysTreeNode.deleteBranch": "Smazat větev",
|
||||
@@ -836,6 +862,7 @@
|
||||
"designer.addAllTables": "Přidat všechny tabulky",
|
||||
"designer.all": "Vše",
|
||||
"designer.allKeys": "Všechny klíče",
|
||||
"designer.chooseTableColor": "Vybrat barvu tabulky",
|
||||
"designer.columnProperties": "Vlastnosti sloupce",
|
||||
"designer.columns": "Sloupce - { filterColumns }",
|
||||
"designer.dataTypeYesNo": "Datový typ: {show}",
|
||||
@@ -900,7 +927,12 @@
|
||||
"file.queryDesignerFiles": "Soubory návrháře dotazů",
|
||||
"file.sqlFiles": "Soubory SQL",
|
||||
"file.sqliteDatabase": "Databáze SQLite",
|
||||
"files.allConnections": "Všechna připojení",
|
||||
"files.allDatabases": "všechny databáze",
|
||||
"files.allSupportedFiles": "Všechny podporované soubory",
|
||||
"files.clearConnectionFilter": "Vymazat filtr připojení",
|
||||
"files.connection": "Připojení",
|
||||
"files.currentDatabase": "Aktuální databáze",
|
||||
"files.openFile": "Otevřít soubor",
|
||||
"files.refreshFiles": "Obnovit soubory",
|
||||
"files.savedFiles": "Uložené soubory",
|
||||
@@ -1060,6 +1092,7 @@
|
||||
"importExport.value": "Hodnota",
|
||||
"indexEditor.filteredIndexCondition": "Podmínka filtrovaného indexu",
|
||||
"indexEditor.indexName": "Název indexu",
|
||||
"indexEditor.indexType": "Typ indexu",
|
||||
"indexEditor.isUnique": "Je jedinečný index",
|
||||
"insertJoin.alias": "Alias",
|
||||
"insertJoin.columnFrom": "Sloupec z",
|
||||
@@ -1135,6 +1168,10 @@
|
||||
"newObject.erDiagramDisabled": "ER Diagram není pro aktuální databázi k dispozici",
|
||||
"newObject.exportDescription": "Exportovat do souboru jako CSV, JSON, Excel nebo jiné databáze",
|
||||
"newObject.exportDisabled": "Export není pro aktuální databázi k dispozici",
|
||||
"newObject.graphqlChatDescription": "Chatovat s GraphQL API pomocí AI",
|
||||
"newObject.graphqlChatDisabled": "GraphQL chat není pro aktuální připojení k dispozici",
|
||||
"newObject.graphqlQueryDescription": "Psát dotazy, vybírat atributy a argumenty",
|
||||
"newObject.graphqlQueryDisabled": "GraphQL dotaz není pro aktuální databázi k dispozici",
|
||||
"newObject.perspectiveDescription": "Propojte data z více databází",
|
||||
"newObject.queryDesignerDescription": "Vizuálně navrhnout SQL dotazy",
|
||||
"newObject.queryDesignerDisabled": "Návrhář dotazů není pro aktuální databázi k dispozici",
|
||||
@@ -1158,6 +1195,7 @@
|
||||
"privateCloudWidget.addNewConnectionOrFile": "Přidat nové připojení nebo soubor",
|
||||
"privateCloudWidget.addNewFolder": "Přidat novou složku",
|
||||
"privateCloudWidget.administrateAccess": "Spravovat přístup",
|
||||
"privateCloudWidget.cloudUnavailable": "DbGate Cloud je dočasně nedostupný",
|
||||
"privateCloudWidget.createConnection": "Vytvořit připojení na DbGate Cloud",
|
||||
"privateCloudWidget.createSharedFolder": "Vytvořit sdílenou složku",
|
||||
"privateCloudWidget.deleteFolder": "Smazat složku",
|
||||
@@ -1170,6 +1208,7 @@
|
||||
"privateCloudWidget.renameFolder": "Přejmenovat složku",
|
||||
"privateCloudWidget.searchPlaceholder": "Hledat cloudová připojení a soubory",
|
||||
"privateCloudWidget.yourInviteLink": "Váš pozvánkový odkaz (ve tvaru dbgate://folder/xxx)",
|
||||
"publicCloudWidget.cloudUnavailable": "DbGate Cloud je dočasně nedostupný",
|
||||
"publicCloudWidget.noFilesFound": "Pro vaši konfiguraci nebyly nalezeny žádné soubory",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Jsou zobrazeny pouze soubory relevantní pro vaše připojení, platformu a edici DbGate. Nejprve prosím definujte připojení.",
|
||||
"publicCloudWidget.publicKnowledgeBase": "Veřejná znalostní báze",
|
||||
@@ -1191,10 +1230,13 @@
|
||||
"query.aggregate": "Agregace",
|
||||
"query.alias": "Alias",
|
||||
"query.columnExpression": "Sloupec/Výraz",
|
||||
"query.defaultIsolationLevel": "Výchozí",
|
||||
"query.defaultIsolationLevelNamed": "Výchozí ({level})",
|
||||
"query.download": "stáhnout",
|
||||
"query.filter": "Filtr",
|
||||
"query.groupBy": "Seskupit podle",
|
||||
"query.groupFilter": "Filtr skupiny",
|
||||
"query.isolationLevel": "Úroveň izolace",
|
||||
"query.limitRows": "Omezit na {queryRowsLimit} řádků",
|
||||
"query.named": ":proměnná",
|
||||
"query.noParameters": "(žádné parametry)",
|
||||
@@ -1287,6 +1329,7 @@
|
||||
"settings.behaviour.openDetailOnArrows": "Otevřít detail při navigaci klávesnicí",
|
||||
"settings.behaviour.singleClickPreview": "Když jedním kliknutím nebo výběrem souboru v zobrazení \"Tabulky, Pohledy, Funkce\", je zobrazen v režimu náhledu a znovu používá existující kartu (karta náhledu). To je užitečné, pokud rychle procházíte tabulky a nechcete, aby každá navštívená tabulka měla svou vlastní kartu. Když začnete upravovat tabulku nebo použijete dvojklik pro otevření tabulky ze zobrazení \"Tabulky\", nová karta je věnována této tabulce.",
|
||||
"settings.behaviour.useTabPreviewMode": "Použít režim náhledu na kartě",
|
||||
"settings.checkAll": "Zaškrtnout vše / Zrušit zaškrtnutí všeho",
|
||||
"settings.confirmations": "Potvrzení",
|
||||
"settings.confirmations.skipConfirm.collectionDataSave": "Přeskočit potvrzení při ukládání údajů kolekce (NoSQL)",
|
||||
"settings.confirmations.skipConfirm.tableDataSave": "Přeskočit potvrzení při ukládání údajů tabulky (SQL)",
|
||||
@@ -1305,6 +1348,7 @@
|
||||
"settings.dataGrid.coloringMode.36": "Každý 3. a 6. řádek",
|
||||
"settings.dataGrid.coloringMode.none": "Žádný",
|
||||
"settings.dataGrid.defaultAutoRefreshInterval": "Výchozí interval automatického obnovení mřížky (v sekundách)",
|
||||
"settings.dataGrid.disableCellDataViewAutoOpen": "Zakázat automatické otevírání zobrazení dat buňky",
|
||||
"settings.dataGrid.pageSize": "Velikost stránky (počet řádků pro inkrementální načítání, musí být mezi 5 a 50000)",
|
||||
"settings.dataGrid.showAllColumnsWhenSearch": "Zobrazit všechny sloupce při hledání",
|
||||
"settings.dataGrid.showHintColumns": "Zobrazit nápovědu pro cizí klíče",
|
||||
@@ -1331,6 +1375,7 @@
|
||||
"settings.defaultActions.tableClick": "Kliknutí na tabulku",
|
||||
"settings.defaultActions.useLastUsedAction": "Použít naposledy použitou akci",
|
||||
"settings.defaultActions.viewClick": "Kliknutí na pohled",
|
||||
"settings.drivers": "Ovladače",
|
||||
"settings.editor.keybinds": "Klávesové zkratky editoru",
|
||||
"settings.editor.wordWrap": "Povolit zalamování textu",
|
||||
"settings.externalTools": "Externí nástroje",
|
||||
@@ -1355,6 +1400,9 @@
|
||||
"settings.other.licenseKey.invalid": "Licenční klíč je neplatný",
|
||||
"settings.other.licenseKey.valid": "Licenční klíč je platný",
|
||||
"settings.other.licenseKey.validTo": "Licence platná do:",
|
||||
"settings.other.toolBarPosition": "Pozice nástrojové lišty",
|
||||
"settings.other.toolBarPosition.bottom": "Dole",
|
||||
"settings.other.toolBarPosition.top": "Nahoře",
|
||||
"settings.session": "Dotazové relace",
|
||||
"settings.session.autoClose": "Automatické uzavření dotazových relací po období nečinnosti",
|
||||
"settings.session.autoCloseTimeout": "Interval, po kterém je dotazová relace bez aktivity uzavřena (v minutách)",
|
||||
@@ -1393,6 +1441,7 @@
|
||||
"sqlGenerator.omitNulls": "Vynechat hodnoty NULL",
|
||||
"sqlGenerator.searchTablesOrObjects": "Hledat tabulky nebo objekty",
|
||||
"sqlGenerator.skipAutoincrementColumn": "Přeskočit autoincrement sloupec",
|
||||
"sqlGenerator.skipComputedColumns": "Přeskočit vypočítané sloupce",
|
||||
"sqlGenerator.sqlGenerator": "SQL generátor",
|
||||
"sqlGenerator.sqlTruncated": "SQL zkráceno, překročen limit velikosti souboru",
|
||||
"sqlGenerator.tables": "Tabulky",
|
||||
@@ -1467,6 +1516,7 @@
|
||||
"tableEditor.defaultValue": "Výchozí hodnota",
|
||||
"tableEditor.dependencies": "Závislosti",
|
||||
"tableEditor.foreignKeys": "Cizí klíče ({foreignKeyCount})",
|
||||
"tableEditor.indexType": "Typ",
|
||||
"tableEditor.indexes": "Indexy ({indexCount})",
|
||||
"tableEditor.isPersisted": "Je persistentní",
|
||||
"tableEditor.isSparse": "Je řídký",
|
||||
@@ -1485,7 +1535,6 @@
|
||||
"tableEditor.remove": "Odstranit",
|
||||
"tableEditor.tablename": "Název tabulky",
|
||||
"tableEditor.tableproperties": "Vlastnosti tabulky",
|
||||
"tableEditor.unique": "Jedinečný",
|
||||
"tableEditor.uniqueConstraints": "Omezení jedinečnosti ({constraintCount})",
|
||||
"tableEditor.yes": "ANO",
|
||||
"tableStructure.alter": "Upravit tabulku",
|
||||
@@ -1521,6 +1570,7 @@
|
||||
"widget.collectionsContainers": "Kolekce/kontejnery",
|
||||
"widget.databaseContent": "Obsah databáze",
|
||||
"widget.databases": "Databáze",
|
||||
"widget.endpoints": "Endpointy",
|
||||
"widget.keys": "Klíče",
|
||||
"widget.pinned": "Připnuté",
|
||||
"widget.tablesViewsFunctions": "Tabulky, pohledy, funkce",
|
||||
@@ -1535,4 +1585,4 @@
|
||||
"widgets.openedTabs": "Otevřené karty",
|
||||
"widgets.premiumPromo": "Premium promo",
|
||||
"widgets.queryHistoryAndClosedTabs": "Historie dotazů a zavřené karty"
|
||||
}
|
||||
}
|
||||
|
||||
+52
-2
@@ -113,6 +113,7 @@
|
||||
"command.about": "Über DbGate",
|
||||
"command.about.show": "Anzeigen",
|
||||
"command.about.toolbar": "Über DbGate",
|
||||
"command.apiQuery": "API-Abfrage",
|
||||
"command.app.checkForUpdates": "Nach Updates suchen",
|
||||
"command.app.disconnect": "Trennen",
|
||||
"command.app.loggedUser": "Angemeldeter Benutzer",
|
||||
@@ -245,6 +246,7 @@
|
||||
"command.designer": "Designer",
|
||||
"command.designer.arrange": "Anordnen",
|
||||
"command.designer.exportDiagram": "Diagramm exportieren",
|
||||
"command.designer.exportDiagramPng": "Diagramm als PNG exportieren",
|
||||
"command.designer.openSql": "SQL öffnen",
|
||||
"command.designer.remove": "Entfernen",
|
||||
"command.designer.removeSelectedTables": "Ausgewählte Tabellen entfernen",
|
||||
@@ -272,6 +274,11 @@
|
||||
"command.folder": "Ordner",
|
||||
"command.folder.openData": "Datenordner öffnen",
|
||||
"command.folder.openLogs": "Protokolle öffnen",
|
||||
"command.gqlConnection": "GraphQL-Verbindung",
|
||||
"command.gqlConnection.toggleCellDataView": "Zell-Datenansicht umschalten",
|
||||
"command.gqlConnection.toggleCellDataView.menu": "Zelldaten anzeigen",
|
||||
"command.gqlConnection.toggleCellDataView.toolbar": "Zelldaten",
|
||||
"command.graphql.chat": "GraphQL-Chat",
|
||||
"command.internal": "Intern",
|
||||
"command.internal.loadCampaigns": "Kampagnenliste laden",
|
||||
"command.internal.showCampaigns": "Kampagnen anzeigen",
|
||||
@@ -294,12 +301,14 @@
|
||||
"command.new.connectionFolderToolbar": "Verbindungsordner hinzufügen",
|
||||
"command.new.diagram": "ER-Diagramm",
|
||||
"command.new.duckdbDatabase": "Neue DuckDB-Datenbank",
|
||||
"command.new.graphqlQuery": "GraphQL-Abfrage",
|
||||
"command.new.jsonl": "JSON-Zeilen",
|
||||
"command.new.markdown": "Markdown-Seite",
|
||||
"command.new.modelCompare": "DB vergleichen",
|
||||
"command.new.modelTransform": "Modell transformieren",
|
||||
"command.new.newApplication": "Neue Anwendung",
|
||||
"command.new.newDiagram": "Neues ER-Diagramm",
|
||||
"command.new.newGraphqlQuery": "Neue GraphQL-Abfrage",
|
||||
"command.new.newJsonl": "Neue JSON-Zeilen-Datei",
|
||||
"command.new.newModelTransform": "Neue Modelltransformation",
|
||||
"command.new.newPerspective": "Neue Perspektive",
|
||||
@@ -342,6 +351,8 @@
|
||||
"command.redisLikeData.save": "Speichern",
|
||||
"command.redo": "Wiederholen",
|
||||
"command.replace": "Ersetzen",
|
||||
"command.restApi": "REST-API",
|
||||
"command.restApi.execute": "Ausführen",
|
||||
"command.save": "Speichern",
|
||||
"command.saveAs": "Speichern unter",
|
||||
"command.saveToDisk": "Auf Festplatte speichern",
|
||||
@@ -432,6 +443,8 @@
|
||||
"common.fileType": "{extension}-Dateien",
|
||||
"common.files.allFiles": "Alle Dateien",
|
||||
"common.general": "Allgemein",
|
||||
"common.graphqlChat": "GraphQL-Chat",
|
||||
"common.graphqlQuery": "GraphQL-Abfrage",
|
||||
"common.import": "Importieren",
|
||||
"common.kill": "Beenden",
|
||||
"common.loadingData": "Lade Daten",
|
||||
@@ -534,6 +547,11 @@
|
||||
"connection.accessKeyId": "Zugriffsschlüssel-ID",
|
||||
"connection.allowedDatabases": "Erlaubte Datenbanken, eine pro Zeile",
|
||||
"connection.allowedDatabasesRegex": "Regulärer Ausdruck für erlaubte Datenbanken",
|
||||
"connection.apiKeyHeader": "API-Schlüssel-Header",
|
||||
"connection.apiKeyValue": "API-Schlüssel-Wert",
|
||||
"connection.apiQuery": "API-Abfrage",
|
||||
"connection.apiServerUrl1": "API-Server-URL",
|
||||
"connection.apiServerUrl2": "API-sekundäre Server-URL",
|
||||
"connection.askPassword": "Nicht speichern, nach Passwort fragen",
|
||||
"connection.askUser": "Nicht speichern, nach Benutzername und Passwort fragen",
|
||||
"connection.authToken": "Auth-Token",
|
||||
@@ -555,6 +573,7 @@
|
||||
"connection.databaseFilePath": "Datenbankdatei (Pfad auf Server)",
|
||||
"connection.databaseUrl": "Datenbank-URL",
|
||||
"connection.defaultDatabase": "Standarddatenbank",
|
||||
"connection.defaultIsolationLevel": "Standard-Isolationsstufe",
|
||||
"connection.delete": "Löschen",
|
||||
"connection.deleteConfirm": "Verbindung {name} wirklich löschen?",
|
||||
"connection.deleteFolderConfirm": "Ordner {folder} wirklich löschen? Verbindungen im Ordner werden in den Stammordner verschoben.",
|
||||
@@ -567,6 +586,9 @@
|
||||
"connection.engine": "Datenbank-Engine",
|
||||
"connection.engineDriverNotFound": "Engine-Treiber {engine} nicht gefunden, überprüfen Sie installierte Plugins und ändern Sie die Engine im Verbindungsbearbeitungsdialog",
|
||||
"connection.fillDetails": "Datenbankverbindungsdetails ausfüllen",
|
||||
"connection.httpProxyPassword": "HTTP-Proxy-Passwort",
|
||||
"connection.httpProxyUrl": "HTTP-Proxy-URL",
|
||||
"connection.httpProxyUser": "HTTP-Proxy-Benutzer",
|
||||
"connection.isReadOnly": "Nur Lesezugriff",
|
||||
"connection.keySeparator": "Schlüsseltrennzeichen",
|
||||
"connection.localDataCenter": "Lokales Rechenzentrum",
|
||||
@@ -626,6 +648,7 @@
|
||||
"dataForm.noData": "Keine Daten",
|
||||
"dataForm.outOfBounds": "Außerhalb des Bereichs: {current} / {total}",
|
||||
"dataForm.rowCount": "Zeile: {current} / {total}",
|
||||
"dataForm.rowCountMany": "Zeile: {current} / Viele",
|
||||
"dataGrid.chooseValue": "Wert aus {field} auswählen",
|
||||
"dataGrid.codeHighlighting": "Code-Hervorhebung:",
|
||||
"dataGrid.codeHighlighting.none": "Keine (unformatierter Text)",
|
||||
@@ -664,6 +687,7 @@
|
||||
"database.export": "Exportieren",
|
||||
"database.exportDbModel": "DB-Modell exportieren",
|
||||
"database.generateScript": "Skript generieren",
|
||||
"database.graphqlChat": "GraphQL-Chat",
|
||||
"database.import": "Importieren",
|
||||
"database.newApplication": "Neue Anwendung",
|
||||
"database.newCollection": "Neue Sammlung/Container",
|
||||
@@ -764,6 +788,7 @@
|
||||
"datagrid.openQuery": "Abfrage öffnen",
|
||||
"datagrid.resetFilter": "Filter zurücksetzen",
|
||||
"datagrid.resetView": "Ansicht zurücksetzen",
|
||||
"datagrid.rowCountMany": "Viele",
|
||||
"datagrid.rows": "Zeilen",
|
||||
"datagrid.searchMacros": "Makros suchen",
|
||||
"datagrid.selectedInfo.count": "Anzahl",
|
||||
@@ -771,6 +796,7 @@
|
||||
"datagrid.selectedInfo.sum": "Summe",
|
||||
"datagrid.setFormat": "Format festlegen: ",
|
||||
"datagrid.structure": "Struktur",
|
||||
"datagrid.structure.notLoaded": "Es wurde keine Struktur geladen, wahrscheinlich existiert die Tabelle in der aktuellen Datenbank nicht",
|
||||
"datagrid.structure.waiting": "Warte auf Struktur",
|
||||
"datagrid.useMacro": "Makro verwenden",
|
||||
"dbKeysTreeNode.deleteBranch": "Zweig löschen",
|
||||
@@ -836,6 +862,7 @@
|
||||
"designer.addAllTables": "Alle Tabellen hinzufügen",
|
||||
"designer.all": "Alle",
|
||||
"designer.allKeys": "Alle Schlüssel",
|
||||
"designer.chooseTableColor": "Tabellenfarbe auswählen",
|
||||
"designer.columnProperties": "Spalteneigenschaften",
|
||||
"designer.columns": "Spalten - { filterColumns }",
|
||||
"designer.dataTypeYesNo": "Datentyp: {show}",
|
||||
@@ -900,7 +927,12 @@
|
||||
"file.queryDesignerFiles": "Abfrage-Designer-Dateien",
|
||||
"file.sqlFiles": "SQL-Dateien",
|
||||
"file.sqliteDatabase": "SQLite-Datenbank",
|
||||
"files.allConnections": "Alle Verbindungen",
|
||||
"files.allDatabases": "alle Datenbanken",
|
||||
"files.allSupportedFiles": "Alle unterstützten Dateien",
|
||||
"files.clearConnectionFilter": "Verbindungsfilter löschen",
|
||||
"files.connection": "Verbindung",
|
||||
"files.currentDatabase": "Aktuelle Datenbank",
|
||||
"files.openFile": "Datei öffnen",
|
||||
"files.refreshFiles": "Dateien aktualisieren",
|
||||
"files.savedFiles": "Gespeicherte Dateien",
|
||||
@@ -1060,6 +1092,7 @@
|
||||
"importExport.value": "Wert",
|
||||
"indexEditor.filteredIndexCondition": "Gefilterte Index-Bedingung",
|
||||
"indexEditor.indexName": "Index-Name",
|
||||
"indexEditor.indexType": "Index-Typ",
|
||||
"indexEditor.isUnique": "Ist eindeutiger Index",
|
||||
"insertJoin.alias": "Alias",
|
||||
"insertJoin.columnFrom": "Spalte von",
|
||||
@@ -1135,6 +1168,10 @@
|
||||
"newObject.erDiagramDisabled": "ER-Diagramm ist für aktuelle Datenbank nicht verfügbar",
|
||||
"newObject.exportDescription": "In Datei wie CSV, JSON, Excel oder andere DB exportieren",
|
||||
"newObject.exportDisabled": "Export ist für aktuelle Datenbank nicht verfügbar",
|
||||
"newObject.graphqlChatDescription": "Mit Ihrer GraphQL-API per KI chatten",
|
||||
"newObject.graphqlChatDisabled": "GraphQL-Chat ist für aktuelle Verbindung nicht verfügbar",
|
||||
"newObject.graphqlQueryDescription": "Abfragen schreiben, Attribute und Argumente auswählen",
|
||||
"newObject.graphqlQueryDisabled": "GraphQL-Abfrage ist für aktuelle Datenbank nicht verfügbar",
|
||||
"newObject.perspectiveDescription": "Komplexe Daten aus mehreren Datenbanken verknüpfen",
|
||||
"newObject.queryDesignerDescription": "SQL-Abfragen visuell entwerfen",
|
||||
"newObject.queryDesignerDisabled": "Abfrage-Designer ist für aktuelle Datenbank nicht verfügbar",
|
||||
@@ -1158,6 +1195,7 @@
|
||||
"privateCloudWidget.addNewConnectionOrFile": "Neue Verbindung oder Datei hinzufügen",
|
||||
"privateCloudWidget.addNewFolder": "Neuen Ordner hinzufügen",
|
||||
"privateCloudWidget.administrateAccess": "Zugriff verwalten",
|
||||
"privateCloudWidget.cloudUnavailable": "DbGate Cloud ist vorübergehend nicht verfügbar",
|
||||
"privateCloudWidget.createConnection": "Verbindung in DbGate Cloud erstellen",
|
||||
"privateCloudWidget.createSharedFolder": "Freigegebenen Ordner erstellen",
|
||||
"privateCloudWidget.deleteFolder": "Ordner löschen",
|
||||
@@ -1170,6 +1208,7 @@
|
||||
"privateCloudWidget.renameFolder": "Ordner umbenennen",
|
||||
"privateCloudWidget.searchPlaceholder": "Cloud-Verbindungen und Dateien suchen",
|
||||
"privateCloudWidget.yourInviteLink": "Ihr Einladungslink (im Format dbgate://folder/xxx)",
|
||||
"publicCloudWidget.cloudUnavailable": "DbGate Cloud ist vorübergehend nicht verfügbar",
|
||||
"publicCloudWidget.noFilesFound": "Keine Dateien für Ihre Konfiguration gefunden",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Es werden nur Dateien aufgelistet, die für Ihre Verbindungen, Plattform und DbGate-Edition relevant sind. Bitte definieren Sie zuerst Verbindungen.",
|
||||
"publicCloudWidget.publicKnowledgeBase": "Öffentliche Wissensdatenbank",
|
||||
@@ -1191,10 +1230,13 @@
|
||||
"query.aggregate": "Aggregation",
|
||||
"query.alias": "Alias",
|
||||
"query.columnExpression": "Spalte/Ausdruck",
|
||||
"query.defaultIsolationLevel": "Standard",
|
||||
"query.defaultIsolationLevelNamed": "Standard ({level})",
|
||||
"query.download": "herunterladen",
|
||||
"query.filter": "Filter",
|
||||
"query.groupBy": "Gruppieren nach",
|
||||
"query.groupFilter": "Gruppenfilter",
|
||||
"query.isolationLevel": "Isolationsstufe",
|
||||
"query.limitRows": "Auf {queryRowsLimit} Zeilen begrenzen",
|
||||
"query.named": ":Variable",
|
||||
"query.noParameters": "(keine Parameter)",
|
||||
@@ -1287,6 +1329,7 @@
|
||||
"settings.behaviour.openDetailOnArrows": "Details bei Tastaturnavigation öffnen",
|
||||
"settings.behaviour.singleClickPreview": "Wenn Sie in der Ansicht \"Tabellen, Sichten, Funktionen\" einfach klicken oder eine Datei auswählen, wird sie im Vorschaumodus angezeigt und verwendet einen vorhandenen Tab (Vorschau-Tab) wieder. Dies ist nützlich, wenn Sie schnell durch Tabellen blättern und nicht jede besuchte Tabelle in einem eigenen Tab haben möchten. Wenn Sie mit der Bearbeitung der Tabelle beginnen oder per Doppelklick die Tabelle aus der \"Tabellen\"-Ansicht öffnen, wird dieser Tabelle ein neuer Tab gewidmet.",
|
||||
"settings.behaviour.useTabPreviewMode": "Tab-Vorschaumodus verwenden",
|
||||
"settings.checkAll": "Alle auswählen / Alle abwählen",
|
||||
"settings.confirmations": "Bestätigungen",
|
||||
"settings.confirmations.skipConfirm.collectionDataSave": "Bestätigung beim Speichern von Sammlungsdaten überspringen (NoSQL)",
|
||||
"settings.confirmations.skipConfirm.tableDataSave": "Bestätigung beim Speichern von Tabellendaten überspringen (SQL)",
|
||||
@@ -1305,6 +1348,7 @@
|
||||
"settings.dataGrid.coloringMode.36": "Jede 3. und 6. Zeile",
|
||||
"settings.dataGrid.coloringMode.none": "Keine",
|
||||
"settings.dataGrid.defaultAutoRefreshInterval": "Standard-Raster-Auto-Aktualisierungsintervall in Sekunden",
|
||||
"settings.dataGrid.disableCellDataViewAutoOpen": "Automatische Zell-Datenansicht deaktivieren",
|
||||
"settings.dataGrid.pageSize": "Seitengröße (Anzahl der Zeilen für inkrementelles Laden, muss zwischen 5 und 50000 liegen)",
|
||||
"settings.dataGrid.showAllColumnsWhenSearch": "Alle Spalten beim Suchen anzeigen",
|
||||
"settings.dataGrid.showHintColumns": "Fremdschlüssel-Hinweise anzeigen",
|
||||
@@ -1331,6 +1375,7 @@
|
||||
"settings.defaultActions.tableClick": "Klick auf Tabelle",
|
||||
"settings.defaultActions.useLastUsedAction": "Zuletzt verwendete Aktion verwenden",
|
||||
"settings.defaultActions.viewClick": "Klick auf Ansicht",
|
||||
"settings.drivers": "Treiber",
|
||||
"settings.editor.keybinds": "Editor-Tastenkombinationen",
|
||||
"settings.editor.wordWrap": "Zeilenumbruch aktivieren",
|
||||
"settings.externalTools": "Externe Werkzeuge",
|
||||
@@ -1355,6 +1400,9 @@
|
||||
"settings.other.licenseKey.invalid": "Lizenzschlüssel ist ungültig",
|
||||
"settings.other.licenseKey.valid": "Lizenzschlüssel ist gültig",
|
||||
"settings.other.licenseKey.validTo": "Lizenz gültig bis:",
|
||||
"settings.other.toolBarPosition": "Symbolleistenposition",
|
||||
"settings.other.toolBarPosition.bottom": "Unten",
|
||||
"settings.other.toolBarPosition.top": "Oben",
|
||||
"settings.session": "Abfrage-Sitzungen",
|
||||
"settings.session.autoClose": "Automatisches Schließen von Abfrage-Sitzungen nach Zeitraum ohne Aktivität",
|
||||
"settings.session.autoCloseTimeout": "Intervall, nach dem Abfrage-Sitzung ohne Aktivität geschlossen wird (in Minuten)",
|
||||
@@ -1393,6 +1441,7 @@
|
||||
"sqlGenerator.omitNulls": "NULL-Werte auslassen",
|
||||
"sqlGenerator.searchTablesOrObjects": "Tabellen oder Objekte suchen",
|
||||
"sqlGenerator.skipAutoincrementColumn": "Autoincrement-Spalte überspringen",
|
||||
"sqlGenerator.skipComputedColumns": "Berechnete Spalten überspringen",
|
||||
"sqlGenerator.sqlGenerator": "SQL-Generator",
|
||||
"sqlGenerator.sqlTruncated": "SQL gekürzt, Dateigrößenlimit überschritten",
|
||||
"sqlGenerator.tables": "Tabellen",
|
||||
@@ -1467,6 +1516,7 @@
|
||||
"tableEditor.defaultValue": "Standardwert",
|
||||
"tableEditor.dependencies": "Abhängigkeiten",
|
||||
"tableEditor.foreignKeys": "Fremdschlüssel ({foreignKeyCount})",
|
||||
"tableEditor.indexType": "Typ",
|
||||
"tableEditor.indexes": "Indizes ({indexCount})",
|
||||
"tableEditor.isPersisted": "Ist persistent",
|
||||
"tableEditor.isSparse": "Sparse (dünn besetzt)",
|
||||
@@ -1485,7 +1535,6 @@
|
||||
"tableEditor.remove": "Entfernen",
|
||||
"tableEditor.tablename": "Tabellenname",
|
||||
"tableEditor.tableproperties": "Tabelleneigenschaften",
|
||||
"tableEditor.unique": "Eindeutig",
|
||||
"tableEditor.uniqueConstraints": "Eindeutigkeitseinschränkungen ({constraintCount})",
|
||||
"tableEditor.yes": "JA",
|
||||
"tableStructure.alter": "Tabelle ändern",
|
||||
@@ -1521,6 +1570,7 @@
|
||||
"widget.collectionsContainers": "Sammlungen/Container",
|
||||
"widget.databaseContent": "Datenbankinhalt",
|
||||
"widget.databases": "Datenbanken",
|
||||
"widget.endpoints": "Endpoints",
|
||||
"widget.keys": "Schlüssel",
|
||||
"widget.pinned": "Angeheftet",
|
||||
"widget.tablesViewsFunctions": "Tabellen, Ansichten, Funktionen",
|
||||
@@ -1535,4 +1585,4 @@
|
||||
"widgets.openedTabs": "Geöffnete Tabs",
|
||||
"widgets.premiumPromo": "Premium-Werbung",
|
||||
"widgets.queryHistoryAndClosedTabs": "Abfrageverlauf & geschlossene Tabs"
|
||||
}
|
||||
}
|
||||
|
||||
+52
-2
@@ -113,6 +113,7 @@
|
||||
"command.about": "About",
|
||||
"command.about.show": "Show",
|
||||
"command.about.toolbar": "About",
|
||||
"command.apiQuery": "API Query",
|
||||
"command.app.checkForUpdates": "Check for updates",
|
||||
"command.app.disconnect": "Disconnect",
|
||||
"command.app.loggedUser": "Logged user",
|
||||
@@ -244,7 +245,8 @@
|
||||
"command.datgrid.hideColumn": "Hide column",
|
||||
"command.designer": "Designer",
|
||||
"command.designer.arrange": "Arrange",
|
||||
"command.designer.exportDiagram": "Export diagram",
|
||||
"command.designer.exportDiagram": "Export diagram as HTML",
|
||||
"command.designer.exportDiagramPng": "Export diagram as PNG",
|
||||
"command.designer.openSql": "Open SQL",
|
||||
"command.designer.remove": "Remove",
|
||||
"command.designer.removeSelectedTables": "Remove selected tables",
|
||||
@@ -272,6 +274,11 @@
|
||||
"command.folder": "Folder",
|
||||
"command.folder.openData": "Open data folder",
|
||||
"command.folder.openLogs": "Open logs",
|
||||
"command.gqlConnection": "GraphQL Connection",
|
||||
"command.gqlConnection.toggleCellDataView": "Toggle cell data view",
|
||||
"command.gqlConnection.toggleCellDataView.menu": "Show cell data",
|
||||
"command.gqlConnection.toggleCellDataView.toolbar": "Cell Data",
|
||||
"command.graphql.chat": "GraphQL chat",
|
||||
"command.internal": "Internal",
|
||||
"command.internal.loadCampaigns": "Load campaign list",
|
||||
"command.internal.showCampaigns": "Show campaigns",
|
||||
@@ -294,12 +301,14 @@
|
||||
"command.new.connectionFolderToolbar": "Add connection folder",
|
||||
"command.new.diagram": "ER Diagram",
|
||||
"command.new.duckdbDatabase": "New DuckDB database",
|
||||
"command.new.graphqlQuery": "GraphQL Query",
|
||||
"command.new.jsonl": "JSON Lines",
|
||||
"command.new.markdown": "Markdown page",
|
||||
"command.new.modelCompare": "Compare DB",
|
||||
"command.new.modelTransform": "Model transform",
|
||||
"command.new.newApplication": "New application",
|
||||
"command.new.newDiagram": "New ER diagram",
|
||||
"command.new.newGraphqlQuery": "New GraphQL Query",
|
||||
"command.new.newJsonl": "New JSON lines file",
|
||||
"command.new.newModelTransform": "New model transform",
|
||||
"command.new.newPerspective": "New perspective",
|
||||
@@ -342,6 +351,8 @@
|
||||
"command.redisLikeData.save": "Save",
|
||||
"command.redo": "Redo",
|
||||
"command.replace": "Replace",
|
||||
"command.restApi": "REST API",
|
||||
"command.restApi.execute": "Execute",
|
||||
"command.save": "Save",
|
||||
"command.saveAs": "Save As",
|
||||
"command.saveToDisk": "Save to disk",
|
||||
@@ -432,6 +443,8 @@
|
||||
"common.fileType": "{extension} files",
|
||||
"common.files.allFiles": "All Files",
|
||||
"common.general": "General",
|
||||
"common.graphqlChat": "GraphQL Chat",
|
||||
"common.graphqlQuery": "GraphQL Query",
|
||||
"common.import": "Import",
|
||||
"common.kill": "Kill",
|
||||
"common.loadingData": "Loading data",
|
||||
@@ -534,6 +547,11 @@
|
||||
"connection.accessKeyId": "Access Key ID",
|
||||
"connection.allowedDatabases": "Allowed databases, one per line",
|
||||
"connection.allowedDatabasesRegex": "Allowed databases regular expression",
|
||||
"connection.apiKeyHeader": "API Key Header",
|
||||
"connection.apiKeyValue": "API Key Value",
|
||||
"connection.apiQuery": "API Query",
|
||||
"connection.apiServerUrl1": "API Server URL",
|
||||
"connection.apiServerUrl2": "API Secondary Server URL",
|
||||
"connection.askPassword": "Don't save, ask for password",
|
||||
"connection.askUser": "Don't save, ask for login and password",
|
||||
"connection.authToken": "Auth token",
|
||||
@@ -555,6 +573,7 @@
|
||||
"connection.databaseFilePath": "Database file (path on server)",
|
||||
"connection.databaseUrl": "Database URL",
|
||||
"connection.defaultDatabase": "Default database",
|
||||
"connection.defaultIsolationLevel": "Default isolation level",
|
||||
"connection.delete": "Delete",
|
||||
"connection.deleteConfirm": "Really delete connection {name}?",
|
||||
"connection.deleteFolderConfirm": "Really delete folder {folder}? Connections in folder will be moved into root folder.",
|
||||
@@ -567,6 +586,9 @@
|
||||
"connection.engine": "Database engine",
|
||||
"connection.engineDriverNotFound": "Engine driver {engine} not found, review installed plugins and change engine in edit connection dialog",
|
||||
"connection.fillDetails": "Fill database connection details",
|
||||
"connection.httpProxyPassword": "HTTP Proxy Password",
|
||||
"connection.httpProxyUrl": "HTTP Proxy URL",
|
||||
"connection.httpProxyUser": "HTTP Proxy User",
|
||||
"connection.isReadOnly": "Is read only",
|
||||
"connection.keySeparator": "Key separator",
|
||||
"connection.localDataCenter": "Local DataCenter",
|
||||
@@ -626,6 +648,7 @@
|
||||
"dataForm.noData": "No data",
|
||||
"dataForm.outOfBounds": "Out of bounds: {current} / {total}",
|
||||
"dataForm.rowCount": "Row: {current} / {total}",
|
||||
"dataForm.rowCountMany": "Row: {current} / Many",
|
||||
"dataGrid.chooseValue": "Choose value from {field}",
|
||||
"dataGrid.codeHighlighting": "Code highlighting:",
|
||||
"dataGrid.codeHighlighting.none": "None (raw text)",
|
||||
@@ -664,6 +687,7 @@
|
||||
"database.export": "Export",
|
||||
"database.exportDbModel": "Export DB model",
|
||||
"database.generateScript": "Generate script",
|
||||
"database.graphqlChat": "GraphQL chat",
|
||||
"database.import": "Import",
|
||||
"database.newApplication": "New application",
|
||||
"database.newCollection": "New collection/container",
|
||||
@@ -764,6 +788,7 @@
|
||||
"datagrid.openQuery": "Open Query",
|
||||
"datagrid.resetFilter": "Reset filter",
|
||||
"datagrid.resetView": "Reset view",
|
||||
"datagrid.rowCountMany": "Many",
|
||||
"datagrid.rows": "Rows",
|
||||
"datagrid.searchMacros": "Search macros",
|
||||
"datagrid.selectedInfo.count": "Count",
|
||||
@@ -771,6 +796,7 @@
|
||||
"datagrid.selectedInfo.sum": "Sum",
|
||||
"datagrid.setFormat": "Set format: ",
|
||||
"datagrid.structure": "Structure",
|
||||
"datagrid.structure.notLoaded": "No structure was loaded, probably table doesn't exist in current database",
|
||||
"datagrid.structure.waiting": "Waiting for structure",
|
||||
"datagrid.useMacro": "Use macro",
|
||||
"dbKeysTreeNode.deleteBranch": "Delete branch",
|
||||
@@ -836,6 +862,7 @@
|
||||
"designer.addAllTables": "Add all tables",
|
||||
"designer.all": "All",
|
||||
"designer.allKeys": "All Keys",
|
||||
"designer.chooseTableColor": "Choose table color",
|
||||
"designer.columnProperties": "Column properties",
|
||||
"designer.columns": "Columns - { filterColumns }",
|
||||
"designer.dataTypeYesNo": "Data type: {show}",
|
||||
@@ -900,7 +927,12 @@
|
||||
"file.queryDesignerFiles": "Query designer files",
|
||||
"file.sqlFiles": "SQL files",
|
||||
"file.sqliteDatabase": "SQLite database",
|
||||
"files.allConnections": "All connections",
|
||||
"files.allDatabases": "all databases",
|
||||
"files.allSupportedFiles": "All supported files",
|
||||
"files.clearConnectionFilter": "Clear connection filter",
|
||||
"files.connection": "Connection",
|
||||
"files.currentDatabase": "Current database",
|
||||
"files.openFile": "Open file",
|
||||
"files.refreshFiles": "Refresh files",
|
||||
"files.savedFiles": "Saved files",
|
||||
@@ -1060,6 +1092,7 @@
|
||||
"importExport.value": "Value",
|
||||
"indexEditor.filteredIndexCondition": "Filtered index condition",
|
||||
"indexEditor.indexName": "Index name",
|
||||
"indexEditor.indexType": "Index type",
|
||||
"indexEditor.isUnique": "Is unique index",
|
||||
"insertJoin.alias": "Alias",
|
||||
"insertJoin.columnFrom": "Column from",
|
||||
@@ -1135,6 +1168,10 @@
|
||||
"newObject.erDiagramDisabled": "ER Diagram is not available for current database",
|
||||
"newObject.exportDescription": "Export to file like CSV, JSON, Excel, or other DB",
|
||||
"newObject.exportDisabled": "Export is not available for current database",
|
||||
"newObject.graphqlChatDescription": "Chat with your GraphQL API using AI",
|
||||
"newObject.graphqlChatDisabled": "GraphQL chat is not available for current connection",
|
||||
"newObject.graphqlQueryDescription": "Write queries, choose attributes and arguments",
|
||||
"newObject.graphqlQueryDisabled": "GraphQL Query is not available for current database",
|
||||
"newObject.perspectiveDescription": "Join complex data from multiple databases",
|
||||
"newObject.queryDesignerDescription": "Design SQL queries visually",
|
||||
"newObject.queryDesignerDisabled": "Query Designer is not available for current database",
|
||||
@@ -1158,6 +1195,7 @@
|
||||
"privateCloudWidget.addNewConnectionOrFile": "Add new connection or file",
|
||||
"privateCloudWidget.addNewFolder": "Add new folder",
|
||||
"privateCloudWidget.administrateAccess": "Administrate access",
|
||||
"privateCloudWidget.cloudUnavailable": "DbGate Cloud is temporarily unavailable",
|
||||
"privateCloudWidget.createConnection": "Create connection on DbGate Cloud",
|
||||
"privateCloudWidget.createSharedFolder": "Create shared folder",
|
||||
"privateCloudWidget.deleteFolder": "Delete folder",
|
||||
@@ -1170,6 +1208,7 @@
|
||||
"privateCloudWidget.renameFolder": "Rename folder",
|
||||
"privateCloudWidget.searchPlaceholder": "Search cloud connections and files",
|
||||
"privateCloudWidget.yourInviteLink": "Your invite link (in form dbgate://folder/xxx)",
|
||||
"publicCloudWidget.cloudUnavailable": "DbGate Cloud is temporarily unavailable",
|
||||
"publicCloudWidget.noFilesFound": "No files found for your configuration",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Only files relevant for your connections, platform and DbGate edition are listed. Please define connections at first.",
|
||||
"publicCloudWidget.publicKnowledgeBase": "Public Knowledge Base",
|
||||
@@ -1191,10 +1230,13 @@
|
||||
"query.aggregate": "Aggregate",
|
||||
"query.alias": "Alias",
|
||||
"query.columnExpression": "Column/Expression",
|
||||
"query.defaultIsolationLevel": "Default",
|
||||
"query.defaultIsolationLevelNamed": "Default ({level})",
|
||||
"query.download": "download",
|
||||
"query.filter": "Filter",
|
||||
"query.groupBy": "Group by",
|
||||
"query.groupFilter": "Group filter",
|
||||
"query.isolationLevel": "Isolation level",
|
||||
"query.limitRows": "Limit {queryRowsLimit} rows",
|
||||
"query.named": ":variable",
|
||||
"query.noParameters": "(no parameters)",
|
||||
@@ -1287,6 +1329,7 @@
|
||||
"settings.behaviour.openDetailOnArrows": "Open detail on keyboard navigation",
|
||||
"settings.behaviour.singleClickPreview": "When you single-click or select a file in the \"Tables, Views, Functions\" view, it is shown in a preview mode and reuses an existing tab (preview tab). This is useful if you are quickly browsing tables and don\\'t want every visited table to have its own tab. When you start editing the table or use double-click to open the table from the \"Tables\" view, a new tab is dedicated to that table.",
|
||||
"settings.behaviour.useTabPreviewMode": "Use tab preview mode",
|
||||
"settings.checkAll": "Check all / Uncheck all",
|
||||
"settings.confirmations": "Confirmations",
|
||||
"settings.confirmations.skipConfirm.collectionDataSave": "Skip confirmation when saving collection data (NoSQL)",
|
||||
"settings.confirmations.skipConfirm.tableDataSave": "Skip confirmation when saving table data (SQL)",
|
||||
@@ -1305,6 +1348,7 @@
|
||||
"settings.dataGrid.coloringMode.36": "Every 3rd and 6th row",
|
||||
"settings.dataGrid.coloringMode.none": "None",
|
||||
"settings.dataGrid.defaultAutoRefreshInterval": "Default grid auto refresh interval in seconds",
|
||||
"settings.dataGrid.disableCellDataViewAutoOpen": "Disable automatic Cell Data View",
|
||||
"settings.dataGrid.pageSize": "Page size (number of rows for incremental loading, must be between 5 and 50000)",
|
||||
"settings.dataGrid.showAllColumnsWhenSearch": "Show all columns when searching",
|
||||
"settings.dataGrid.showHintColumns": "Show foreign key hints",
|
||||
@@ -1331,6 +1375,7 @@
|
||||
"settings.defaultActions.tableClick": "Table click",
|
||||
"settings.defaultActions.useLastUsedAction": "Use last used action",
|
||||
"settings.defaultActions.viewClick": "View click",
|
||||
"settings.drivers": "Drivers",
|
||||
"settings.editor.keybinds": "Editor keybinds",
|
||||
"settings.editor.wordWrap": "Enable word wrap",
|
||||
"settings.externalTools": "External Tools",
|
||||
@@ -1355,6 +1400,9 @@
|
||||
"settings.other.licenseKey.invalid": "License key is invalid",
|
||||
"settings.other.licenseKey.valid": "License key is valid",
|
||||
"settings.other.licenseKey.validTo": "License valid to:",
|
||||
"settings.other.toolBarPosition": "Tool bar position",
|
||||
"settings.other.toolBarPosition.bottom": "Bottom",
|
||||
"settings.other.toolBarPosition.top": "Top",
|
||||
"settings.session": "Query sessions",
|
||||
"settings.session.autoClose": "Automatic close query sessions after period without any activity",
|
||||
"settings.session.autoCloseTimeout": "Interval, after which query session without activity is closed (in minutes)",
|
||||
@@ -1393,6 +1441,7 @@
|
||||
"sqlGenerator.omitNulls": "Omit NULL values",
|
||||
"sqlGenerator.searchTablesOrObjects": "Search tables or objects",
|
||||
"sqlGenerator.skipAutoincrementColumn": "Skip autoincrement column",
|
||||
"sqlGenerator.skipComputedColumns": "Skip computed columns",
|
||||
"sqlGenerator.sqlGenerator": "SQL Generator",
|
||||
"sqlGenerator.sqlTruncated": "SQL truncated, file size limit exceed",
|
||||
"sqlGenerator.tables": "Tables",
|
||||
@@ -1467,6 +1516,7 @@
|
||||
"tableEditor.defaultValue": "Default value",
|
||||
"tableEditor.dependencies": "Dependencies",
|
||||
"tableEditor.foreignKeys": "Foreign keys ({foreignKeyCount})",
|
||||
"tableEditor.indexType": "Type",
|
||||
"tableEditor.indexes": "Indexes ({indexCount})",
|
||||
"tableEditor.isPersisted": "Is Persisted",
|
||||
"tableEditor.isSparse": "Is Sparse",
|
||||
@@ -1485,7 +1535,6 @@
|
||||
"tableEditor.remove": "Remove",
|
||||
"tableEditor.tablename": "Table name",
|
||||
"tableEditor.tableproperties": "Table properties",
|
||||
"tableEditor.unique": "Unique",
|
||||
"tableEditor.uniqueConstraints": "Unique constraints ({constraintCount})",
|
||||
"tableEditor.yes": "YES",
|
||||
"tableStructure.alter": "Alter table",
|
||||
@@ -1521,6 +1570,7 @@
|
||||
"widget.collectionsContainers": "Collections/containers",
|
||||
"widget.databaseContent": "Database content",
|
||||
"widget.databases": "Databases",
|
||||
"widget.endpoints": "Endpoints",
|
||||
"widget.keys": "Keys",
|
||||
"widget.pinned": "Pinned",
|
||||
"widget.tablesViewsFunctions": "Tables, views, functions",
|
||||
|
||||
+52
-2
@@ -113,6 +113,7 @@
|
||||
"command.about": "Acerca de",
|
||||
"command.about.show": "Mostrar",
|
||||
"command.about.toolbar": "Acerca de",
|
||||
"command.apiQuery": "Consulta API",
|
||||
"command.app.checkForUpdates": "Buscar actualizaciones",
|
||||
"command.app.disconnect": "Desconectar",
|
||||
"command.app.loggedUser": "Usuario conectado",
|
||||
@@ -245,6 +246,7 @@
|
||||
"command.designer": "Diseñador",
|
||||
"command.designer.arrange": "Organizar",
|
||||
"command.designer.exportDiagram": "Exportar diagrama",
|
||||
"command.designer.exportDiagramPng": "Exportar diagrama como PNG",
|
||||
"command.designer.openSql": "Abrir SQL",
|
||||
"command.designer.remove": "Eliminar",
|
||||
"command.designer.removeSelectedTables": "Eliminar tablas seleccionadas",
|
||||
@@ -272,6 +274,11 @@
|
||||
"command.folder": "Carpeta",
|
||||
"command.folder.openData": "Abrir carpeta de datos",
|
||||
"command.folder.openLogs": "Abrir registros",
|
||||
"command.gqlConnection": "Conexión GraphQL",
|
||||
"command.gqlConnection.toggleCellDataView": "Alternar vista de datos de celda",
|
||||
"command.gqlConnection.toggleCellDataView.menu": "Mostrar datos de celda",
|
||||
"command.gqlConnection.toggleCellDataView.toolbar": "Datos de celda",
|
||||
"command.graphql.chat": "Chat GraphQL",
|
||||
"command.internal": "Interno",
|
||||
"command.internal.loadCampaigns": "Cargar lista de campañas",
|
||||
"command.internal.showCampaigns": "Mostrar campañas",
|
||||
@@ -294,12 +301,14 @@
|
||||
"command.new.connectionFolderToolbar": "Agregar carpeta de conexión",
|
||||
"command.new.diagram": "Diagrama ER",
|
||||
"command.new.duckdbDatabase": "Nueva base de datos DuckDB",
|
||||
"command.new.graphqlQuery": "Consulta GraphQL",
|
||||
"command.new.jsonl": "Líneas JSON",
|
||||
"command.new.markdown": "Página Markdown",
|
||||
"command.new.modelCompare": "Comparar BD",
|
||||
"command.new.modelTransform": "Transformación de modelo",
|
||||
"command.new.newApplication": "Nueva aplicación",
|
||||
"command.new.newDiagram": "Nuevo diagrama ER",
|
||||
"command.new.newGraphqlQuery": "Nueva consulta GraphQL",
|
||||
"command.new.newJsonl": "Nuevo archivo de líneas JSON",
|
||||
"command.new.newModelTransform": "Nueva transformación de modelo",
|
||||
"command.new.newPerspective": "Nueva perspectiva",
|
||||
@@ -342,6 +351,8 @@
|
||||
"command.redisLikeData.save": "Guardar",
|
||||
"command.redo": "Rehacer",
|
||||
"command.replace": "Reemplazar",
|
||||
"command.restApi": "REST API",
|
||||
"command.restApi.execute": "Ejecutar",
|
||||
"command.save": "Guardar",
|
||||
"command.saveAs": "Guardar como",
|
||||
"command.saveToDisk": "Guardar en disco",
|
||||
@@ -432,6 +443,8 @@
|
||||
"common.fileType": "Archivos {extension}",
|
||||
"common.files.allFiles": "Todos los archivos",
|
||||
"common.general": "General",
|
||||
"common.graphqlChat": "Chat GraphQL",
|
||||
"common.graphqlQuery": "Consulta GraphQL",
|
||||
"common.import": "Importar",
|
||||
"common.kill": "Terminar",
|
||||
"common.loadingData": "Cargando datos",
|
||||
@@ -534,6 +547,11 @@
|
||||
"connection.accessKeyId": "ID de clave de acceso",
|
||||
"connection.allowedDatabases": "Bases de datos permitidas, una por línea",
|
||||
"connection.allowedDatabasesRegex": "Expresión regular de bases de datos permitidas",
|
||||
"connection.apiKeyHeader": "Encabezado de clave API",
|
||||
"connection.apiKeyValue": "Valor de clave API",
|
||||
"connection.apiQuery": "Consulta API",
|
||||
"connection.apiServerUrl1": "URL de servidor API",
|
||||
"connection.apiServerUrl2": "URL secundaria de servidor API",
|
||||
"connection.askPassword": "No guardar, preguntar por contraseña",
|
||||
"connection.askUser": "No guardar, preguntar por usuario y contraseña",
|
||||
"connection.authToken": "Token de autenticación",
|
||||
@@ -555,6 +573,7 @@
|
||||
"connection.databaseFilePath": "Archivo de base de datos (ruta en servidor)",
|
||||
"connection.databaseUrl": "URL de base de datos",
|
||||
"connection.defaultDatabase": "Base de datos predeterminada",
|
||||
"connection.defaultIsolationLevel": "Nivel de aislamiento predeterminado",
|
||||
"connection.delete": "Eliminar",
|
||||
"connection.deleteConfirm": "¿Realmente eliminar la conexión {name}?",
|
||||
"connection.deleteFolderConfirm": "¿Realmente eliminar la carpeta {folder}? Las conexiones en la carpeta se moverán a la carpeta raíz.",
|
||||
@@ -567,6 +586,9 @@
|
||||
"connection.engine": "Motor de base de datos",
|
||||
"connection.engineDriverNotFound": "Controlador de motor {engine} no encontrado, revise los plugins instalados y cambie el motor en el diálogo de edición de conexión",
|
||||
"connection.fillDetails": "Completar detalles de conexión de base de datos",
|
||||
"connection.httpProxyPassword": "Contraseña de proxy HTTP",
|
||||
"connection.httpProxyUrl": "URL de proxy HTTP",
|
||||
"connection.httpProxyUser": "Usuario de proxy HTTP",
|
||||
"connection.isReadOnly": "Es solo lectura",
|
||||
"connection.keySeparator": "Separador de claves",
|
||||
"connection.localDataCenter": "Centro de datos local",
|
||||
@@ -626,6 +648,7 @@
|
||||
"dataForm.noData": "Sin datos",
|
||||
"dataForm.outOfBounds": "Fuera de límites: {current} / {total}",
|
||||
"dataForm.rowCount": "Fila: {current} / {total}",
|
||||
"dataForm.rowCountMany": "Fila: {current} / Muchas",
|
||||
"dataGrid.chooseValue": "Elegir valor de {field}",
|
||||
"dataGrid.codeHighlighting": "Resaltado de código:",
|
||||
"dataGrid.codeHighlighting.none": "Ninguno (texto sin formato)",
|
||||
@@ -664,6 +687,7 @@
|
||||
"database.export": "Exportar",
|
||||
"database.exportDbModel": "Exportar modelo de BD",
|
||||
"database.generateScript": "Generar script",
|
||||
"database.graphqlChat": "Chat GraphQL",
|
||||
"database.import": "Importar",
|
||||
"database.newApplication": "Nueva aplicación",
|
||||
"database.newCollection": "Nueva colección/contenedor",
|
||||
@@ -764,6 +788,7 @@
|
||||
"datagrid.openQuery": "Abrir consulta",
|
||||
"datagrid.resetFilter": "Restablecer filtro",
|
||||
"datagrid.resetView": "Restablecer vista",
|
||||
"datagrid.rowCountMany": "Muchas",
|
||||
"datagrid.rows": "Filas",
|
||||
"datagrid.searchMacros": "Buscar macros",
|
||||
"datagrid.selectedInfo.count": "Cantidad",
|
||||
@@ -771,6 +796,7 @@
|
||||
"datagrid.selectedInfo.sum": "Suma",
|
||||
"datagrid.setFormat": "Establecer formato: ",
|
||||
"datagrid.structure": "Estructura",
|
||||
"datagrid.structure.notLoaded": "No se cargó ninguna estructura, probablemente la tabla no existe en la base de datos actual",
|
||||
"datagrid.structure.waiting": "Esperando estructura",
|
||||
"datagrid.useMacro": "Usar macro",
|
||||
"dbKeysTreeNode.deleteBranch": "Eliminar rama",
|
||||
@@ -836,6 +862,7 @@
|
||||
"designer.addAllTables": "Agregar todas las tablas",
|
||||
"designer.all": "Todo",
|
||||
"designer.allKeys": "Todas las claves",
|
||||
"designer.chooseTableColor": "Elegir color de tabla",
|
||||
"designer.columnProperties": "Propiedades de columna",
|
||||
"designer.columns": "Columnas - { filterColumns }",
|
||||
"designer.dataTypeYesNo": "Tipo de dato: {show}",
|
||||
@@ -900,7 +927,12 @@
|
||||
"file.queryDesignerFiles": "Archivos de diseñador de consultas",
|
||||
"file.sqlFiles": "Archivos SQL",
|
||||
"file.sqliteDatabase": "Base de datos SQLite",
|
||||
"files.allConnections": "Todas las conexiones",
|
||||
"files.allDatabases": "todas las bases de datos",
|
||||
"files.allSupportedFiles": "Todos los archivos soportados",
|
||||
"files.clearConnectionFilter": "Limpiar filtro de conexión",
|
||||
"files.connection": "Conexión",
|
||||
"files.currentDatabase": "Base de datos actual",
|
||||
"files.openFile": "Abrir archivo",
|
||||
"files.refreshFiles": "Refrescar archivos",
|
||||
"files.savedFiles": "Archivos guardados",
|
||||
@@ -1060,6 +1092,7 @@
|
||||
"importExport.value": "Valor",
|
||||
"indexEditor.filteredIndexCondition": "Condición de índice filtrado",
|
||||
"indexEditor.indexName": "Nombre de índice",
|
||||
"indexEditor.indexType": "Tipo de índice",
|
||||
"indexEditor.isUnique": "Es índice único",
|
||||
"insertJoin.alias": "Alias",
|
||||
"insertJoin.columnFrom": "Columna desde",
|
||||
@@ -1135,6 +1168,10 @@
|
||||
"newObject.erDiagramDisabled": "El diagrama ER no está disponible para la base de datos actual",
|
||||
"newObject.exportDescription": "Exportar a archivo como CSV, JSON, Excel u otra BD",
|
||||
"newObject.exportDisabled": "La exportación no está disponible para la base de datos actual",
|
||||
"newObject.graphqlChatDescription": "Chatear con su API GraphQL usando IA",
|
||||
"newObject.graphqlChatDisabled": "El chat GraphQL no está disponible para la conexión actual",
|
||||
"newObject.graphqlQueryDescription": "Escribir consultas, elegir atributos y argumentos",
|
||||
"newObject.graphqlQueryDisabled": "La consulta GraphQL no está disponible para la base de datos actual",
|
||||
"newObject.perspectiveDescription": "Unir datos complejos de múltiples bases de datos",
|
||||
"newObject.queryDesignerDescription": "Diseñar consultas SQL visualmente",
|
||||
"newObject.queryDesignerDisabled": "El diseñador de consultas no está disponible para la base de datos actual",
|
||||
@@ -1158,6 +1195,7 @@
|
||||
"privateCloudWidget.addNewConnectionOrFile": "Agregar nueva conexión o archivo",
|
||||
"privateCloudWidget.addNewFolder": "Agregar nueva carpeta",
|
||||
"privateCloudWidget.administrateAccess": "Administrar acceso",
|
||||
"privateCloudWidget.cloudUnavailable": "DbGate Cloud está temporalmente no disponible",
|
||||
"privateCloudWidget.createConnection": "Crear conexión en DbGate Cloud",
|
||||
"privateCloudWidget.createSharedFolder": "Crear carpeta compartida",
|
||||
"privateCloudWidget.deleteFolder": "Eliminar carpeta",
|
||||
@@ -1170,6 +1208,7 @@
|
||||
"privateCloudWidget.renameFolder": "Renombrar carpeta",
|
||||
"privateCloudWidget.searchPlaceholder": "Buscar conexiones y archivos en la nube",
|
||||
"privateCloudWidget.yourInviteLink": "Su enlace de invitación (en forma dbgate://folder/xxx)",
|
||||
"publicCloudWidget.cloudUnavailable": "DbGate Cloud está temporalmente no disponible",
|
||||
"publicCloudWidget.noFilesFound": "No se encontraron archivos para su configuración",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Solo se listan archivos relevantes para sus conexiones, plataforma y edición de DbGate. Defina primero las conexiones.",
|
||||
"publicCloudWidget.publicKnowledgeBase": "Base de conocimiento pública",
|
||||
@@ -1191,10 +1230,13 @@
|
||||
"query.aggregate": "Agregar",
|
||||
"query.alias": "Alias",
|
||||
"query.columnExpression": "Columna/Expresión",
|
||||
"query.defaultIsolationLevel": "Predeterminado",
|
||||
"query.defaultIsolationLevelNamed": "Predeterminado ({level})",
|
||||
"query.download": "descargar",
|
||||
"query.filter": "Filtro",
|
||||
"query.groupBy": "Agrupar por",
|
||||
"query.groupFilter": "Filtro de grupo",
|
||||
"query.isolationLevel": "Nivel de aislamiento",
|
||||
"query.limitRows": "Limitar {queryRowsLimit} filas",
|
||||
"query.named": ":variable",
|
||||
"query.noParameters": "(sin parámetros)",
|
||||
@@ -1287,6 +1329,7 @@
|
||||
"settings.behaviour.openDetailOnArrows": "Abrir detalle en navegación con teclado",
|
||||
"settings.behaviour.singleClickPreview": "Cuando hace clic único o selecciona un archivo en la vista \"Tablas, Vistas, Funciones\", se muestra en modo de vista previa y reutiliza una pestaña existente (pestaña de vista previa). Esto es útil si está navegando rápidamente por las tablas y no desea que cada tabla visitada tenga su propia pestaña. Cuando comience a editar la tabla o use doble clic para abrir la tabla desde la vista \"Tablas\", se dedica una nueva pestaña a esa tabla.",
|
||||
"settings.behaviour.useTabPreviewMode": "Usar modo de vista previa de pestaña",
|
||||
"settings.checkAll": "Seleccionar todo / Deseleccionar todo",
|
||||
"settings.confirmations": "Confirmaciones",
|
||||
"settings.confirmations.skipConfirm.collectionDataSave": "Omitir confirmación al guardar datos de colección (NoSQL)",
|
||||
"settings.confirmations.skipConfirm.tableDataSave": "Omitir confirmación al guardar datos de tabla (SQL)",
|
||||
@@ -1305,6 +1348,7 @@
|
||||
"settings.dataGrid.coloringMode.36": "Cada tercera y sexta fila",
|
||||
"settings.dataGrid.coloringMode.none": "Ninguno",
|
||||
"settings.dataGrid.defaultAutoRefreshInterval": "Intervalo predeterminado de recarga automática de cuadrícula en segundos",
|
||||
"settings.dataGrid.disableCellDataViewAutoOpen": "Deshabilitar vista de datos de celda automática",
|
||||
"settings.dataGrid.pageSize": "Tamaño de página (número de filas para carga incremental, debe estar entre 5 y 50000)",
|
||||
"settings.dataGrid.showAllColumnsWhenSearch": "Mostrar todas las columnas al buscar",
|
||||
"settings.dataGrid.showHintColumns": "Mostrar sugerencias de claves foráneas",
|
||||
@@ -1331,6 +1375,7 @@
|
||||
"settings.defaultActions.tableClick": "Clic en tabla",
|
||||
"settings.defaultActions.useLastUsedAction": "Usar última acción utilizada",
|
||||
"settings.defaultActions.viewClick": "Clic en vista",
|
||||
"settings.drivers": "Controladores",
|
||||
"settings.editor.keybinds": "Atajos de teclado del editor",
|
||||
"settings.editor.wordWrap": "Habilitar ajuste de línea",
|
||||
"settings.externalTools": "Herramientas externas",
|
||||
@@ -1355,6 +1400,9 @@
|
||||
"settings.other.licenseKey.invalid": "La clave de licencia no es válida",
|
||||
"settings.other.licenseKey.valid": "La clave de licencia es válida",
|
||||
"settings.other.licenseKey.validTo": "Licencia válida hasta:",
|
||||
"settings.other.toolBarPosition": "Posición de barra de herramientas",
|
||||
"settings.other.toolBarPosition.bottom": "Abajo",
|
||||
"settings.other.toolBarPosition.top": "Arriba",
|
||||
"settings.session": "Sesiones de consulta",
|
||||
"settings.session.autoClose": "Cerrar automáticamente las sesiones de consulta después de un período sin actividad",
|
||||
"settings.session.autoCloseTimeout": "Intervalo después del cual se cierra la sesión de consulta sin actividad (en minutos)",
|
||||
@@ -1393,6 +1441,7 @@
|
||||
"sqlGenerator.omitNulls": "Omitir valores NULL",
|
||||
"sqlGenerator.searchTablesOrObjects": "Buscar tablas u objetos",
|
||||
"sqlGenerator.skipAutoincrementColumn": "Omitir columna autoincremental",
|
||||
"sqlGenerator.skipComputedColumns": "Omitir columnas calculadas",
|
||||
"sqlGenerator.sqlGenerator": "Generador SQL",
|
||||
"sqlGenerator.sqlTruncated": "SQL truncado, se excedió el límite de tamaño de archivo",
|
||||
"sqlGenerator.tables": "Tablas",
|
||||
@@ -1467,6 +1516,7 @@
|
||||
"tableEditor.defaultValue": "Valor predeterminado",
|
||||
"tableEditor.dependencies": "Dependencias",
|
||||
"tableEditor.foreignKeys": "Claves foráneas ({foreignKeyCount})",
|
||||
"tableEditor.indexType": "Tipo",
|
||||
"tableEditor.indexes": "Índices ({indexCount})",
|
||||
"tableEditor.isPersisted": "Es persistente",
|
||||
"tableEditor.isSparse": "Es dispersa",
|
||||
@@ -1485,7 +1535,6 @@
|
||||
"tableEditor.remove": "Eliminar",
|
||||
"tableEditor.tablename": "Nombre de tabla",
|
||||
"tableEditor.tableproperties": "Propiedades de la tabla",
|
||||
"tableEditor.unique": "Único",
|
||||
"tableEditor.uniqueConstraints": "Restricciones únicas ({constraintCount})",
|
||||
"tableEditor.yes": "SÍ",
|
||||
"tableStructure.alter": "Modificar tabla",
|
||||
@@ -1521,6 +1570,7 @@
|
||||
"widget.collectionsContainers": "Colecciones/contenedores",
|
||||
"widget.databaseContent": "Contenido de la base de datos",
|
||||
"widget.databases": "Bases de datos",
|
||||
"widget.endpoints": "Endpoints",
|
||||
"widget.keys": "Claves",
|
||||
"widget.pinned": "Anclado",
|
||||
"widget.tablesViewsFunctions": "Tablas, vistas, funciones",
|
||||
@@ -1535,4 +1585,4 @@
|
||||
"widgets.openedTabs": "Pestañas abiertas",
|
||||
"widgets.premiumPromo": "Promoción Premium",
|
||||
"widgets.queryHistoryAndClosedTabs": "Historial de consultas y pestañas cerradas"
|
||||
}
|
||||
}
|
||||
|
||||
+52
-2
@@ -113,6 +113,7 @@
|
||||
"command.about": "À propos",
|
||||
"command.about.show": "Afficher",
|
||||
"command.about.toolbar": "À propos",
|
||||
"command.apiQuery": "Requête API",
|
||||
"command.app.checkForUpdates": "Vérifier les mises à jour",
|
||||
"command.app.disconnect": "Déconnecter",
|
||||
"command.app.loggedUser": "Utilisateur connecté",
|
||||
@@ -245,6 +246,7 @@
|
||||
"command.designer": "Concepteur",
|
||||
"command.designer.arrange": "Organiser",
|
||||
"command.designer.exportDiagram": "Exporter le diagramme",
|
||||
"command.designer.exportDiagramPng": "Exporter le diagramme en PNG",
|
||||
"command.designer.openSql": "Ouvrir SQL",
|
||||
"command.designer.remove": "Supprimer",
|
||||
"command.designer.removeSelectedTables": "Supprimer les tables sélectionnées",
|
||||
@@ -272,6 +274,11 @@
|
||||
"command.folder": "Dossier",
|
||||
"command.folder.openData": "Ouvrir le dossier de données",
|
||||
"command.folder.openLogs": "Ouvrir les journaux",
|
||||
"command.gqlConnection": "Connexion GraphQL",
|
||||
"command.gqlConnection.toggleCellDataView": "Basculer la vue des données de cellule",
|
||||
"command.gqlConnection.toggleCellDataView.menu": "Afficher les données de cellule",
|
||||
"command.gqlConnection.toggleCellDataView.toolbar": "Données de cellule",
|
||||
"command.graphql.chat": "Chat GraphQL",
|
||||
"command.internal": "Interne",
|
||||
"command.internal.loadCampaigns": "Charger la liste des campagnes",
|
||||
"command.internal.showCampaigns": "Afficher les campagnes",
|
||||
@@ -294,12 +301,14 @@
|
||||
"command.new.connectionFolderToolbar": "Ajouter un dossier de connexion",
|
||||
"command.new.diagram": "Diagramme ER",
|
||||
"command.new.duckdbDatabase": "Nouvelle base de données DuckDB",
|
||||
"command.new.graphqlQuery": "Requête GraphQL",
|
||||
"command.new.jsonl": "Lignes JSON",
|
||||
"command.new.markdown": "Page Markdown",
|
||||
"command.new.modelCompare": "Comparer les bases de données",
|
||||
"command.new.modelTransform": "Transformation de modèle",
|
||||
"command.new.newApplication": "Nouvelle application",
|
||||
"command.new.newDiagram": "Nouveau diagramme ER",
|
||||
"command.new.newGraphqlQuery": "Nouvelle requête GraphQL",
|
||||
"command.new.newJsonl": "Nouveau fichier de lignes JSON",
|
||||
"command.new.newModelTransform": "Nouvelle transformation de modèle",
|
||||
"command.new.newPerspective": "Nouvelle perspective",
|
||||
@@ -342,6 +351,8 @@
|
||||
"command.redisLikeData.save": "Enregistrer",
|
||||
"command.redo": "Rétablir",
|
||||
"command.replace": "Remplacer",
|
||||
"command.restApi": "API REST",
|
||||
"command.restApi.execute": "Exécuter",
|
||||
"command.save": "Enregistrer",
|
||||
"command.saveAs": "Enregistrer sous",
|
||||
"command.saveToDisk": "Enregistrer sur le disque",
|
||||
@@ -432,6 +443,8 @@
|
||||
"common.fileType": "Fichiers {extension}",
|
||||
"common.files.allFiles": "Tous les fichiers",
|
||||
"common.general": "Général",
|
||||
"common.graphqlChat": "Chat GraphQL",
|
||||
"common.graphqlQuery": "Requête GraphQL",
|
||||
"common.import": "Importer",
|
||||
"common.kill": "Tuer",
|
||||
"common.loadingData": "Chargement des données",
|
||||
@@ -534,6 +547,11 @@
|
||||
"connection.accessKeyId": "ID de clé d'accès",
|
||||
"connection.allowedDatabases": "Bases de données autorisées, une par ligne",
|
||||
"connection.allowedDatabasesRegex": "Expression régulière des bases de données autorisées",
|
||||
"connection.apiKeyHeader": "En-tête de clé API",
|
||||
"connection.apiKeyValue": "Valeur de clé API",
|
||||
"connection.apiQuery": "Requête API",
|
||||
"connection.apiServerUrl1": "URL du serveur API",
|
||||
"connection.apiServerUrl2": "URL secondaire du serveur API",
|
||||
"connection.askPassword": "Ne pas enregistrer, demander le mot de passe",
|
||||
"connection.askUser": "Ne pas enregistrer, demander l'identifiant et le mot de passe",
|
||||
"connection.authToken": "Jeton d'authentification",
|
||||
@@ -555,6 +573,7 @@
|
||||
"connection.databaseFilePath": "Fichier de base de données (chemin sur le serveur)",
|
||||
"connection.databaseUrl": "URL de la base de données",
|
||||
"connection.defaultDatabase": "Base de données par défaut",
|
||||
"connection.defaultIsolationLevel": "Niveau d'isolation par défaut",
|
||||
"connection.delete": "Supprimer",
|
||||
"connection.deleteConfirm": "Vraiment supprimer la connexion {name} ?",
|
||||
"connection.deleteFolderConfirm": "Vraiment supprimer le dossier {folder} ? Les connexions du dossier seront déplacées dans le dossier racine.",
|
||||
@@ -567,6 +586,9 @@
|
||||
"connection.engine": "Moteur de base de données",
|
||||
"connection.engineDriverNotFound": "Pilote du moteur {engine} introuvable, vérifiez les plugins installés et modifiez le moteur dans la boîte de dialogue de modification de connexion",
|
||||
"connection.fillDetails": "Remplir les détails de connexion à la base de données",
|
||||
"connection.httpProxyPassword": "Mot de passe du proxy HTTP",
|
||||
"connection.httpProxyUrl": "URL du proxy HTTP",
|
||||
"connection.httpProxyUser": "Utilisateur du proxy HTTP",
|
||||
"connection.isReadOnly": "Lecture seule",
|
||||
"connection.keySeparator": "Séparateur de clé",
|
||||
"connection.localDataCenter": "Centre de données local",
|
||||
@@ -626,6 +648,7 @@
|
||||
"dataForm.noData": "Aucune donnée",
|
||||
"dataForm.outOfBounds": "Hors limites : {current} / {total}",
|
||||
"dataForm.rowCount": "Ligne : {current} / {total}",
|
||||
"dataForm.rowCountMany": "Ligne : {current} / Plusieurs",
|
||||
"dataGrid.chooseValue": "Choisir une valeur de {field}",
|
||||
"dataGrid.codeHighlighting": "Coloration syntaxique :",
|
||||
"dataGrid.codeHighlighting.none": "Aucune (texte brut)",
|
||||
@@ -664,6 +687,7 @@
|
||||
"database.export": "Exporter",
|
||||
"database.exportDbModel": "Exporter le modèle de base de données",
|
||||
"database.generateScript": "Générer un script",
|
||||
"database.graphqlChat": "Chat GraphQL",
|
||||
"database.import": "Importer",
|
||||
"database.newApplication": "Nouvelle application",
|
||||
"database.newCollection": "Nouvelle collection/conteneur",
|
||||
@@ -764,6 +788,7 @@
|
||||
"datagrid.openQuery": "Ouvrir la requête",
|
||||
"datagrid.resetFilter": "Réinitialiser le filtre",
|
||||
"datagrid.resetView": "Réinitialiser la vue",
|
||||
"datagrid.rowCountMany": "Plusieurs",
|
||||
"datagrid.rows": "Lignes",
|
||||
"datagrid.searchMacros": "Rechercher des macros",
|
||||
"datagrid.selectedInfo.count": "Nombre",
|
||||
@@ -771,6 +796,7 @@
|
||||
"datagrid.selectedInfo.sum": "Somme",
|
||||
"datagrid.setFormat": "Définir le format : ",
|
||||
"datagrid.structure": "Structure",
|
||||
"datagrid.structure.notLoaded": "Aucune structure n'a été chargée, la table n'existe probablement pas dans la base de données actuelle",
|
||||
"datagrid.structure.waiting": "En attente de la structure",
|
||||
"datagrid.useMacro": "Utiliser la macro",
|
||||
"dbKeysTreeNode.deleteBranch": "Supprimer la branche",
|
||||
@@ -836,6 +862,7 @@
|
||||
"designer.addAllTables": "Ajouter toutes les tables",
|
||||
"designer.all": "Tout",
|
||||
"designer.allKeys": "Toutes les clés",
|
||||
"designer.chooseTableColor": "Choisir la couleur de la table",
|
||||
"designer.columnProperties": "Propriétés de colonne",
|
||||
"designer.columns": "Colonnes - { filterColumns }",
|
||||
"designer.dataTypeYesNo": "Type de données : {show}",
|
||||
@@ -900,7 +927,12 @@
|
||||
"file.queryDesignerFiles": "Fichiers du concepteur de requêtes",
|
||||
"file.sqlFiles": "Fichiers SQL",
|
||||
"file.sqliteDatabase": "Base de données SQLite",
|
||||
"files.allConnections": "Toutes les connexions",
|
||||
"files.allDatabases": "toutes les bases de données",
|
||||
"files.allSupportedFiles": "Tous les fichiers pris en charge",
|
||||
"files.clearConnectionFilter": "Effacer le filtre de connexion",
|
||||
"files.connection": "Connexion",
|
||||
"files.currentDatabase": "Base de données actuelle",
|
||||
"files.openFile": "Ouvrir le fichier",
|
||||
"files.refreshFiles": "Rafraîchir les fichiers",
|
||||
"files.savedFiles": "Fichiers enregistrés",
|
||||
@@ -1060,6 +1092,7 @@
|
||||
"importExport.value": "Valeur",
|
||||
"indexEditor.filteredIndexCondition": "Condition d'index filtré",
|
||||
"indexEditor.indexName": "Nom de l'index",
|
||||
"indexEditor.indexType": "Type d'index",
|
||||
"indexEditor.isUnique": "Est un index unique",
|
||||
"insertJoin.alias": "Alias",
|
||||
"insertJoin.columnFrom": "Colonne de",
|
||||
@@ -1135,6 +1168,10 @@
|
||||
"newObject.erDiagramDisabled": "Le diagramme ER n'est pas disponible pour la base de données actuelle",
|
||||
"newObject.exportDescription": "Exporter vers un fichier comme CSV, JSON, Excel ou autre BD",
|
||||
"newObject.exportDisabled": "L'exportation n'est pas disponible pour la base de données actuelle",
|
||||
"newObject.graphqlChatDescription": "Discuter avec votre API GraphQL à l'aide de l'IA",
|
||||
"newObject.graphqlChatDisabled": "Le chat GraphQL n'est pas disponible pour la connexion actuelle",
|
||||
"newObject.graphqlQueryDescription": "Écrire des requêtes, choisir des attributs et des arguments",
|
||||
"newObject.graphqlQueryDisabled": "La requête GraphQL n'est pas disponible pour la base de données actuelle",
|
||||
"newObject.perspectiveDescription": "Joindre des données complexes de plusieurs bases de données",
|
||||
"newObject.queryDesignerDescription": "Concevoir des requêtes SQL visuellement",
|
||||
"newObject.queryDesignerDisabled": "Le concepteur de requêtes n'est pas disponible pour la base de données actuelle",
|
||||
@@ -1158,6 +1195,7 @@
|
||||
"privateCloudWidget.addNewConnectionOrFile": "Ajouter une nouvelle connexion ou un fichier",
|
||||
"privateCloudWidget.addNewFolder": "Ajouter un nouveau dossier",
|
||||
"privateCloudWidget.administrateAccess": "Gérer les accès",
|
||||
"privateCloudWidget.cloudUnavailable": "DbGate Cloud est temporairement indisponible",
|
||||
"privateCloudWidget.createConnection": "Créer une connexion sur DbGate Cloud",
|
||||
"privateCloudWidget.createSharedFolder": "Créer un dossier partagé",
|
||||
"privateCloudWidget.deleteFolder": "Supprimer le dossier",
|
||||
@@ -1170,6 +1208,7 @@
|
||||
"privateCloudWidget.renameFolder": "Renommer le dossier",
|
||||
"privateCloudWidget.searchPlaceholder": "Rechercher des connexions et fichiers cloud",
|
||||
"privateCloudWidget.yourInviteLink": "Votre lien d'invitation (sous la forme dbgate://folder/xxx)",
|
||||
"publicCloudWidget.cloudUnavailable": "DbGate Cloud est temporairement indisponible",
|
||||
"publicCloudWidget.noFilesFound": "Aucun fichier trouvé pour votre configuration",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Seuls les fichiers pertinents pour vos connexions, votre plateforme et votre édition de DbGate sont listés. Veuillez d'abord définir des connexions.",
|
||||
"publicCloudWidget.publicKnowledgeBase": "Base de connaissances publique",
|
||||
@@ -1191,10 +1230,13 @@
|
||||
"query.aggregate": "Agrégat",
|
||||
"query.alias": "Alias",
|
||||
"query.columnExpression": "Colonne/Expression",
|
||||
"query.defaultIsolationLevel": "Par défaut",
|
||||
"query.defaultIsolationLevelNamed": "Par défaut ({level})",
|
||||
"query.download": "télécharger",
|
||||
"query.filter": "Filtre",
|
||||
"query.groupBy": "Grouper par",
|
||||
"query.groupFilter": "Filtre de groupe",
|
||||
"query.isolationLevel": "Niveau d'isolation",
|
||||
"query.limitRows": "Limiter à {queryRowsLimit} lignes",
|
||||
"query.named": ":variable",
|
||||
"query.noParameters": "(aucun paramètre)",
|
||||
@@ -1287,6 +1329,7 @@
|
||||
"settings.behaviour.openDetailOnArrows": "Ouvrir les détails lors de la navigation au clavier",
|
||||
"settings.behaviour.singleClickPreview": "Lorsque vous cliquez une fois ou sélectionnez un fichier dans la vue \"Tables, Vues, Fonctions\", il est affiché en mode aperçu et réutilise un onglet existant (onglet d'aperçu). Ceci est utile si vous parcourez rapidement les tables et ne voulez pas que chaque table visitée ait son propre onglet. Lorsque vous commencez à éditer la table ou utilisez le double-clic pour ouvrir la table depuis la vue \"Tables\", un nouvel onglet est dédié à cette table.",
|
||||
"settings.behaviour.useTabPreviewMode": "Utiliser le mode aperçu d'onglet",
|
||||
"settings.checkAll": "Tout cocher / Tout décocher",
|
||||
"settings.confirmations": "Confirmations",
|
||||
"settings.confirmations.skipConfirm.collectionDataSave": "Ignorer la confirmation lors de l'enregistrement des données de collection (NoSQL)",
|
||||
"settings.confirmations.skipConfirm.tableDataSave": "Ignorer la confirmation lors de l'enregistrement des données de table (SQL)",
|
||||
@@ -1305,6 +1348,7 @@
|
||||
"settings.dataGrid.coloringMode.36": "Chaque 3e et 6e ligne",
|
||||
"settings.dataGrid.coloringMode.none": "Aucun",
|
||||
"settings.dataGrid.defaultAutoRefreshInterval": "Intervalle par défaut de rafraîchissement automatique de la grille en secondes",
|
||||
"settings.dataGrid.disableCellDataViewAutoOpen": "Désactiver l'ouverture automatique de la vue des données de cellule",
|
||||
"settings.dataGrid.pageSize": "Taille de page (nombre de lignes pour le chargement incrémental, doit être entre 5 et 50000)",
|
||||
"settings.dataGrid.showAllColumnsWhenSearch": "Afficher toutes les colonnes lors de la recherche",
|
||||
"settings.dataGrid.showHintColumns": "Afficher les indices de clé étrangère",
|
||||
@@ -1331,6 +1375,7 @@
|
||||
"settings.defaultActions.tableClick": "Clic sur table",
|
||||
"settings.defaultActions.useLastUsedAction": "Utiliser la dernière action utilisée",
|
||||
"settings.defaultActions.viewClick": "Clic sur vue",
|
||||
"settings.drivers": "Pilotes",
|
||||
"settings.editor.keybinds": "Raccourcis clavier de l'éditeur",
|
||||
"settings.editor.wordWrap": "Activer le retour à la ligne",
|
||||
"settings.externalTools": "Outils externes",
|
||||
@@ -1355,6 +1400,9 @@
|
||||
"settings.other.licenseKey.invalid": "La clé de licence n'est pas valide",
|
||||
"settings.other.licenseKey.valid": "La clé de licence est valide",
|
||||
"settings.other.licenseKey.validTo": "Licence valide jusqu'au :",
|
||||
"settings.other.toolBarPosition": "Position de la barre d'outils",
|
||||
"settings.other.toolBarPosition.bottom": "Bas",
|
||||
"settings.other.toolBarPosition.top": "Haut",
|
||||
"settings.session": "Sessions de requêtes",
|
||||
"settings.session.autoClose": "Fermeture automatique des sessions de requêtes après une période sans activité",
|
||||
"settings.session.autoCloseTimeout": "Intervalle après lequel une session de requête sans activité est fermée (en minutes)",
|
||||
@@ -1393,6 +1441,7 @@
|
||||
"sqlGenerator.omitNulls": "Omettre les valeurs NULL",
|
||||
"sqlGenerator.searchTablesOrObjects": "Rechercher des tables ou des objets",
|
||||
"sqlGenerator.skipAutoincrementColumn": "Ignorer la colonne auto-incrémentée",
|
||||
"sqlGenerator.skipComputedColumns": "Ignorer les colonnes calculées",
|
||||
"sqlGenerator.sqlGenerator": "Générateur SQL",
|
||||
"sqlGenerator.sqlTruncated": "SQL tronqué, taille de fichier dépassée",
|
||||
"sqlGenerator.tables": "Tables",
|
||||
@@ -1467,6 +1516,7 @@
|
||||
"tableEditor.defaultValue": "Valeur par défaut",
|
||||
"tableEditor.dependencies": "Dépendances",
|
||||
"tableEditor.foreignKeys": "Clés étrangères ({foreignKeyCount})",
|
||||
"tableEditor.indexType": "Type",
|
||||
"tableEditor.indexes": "Index ({indexCount})",
|
||||
"tableEditor.isPersisted": "Valeur persistée",
|
||||
"tableEditor.isSparse": "Est Sparse",
|
||||
@@ -1485,7 +1535,6 @@
|
||||
"tableEditor.remove": "Supprimer",
|
||||
"tableEditor.tablename": "Nom de table",
|
||||
"tableEditor.tableproperties": "Propriétés de la table",
|
||||
"tableEditor.unique": "Unique",
|
||||
"tableEditor.uniqueConstraints": "Contraintes uniques ({constraintCount})",
|
||||
"tableEditor.yes": "OUI",
|
||||
"tableStructure.alter": "Modifier la table",
|
||||
@@ -1521,6 +1570,7 @@
|
||||
"widget.collectionsContainers": "Collections/conteneurs",
|
||||
"widget.databaseContent": "Contenu de la base de données",
|
||||
"widget.databases": "Bases de données",
|
||||
"widget.endpoints": "Points de terminaison",
|
||||
"widget.keys": "Clés",
|
||||
"widget.pinned": "Épinglé",
|
||||
"widget.tablesViewsFunctions": "Tables, vues, fonctions",
|
||||
@@ -1535,4 +1585,4 @@
|
||||
"widgets.openedTabs": "Onglets ouverts",
|
||||
"widgets.premiumPromo": "Promotion Premium",
|
||||
"widgets.queryHistoryAndClosedTabs": "Historique des requêtes et onglets fermés"
|
||||
}
|
||||
}
|
||||
|
||||
+52
-2
@@ -113,6 +113,7 @@
|
||||
"command.about": "Informazioni",
|
||||
"command.about.show": "Mostra",
|
||||
"command.about.toolbar": "Informazioni",
|
||||
"command.apiQuery": "Query API",
|
||||
"command.app.checkForUpdates": "Verifica aggiornamenti",
|
||||
"command.app.disconnect": "Disconnetti",
|
||||
"command.app.loggedUser": "Utente connesso",
|
||||
@@ -245,6 +246,7 @@
|
||||
"command.designer": "Designer",
|
||||
"command.designer.arrange": "Disponi",
|
||||
"command.designer.exportDiagram": "Esporta diagramma",
|
||||
"command.designer.exportDiagramPng": "Esporta diagramma come PNG",
|
||||
"command.designer.openSql": "Apri SQL",
|
||||
"command.designer.remove": "Rimuovi",
|
||||
"command.designer.removeSelectedTables": "Rimuovi tabelle selezionate",
|
||||
@@ -272,6 +274,11 @@
|
||||
"command.folder": "Cartella",
|
||||
"command.folder.openData": "Apri cartella dati",
|
||||
"command.folder.openLogs": "Apri log",
|
||||
"command.gqlConnection": "Connessione GraphQL",
|
||||
"command.gqlConnection.toggleCellDataView": "Attiva/Disattiva vista dati cella",
|
||||
"command.gqlConnection.toggleCellDataView.menu": "Mostra dati cella",
|
||||
"command.gqlConnection.toggleCellDataView.toolbar": "Dati cella",
|
||||
"command.graphql.chat": "Chat GraphQL",
|
||||
"command.internal": "Interno",
|
||||
"command.internal.loadCampaigns": "Carica elenco campagne",
|
||||
"command.internal.showCampaigns": "Mostra campagne",
|
||||
@@ -294,12 +301,14 @@
|
||||
"command.new.connectionFolderToolbar": "Aggiungi cartella connessioni",
|
||||
"command.new.diagram": "Diagramma ER",
|
||||
"command.new.duckdbDatabase": "Nuovo database DuckDB",
|
||||
"command.new.graphqlQuery": "Query GraphQL",
|
||||
"command.new.jsonl": "JSON Lines",
|
||||
"command.new.markdown": "Pagina Markdown",
|
||||
"command.new.modelCompare": "Confronta DB",
|
||||
"command.new.modelTransform": "Trasforma modello",
|
||||
"command.new.newApplication": "Nuova applicazione",
|
||||
"command.new.newDiagram": "Nuovo diagramma ER",
|
||||
"command.new.newGraphqlQuery": "Nuova query GraphQL",
|
||||
"command.new.newJsonl": "Nuovo file JSON lines",
|
||||
"command.new.newModelTransform": "Nuova trasformazione modello",
|
||||
"command.new.newPerspective": "Nuova prospettiva",
|
||||
@@ -342,6 +351,8 @@
|
||||
"command.redisLikeData.save": "Salva",
|
||||
"command.redo": "Ripeti",
|
||||
"command.replace": "Sostituisci",
|
||||
"command.restApi": "REST API",
|
||||
"command.restApi.execute": "Esegui",
|
||||
"command.save": "Salva",
|
||||
"command.saveAs": "Salva come",
|
||||
"command.saveToDisk": "Salva su disco",
|
||||
@@ -432,6 +443,8 @@
|
||||
"common.fileType": "File {extension}",
|
||||
"common.files.allFiles": "Tutti i file",
|
||||
"common.general": "Generale",
|
||||
"common.graphqlChat": "Chat GraphQL",
|
||||
"common.graphqlQuery": "Query GraphQL",
|
||||
"common.import": "Importa",
|
||||
"common.kill": "Termina",
|
||||
"common.loadingData": "Caricamento dati",
|
||||
@@ -534,6 +547,11 @@
|
||||
"connection.accessKeyId": "Access Key ID",
|
||||
"connection.allowedDatabases": "Database consentiti, uno per riga",
|
||||
"connection.allowedDatabasesRegex": "Espressione regolare database consentiti",
|
||||
"connection.apiKeyHeader": "Header API Key",
|
||||
"connection.apiKeyValue": "Valore API Key",
|
||||
"connection.apiQuery": "Query API",
|
||||
"connection.apiServerUrl1": "URL server API",
|
||||
"connection.apiServerUrl2": "URL server API secondario",
|
||||
"connection.askPassword": "Non salvare, richiedi password",
|
||||
"connection.askUser": "Non salvare, richiedi login e password",
|
||||
"connection.authToken": "Token di autenticazione",
|
||||
@@ -555,6 +573,7 @@
|
||||
"connection.databaseFilePath": "File database (percorso sul server)",
|
||||
"connection.databaseUrl": "URL database",
|
||||
"connection.defaultDatabase": "Database predefinito",
|
||||
"connection.defaultIsolationLevel": "Livello di isolamento predefinito",
|
||||
"connection.delete": "Elimina",
|
||||
"connection.deleteConfirm": "Eliminare davvero la connessione {name}?",
|
||||
"connection.deleteFolderConfirm": "Eliminare davvero la cartella {folder}? Le connessioni nella cartella saranno spostate nella cartella radice.",
|
||||
@@ -567,6 +586,9 @@
|
||||
"connection.engine": "Motore database",
|
||||
"connection.engineDriverNotFound": "Driver motore {engine} non trovato, rivedi i plugin installati e cambia motore nella finestra di modifica connessione",
|
||||
"connection.fillDetails": "Compila dettagli connessione database",
|
||||
"connection.httpProxyPassword": "Password proxy HTTP",
|
||||
"connection.httpProxyUrl": "URL proxy HTTP",
|
||||
"connection.httpProxyUser": "Utente proxy HTTP",
|
||||
"connection.isReadOnly": "È sola lettura",
|
||||
"connection.keySeparator": "Separatore chiavi",
|
||||
"connection.localDataCenter": "DataCenter locale",
|
||||
@@ -626,6 +648,7 @@
|
||||
"dataForm.noData": "Nessun dato",
|
||||
"dataForm.outOfBounds": "Fuori limite: {current} / {total}",
|
||||
"dataForm.rowCount": "Riga: {current} / {total}",
|
||||
"dataForm.rowCountMany": "Riga: {current} / Molte",
|
||||
"dataGrid.chooseValue": "Scegli valore da {field}",
|
||||
"dataGrid.codeHighlighting": "Evidenziazione codice:",
|
||||
"dataGrid.codeHighlighting.none": "Nessuna (testo grezzo)",
|
||||
@@ -664,6 +687,7 @@
|
||||
"database.export": "Esporta",
|
||||
"database.exportDbModel": "Esporta modello DB",
|
||||
"database.generateScript": "Genera script",
|
||||
"database.graphqlChat": "Chat GraphQL",
|
||||
"database.import": "Importa",
|
||||
"database.newApplication": "Nuova applicazione",
|
||||
"database.newCollection": "Nuova collezione/container",
|
||||
@@ -764,6 +788,7 @@
|
||||
"datagrid.openQuery": "Apri query",
|
||||
"datagrid.resetFilter": "Ripristina filtro",
|
||||
"datagrid.resetView": "Ripristina vista",
|
||||
"datagrid.rowCountMany": "Molte",
|
||||
"datagrid.rows": "Righe",
|
||||
"datagrid.searchMacros": "Cerca macro",
|
||||
"datagrid.selectedInfo.count": "Conteggio",
|
||||
@@ -771,6 +796,7 @@
|
||||
"datagrid.selectedInfo.sum": "Somma",
|
||||
"datagrid.setFormat": "Imposta formato: ",
|
||||
"datagrid.structure": "Struttura",
|
||||
"datagrid.structure.notLoaded": "Nessuna struttura caricata, probabilmente la tabella non esiste nel database corrente",
|
||||
"datagrid.structure.waiting": "In attesa della struttura",
|
||||
"datagrid.useMacro": "Usa macro",
|
||||
"dbKeysTreeNode.deleteBranch": "Elimina ramo",
|
||||
@@ -836,6 +862,7 @@
|
||||
"designer.addAllTables": "Aggiungi tutte le tabelle",
|
||||
"designer.all": "Tutto",
|
||||
"designer.allKeys": "Tutte le chiavi",
|
||||
"designer.chooseTableColor": "Scegli colore tabella",
|
||||
"designer.columnProperties": "Proprietà colonna",
|
||||
"designer.columns": "Colonne - { filterColumns }",
|
||||
"designer.dataTypeYesNo": "Tipo dato: {show}",
|
||||
@@ -900,7 +927,12 @@
|
||||
"file.queryDesignerFiles": "File designer query",
|
||||
"file.sqlFiles": "File SQL",
|
||||
"file.sqliteDatabase": "Database SQLite",
|
||||
"files.allConnections": "Tutte le connessioni",
|
||||
"files.allDatabases": "tutti i database",
|
||||
"files.allSupportedFiles": "Tutti i file supportati",
|
||||
"files.clearConnectionFilter": "Cancella filtro connessione",
|
||||
"files.connection": "Connessione",
|
||||
"files.currentDatabase": "Database corrente",
|
||||
"files.openFile": "Apri file",
|
||||
"files.refreshFiles": "Aggiorna file",
|
||||
"files.savedFiles": "File salvati",
|
||||
@@ -1060,6 +1092,7 @@
|
||||
"importExport.value": "Valore",
|
||||
"indexEditor.filteredIndexCondition": "Condizione indice filtrato",
|
||||
"indexEditor.indexName": "Nome indice",
|
||||
"indexEditor.indexType": "Tipo indice",
|
||||
"indexEditor.isUnique": "È indice univoco",
|
||||
"insertJoin.alias": "Alias",
|
||||
"insertJoin.columnFrom": "Colonna da",
|
||||
@@ -1135,6 +1168,10 @@
|
||||
"newObject.erDiagramDisabled": "Il diagramma ER non è disponibile per il database corrente",
|
||||
"newObject.exportDescription": "Esporta in file come CSV, JSON, Excel o altro DB",
|
||||
"newObject.exportDisabled": "L'esportazione non è disponibile per il database corrente",
|
||||
"newObject.graphqlChatDescription": "Chatta con la tua API GraphQL usando l'AI",
|
||||
"newObject.graphqlChatDisabled": "La chat GraphQL non è disponibile per la connessione corrente",
|
||||
"newObject.graphqlQueryDescription": "Scrivi query, scegli attributi e argomenti",
|
||||
"newObject.graphqlQueryDisabled": "La query GraphQL non è disponibile per il database corrente",
|
||||
"newObject.perspectiveDescription": "Unisci dati complessi da più database",
|
||||
"newObject.queryDesignerDescription": "Progetta query SQL visivamente",
|
||||
"newObject.queryDesignerDisabled": "Il designer query non è disponibile per il database corrente",
|
||||
@@ -1158,6 +1195,7 @@
|
||||
"privateCloudWidget.addNewConnectionOrFile": "Aggiungi nuova connessione o file",
|
||||
"privateCloudWidget.addNewFolder": "Aggiungi nuova cartella",
|
||||
"privateCloudWidget.administrateAccess": "Amministra accesso",
|
||||
"privateCloudWidget.cloudUnavailable": "DbGate Cloud è temporaneamente non disponibile",
|
||||
"privateCloudWidget.createConnection": "Crea connessione su DbGate Cloud",
|
||||
"privateCloudWidget.createSharedFolder": "Crea cartella condivisa",
|
||||
"privateCloudWidget.deleteFolder": "Elimina cartella",
|
||||
@@ -1170,6 +1208,7 @@
|
||||
"privateCloudWidget.renameFolder": "Rinomina cartella",
|
||||
"privateCloudWidget.searchPlaceholder": "Cerca connessioni e file cloud",
|
||||
"privateCloudWidget.yourInviteLink": "Il tuo link di invito (nel formato dbgate://folder/xxx)",
|
||||
"publicCloudWidget.cloudUnavailable": "DbGate Cloud è temporaneamente non disponibile",
|
||||
"publicCloudWidget.noFilesFound": "Nessun file trovato per la tua configurazione",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Sono elencati solo i file rilevanti per le tue connessioni, piattaforma ed edizione DbGate. Definisci prima le connessioni.",
|
||||
"publicCloudWidget.publicKnowledgeBase": "Knowledge Base pubblica",
|
||||
@@ -1191,10 +1230,13 @@
|
||||
"query.aggregate": "Aggrega",
|
||||
"query.alias": "Alias",
|
||||
"query.columnExpression": "Colonna/Espressione",
|
||||
"query.defaultIsolationLevel": "Predefinito",
|
||||
"query.defaultIsolationLevelNamed": "Predefinito ({level})",
|
||||
"query.download": "scarica",
|
||||
"query.filter": "Filtro",
|
||||
"query.groupBy": "Raggruppa per",
|
||||
"query.groupFilter": "Filtro gruppo",
|
||||
"query.isolationLevel": "Livello di isolamento",
|
||||
"query.limitRows": "Limita a {queryRowsLimit} righe",
|
||||
"query.named": ":variabile",
|
||||
"query.noParameters": "(nessun parametro)",
|
||||
@@ -1287,6 +1329,7 @@
|
||||
"settings.behaviour.openDetailOnArrows": "Apri dettaglio con navigazione tastiera",
|
||||
"settings.behaviour.singleClickPreview": "Quando fai un singolo clic o selezioni un file nella vista \"Tabelle, Viste, Funzioni\", viene mostrato in modalità anteprima e riutilizza una scheda esistente (scheda anteprima). Questo è utile se stai navigando rapidamente le tabelle e non vuoi che ogni tabella visitata abbia la propria scheda. Quando inizi a modificare la tabella o usi il doppio clic per aprire la tabella dalla vista \"Tabelle\", una nuova scheda viene dedicata a quella tabella.",
|
||||
"settings.behaviour.useTabPreviewMode": "Usa modalità anteprima scheda",
|
||||
"settings.checkAll": "Seleziona tutto / Deseleziona tutto",
|
||||
"settings.confirmations": "Conferme",
|
||||
"settings.confirmations.skipConfirm.collectionDataSave": "Salta conferma quando salvi dati collezione (NoSQL)",
|
||||
"settings.confirmations.skipConfirm.tableDataSave": "Salta conferma quando salvi dati tabella (SQL)",
|
||||
@@ -1305,6 +1348,7 @@
|
||||
"settings.dataGrid.coloringMode.36": "Ogni 3a e 6a riga",
|
||||
"settings.dataGrid.coloringMode.none": "Nessuna",
|
||||
"settings.dataGrid.defaultAutoRefreshInterval": "Intervallo predefinito aggiornamento automatico griglia in secondi",
|
||||
"settings.dataGrid.disableCellDataViewAutoOpen": "Disabilita apertura automatica Vista dati cella",
|
||||
"settings.dataGrid.pageSize": "Dimensione pagina (numero di righe per caricamento incrementale, deve essere tra 5 e 50000)",
|
||||
"settings.dataGrid.showAllColumnsWhenSearch": "Mostra tutte le colonne durante la ricerca",
|
||||
"settings.dataGrid.showHintColumns": "Mostra suggerimenti chiavi esterne",
|
||||
@@ -1331,6 +1375,7 @@
|
||||
"settings.defaultActions.tableClick": "Clic tabella",
|
||||
"settings.defaultActions.useLastUsedAction": "Usa ultima azione utilizzata",
|
||||
"settings.defaultActions.viewClick": "Clic vista",
|
||||
"settings.drivers": "Driver",
|
||||
"settings.editor.keybinds": "Scorciatoie editor",
|
||||
"settings.editor.wordWrap": "Abilita a capo automatico",
|
||||
"settings.externalTools": "Strumenti esterni",
|
||||
@@ -1355,6 +1400,9 @@
|
||||
"settings.other.licenseKey.invalid": "La chiave licenza non è valida",
|
||||
"settings.other.licenseKey.valid": "La chiave licenza è valida",
|
||||
"settings.other.licenseKey.validTo": "Licenza valida fino a:",
|
||||
"settings.other.toolBarPosition": "Posizione barra strumenti",
|
||||
"settings.other.toolBarPosition.bottom": "In basso",
|
||||
"settings.other.toolBarPosition.top": "In alto",
|
||||
"settings.session": "Sessioni query",
|
||||
"settings.session.autoClose": "Chiusura automatica sessioni query dopo periodo senza attività",
|
||||
"settings.session.autoCloseTimeout": "Intervallo dopo il quale la sessione query senza attività viene chiusa (in minuti)",
|
||||
@@ -1393,6 +1441,7 @@
|
||||
"sqlGenerator.omitNulls": "Ometti valori NULL",
|
||||
"sqlGenerator.searchTablesOrObjects": "Cerca tabelle o oggetti",
|
||||
"sqlGenerator.skipAutoincrementColumn": "Salta colonna autoincrement",
|
||||
"sqlGenerator.skipComputedColumns": "Salta colonne calcolate",
|
||||
"sqlGenerator.sqlGenerator": "Generatore SQL",
|
||||
"sqlGenerator.sqlTruncated": "SQL troncato, superato limite dimensione file",
|
||||
"sqlGenerator.tables": "Tabelle",
|
||||
@@ -1467,6 +1516,7 @@
|
||||
"tableEditor.defaultValue": "Valore predefinito",
|
||||
"tableEditor.dependencies": "Dipendenze",
|
||||
"tableEditor.foreignKeys": "Chiavi esterne ({foreignKeyCount})",
|
||||
"tableEditor.indexType": "Tipo",
|
||||
"tableEditor.indexes": "Indici ({indexCount})",
|
||||
"tableEditor.isPersisted": "È persistente",
|
||||
"tableEditor.isSparse": "È Sparse",
|
||||
@@ -1485,7 +1535,6 @@
|
||||
"tableEditor.remove": "Rimuovi",
|
||||
"tableEditor.tablename": "Nome tabella",
|
||||
"tableEditor.tableproperties": "Proprietà tabella",
|
||||
"tableEditor.unique": "Univoco",
|
||||
"tableEditor.uniqueConstraints": "Vincoli univoci ({constraintCount})",
|
||||
"tableEditor.yes": "SÌ",
|
||||
"tableStructure.alter": "Modifica tabella",
|
||||
@@ -1521,6 +1570,7 @@
|
||||
"widget.collectionsContainers": "Collezioni/container",
|
||||
"widget.databaseContent": "Contenuto database",
|
||||
"widget.databases": "Database",
|
||||
"widget.endpoints": "Endpoint",
|
||||
"widget.keys": "Chiavi",
|
||||
"widget.pinned": "Fissate",
|
||||
"widget.tablesViewsFunctions": "Tabelle, viste, funzioni",
|
||||
@@ -1535,4 +1585,4 @@
|
||||
"widgets.openedTabs": "Schede aperte",
|
||||
"widgets.premiumPromo": "Promo Premium",
|
||||
"widgets.queryHistoryAndClosedTabs": "Cronologia query e schede chiuse"
|
||||
}
|
||||
}
|
||||
|
||||
+52
-2
@@ -113,6 +113,7 @@
|
||||
"command.about": "について",
|
||||
"command.about.show": "表示",
|
||||
"command.about.toolbar": "について",
|
||||
"command.apiQuery": "APIクエリ",
|
||||
"command.app.checkForUpdates": "更新を確認",
|
||||
"command.app.disconnect": "切断",
|
||||
"command.app.loggedUser": "ログインユーザー",
|
||||
@@ -245,6 +246,7 @@
|
||||
"command.designer": "デザイナー",
|
||||
"command.designer.arrange": "配置",
|
||||
"command.designer.exportDiagram": "ダイアグラムをエクスポート",
|
||||
"command.designer.exportDiagramPng": "ダイアグラムをPNGとしてエクスポート",
|
||||
"command.designer.openSql": "SQLを開く",
|
||||
"command.designer.remove": "削除",
|
||||
"command.designer.removeSelectedTables": "選択したテーブルを削除",
|
||||
@@ -272,6 +274,11 @@
|
||||
"command.folder": "フォルダー",
|
||||
"command.folder.openData": "データフォルダーを開く",
|
||||
"command.folder.openLogs": "ログを開く",
|
||||
"command.gqlConnection": "GraphQL接続",
|
||||
"command.gqlConnection.toggleCellDataView": "セルデータビューの切り替え",
|
||||
"command.gqlConnection.toggleCellDataView.menu": "セルデータを表示",
|
||||
"command.gqlConnection.toggleCellDataView.toolbar": "セルデータ",
|
||||
"command.graphql.chat": "GraphQLチャット",
|
||||
"command.internal": "内部",
|
||||
"command.internal.loadCampaigns": "キャンペーンリストを読み込み",
|
||||
"command.internal.showCampaigns": "キャンペーンを表示",
|
||||
@@ -294,12 +301,14 @@
|
||||
"command.new.connectionFolderToolbar": "接続フォルダーを追加",
|
||||
"command.new.diagram": "ERダイアグラム",
|
||||
"command.new.duckdbDatabase": "新しいDuckDBデータベース",
|
||||
"command.new.graphqlQuery": "GraphQLクエリ",
|
||||
"command.new.jsonl": "JSON Lines",
|
||||
"command.new.markdown": "Markdownページ",
|
||||
"command.new.modelCompare": "DBを比較",
|
||||
"command.new.modelTransform": "モデル変換",
|
||||
"command.new.newApplication": "新しいアプリケーション",
|
||||
"command.new.newDiagram": "新しいERダイアグラム",
|
||||
"command.new.newGraphqlQuery": "新しいGraphQLクエリ",
|
||||
"command.new.newJsonl": "新しいJSON linesファイル",
|
||||
"command.new.newModelTransform": "新しいモデル変換",
|
||||
"command.new.newPerspective": "新しいパースペクティブ",
|
||||
@@ -342,6 +351,8 @@
|
||||
"command.redisLikeData.save": "保存",
|
||||
"command.redo": "やり直す",
|
||||
"command.replace": "置換",
|
||||
"command.restApi": "REST API",
|
||||
"command.restApi.execute": "実行",
|
||||
"command.save": "保存",
|
||||
"command.saveAs": "名前を付けて保存",
|
||||
"command.saveToDisk": "ディスクに保存",
|
||||
@@ -432,6 +443,8 @@
|
||||
"common.fileType": "{extension} ファイル",
|
||||
"common.files.allFiles": "すべてのファイル",
|
||||
"common.general": "一般",
|
||||
"common.graphqlChat": "GraphQLチャット",
|
||||
"common.graphqlQuery": "GraphQLクエリ",
|
||||
"common.import": "インポート",
|
||||
"common.kill": "強制終了",
|
||||
"common.loadingData": "データを読み込み中",
|
||||
@@ -534,6 +547,11 @@
|
||||
"connection.accessKeyId": "アクセスキーID",
|
||||
"connection.allowedDatabases": "許可されたデータベース、1行に1つ",
|
||||
"connection.allowedDatabasesRegex": "許可されたデータベースの正規表現",
|
||||
"connection.apiKeyHeader": "APIキーのヘッダー",
|
||||
"connection.apiKeyValue": "APIキーの値",
|
||||
"connection.apiQuery": "APIクエリ",
|
||||
"connection.apiServerUrl1": "APIサーバーURL",
|
||||
"connection.apiServerUrl2": "APIセカンダリサーバーURL",
|
||||
"connection.askPassword": "保存せず、パスワードを問い合わせる",
|
||||
"connection.askUser": "保存せず、ログインとパスワードを問い合わせる",
|
||||
"connection.authToken": "認証トークン",
|
||||
@@ -555,6 +573,7 @@
|
||||
"connection.databaseFilePath": "データベースファイル(サーバー上のパス)",
|
||||
"connection.databaseUrl": "データベースURL",
|
||||
"connection.defaultDatabase": "デフォルトデータベース",
|
||||
"connection.defaultIsolationLevel": "デフォルト分離レベル",
|
||||
"connection.delete": "削除",
|
||||
"connection.deleteConfirm": "本当に接続 {name} を削除しますか?",
|
||||
"connection.deleteFolderConfirm": "本当にフォルダー {folder} を削除しますか?フォルダー内の接続はルートフォルダーに移動されます。",
|
||||
@@ -567,6 +586,9 @@
|
||||
"connection.engine": "データベースエンジン",
|
||||
"connection.engineDriverNotFound": "エンジンドライバー {engine} が見つかりません。インストールされたプラグインを確認し、接続編集ダイアログでエンジンを変更してください",
|
||||
"connection.fillDetails": "データベース接続詳細を入力",
|
||||
"connection.httpProxyPassword": "HTTPプロキシパスワード",
|
||||
"connection.httpProxyUrl": "HTTPプロキシURL",
|
||||
"connection.httpProxyUser": "HTTPプロキシユーザー",
|
||||
"connection.isReadOnly": "読み取り専用",
|
||||
"connection.keySeparator": "キーセパレーター",
|
||||
"connection.localDataCenter": "ローカルデータセンター",
|
||||
@@ -626,6 +648,7 @@
|
||||
"dataForm.noData": "データがありません",
|
||||
"dataForm.outOfBounds": "範囲外: {current} / {total}",
|
||||
"dataForm.rowCount": "行: {current} / {total}",
|
||||
"dataForm.rowCountMany": "行: {current} / 多数",
|
||||
"dataGrid.chooseValue": "{field} から値を選択",
|
||||
"dataGrid.codeHighlighting": "コードハイライト:",
|
||||
"dataGrid.codeHighlighting.none": "なし(生テキスト)",
|
||||
@@ -664,6 +687,7 @@
|
||||
"database.export": "エクスポート",
|
||||
"database.exportDbModel": "DBモデルをエクスポート",
|
||||
"database.generateScript": "スクリプトを生成",
|
||||
"database.graphqlChat": "GraphQLチャット",
|
||||
"database.import": "インポート",
|
||||
"database.newApplication": "新しいアプリケーション",
|
||||
"database.newCollection": "新しいコレクション/コンテナー",
|
||||
@@ -764,6 +788,7 @@
|
||||
"datagrid.openQuery": "クエリを開く",
|
||||
"datagrid.resetFilter": "フィルターをリセット",
|
||||
"datagrid.resetView": "表示をリセット",
|
||||
"datagrid.rowCountMany": "多数",
|
||||
"datagrid.rows": "行",
|
||||
"datagrid.searchMacros": "Search macros",
|
||||
"datagrid.selectedInfo.count": "件数",
|
||||
@@ -771,6 +796,7 @@
|
||||
"datagrid.selectedInfo.sum": "合計",
|
||||
"datagrid.setFormat": "Set format: ",
|
||||
"datagrid.structure": "Structure",
|
||||
"datagrid.structure.notLoaded": "構造が読み込まれていません。おそらく現在のデータベースにテーブルが存在しません",
|
||||
"datagrid.structure.waiting": "構造を待機中",
|
||||
"datagrid.useMacro": "マクロを使用",
|
||||
"dbKeysTreeNode.deleteBranch": "ブランチを削除",
|
||||
@@ -836,6 +862,7 @@
|
||||
"designer.addAllTables": "すべてのテーブルを追加",
|
||||
"designer.all": "すべて",
|
||||
"designer.allKeys": "すべてのキー",
|
||||
"designer.chooseTableColor": "テーブルの色を選択",
|
||||
"designer.columnProperties": "カラムプロパティ",
|
||||
"designer.columns": "カラム - { filterColumns }",
|
||||
"designer.dataTypeYesNo": "データ型: {show}",
|
||||
@@ -900,7 +927,12 @@
|
||||
"file.queryDesignerFiles": "クエリデザイナーファイル",
|
||||
"file.sqlFiles": "SQLファイル",
|
||||
"file.sqliteDatabase": "SQLiteデータベース",
|
||||
"files.allConnections": "すべての接続",
|
||||
"files.allDatabases": "すべてのデータベース",
|
||||
"files.allSupportedFiles": "サポートされているすべてのファイル",
|
||||
"files.clearConnectionFilter": "接続フィルターをクリア",
|
||||
"files.connection": "接続",
|
||||
"files.currentDatabase": "現在のデータベース",
|
||||
"files.openFile": "ファイルを開く",
|
||||
"files.refreshFiles": "ファイルを更新",
|
||||
"files.savedFiles": "保存されたファイル",
|
||||
@@ -1060,6 +1092,7 @@
|
||||
"importExport.value": "値",
|
||||
"indexEditor.filteredIndexCondition": "フィルター済みインデックス条件",
|
||||
"indexEditor.indexName": "インデックス名",
|
||||
"indexEditor.indexType": "インデックスタイプ",
|
||||
"indexEditor.isUnique": "一意インデックス",
|
||||
"insertJoin.alias": "エイリアス",
|
||||
"insertJoin.columnFrom": "元カラム",
|
||||
@@ -1135,6 +1168,10 @@
|
||||
"newObject.erDiagramDisabled": "現在のデータベースではER図が利用できません",
|
||||
"newObject.exportDescription": "CSV、JSON、Excel、または他のDBにエクスポート",
|
||||
"newObject.exportDisabled": "現在のデータベースではエクスポートが利用できません",
|
||||
"newObject.graphqlChatDescription": "AIを使用してGraphQL APIとチャット",
|
||||
"newObject.graphqlChatDisabled": "現在の接続ではGraphQLチャットが利用できません",
|
||||
"newObject.graphqlQueryDescription": "クエリを記述し、属性と引数を選択",
|
||||
"newObject.graphqlQueryDisabled": "現在のデータベースではGraphQLクエリが利用できません",
|
||||
"newObject.perspectiveDescription": "複数のデータベースから複雑なデータを結合",
|
||||
"newObject.queryDesignerDescription": "SQLクエリをビジュアルに設計",
|
||||
"newObject.queryDesignerDisabled": "現在のデータベースではクエリデザイナーが利用できません",
|
||||
@@ -1158,6 +1195,7 @@
|
||||
"privateCloudWidget.addNewConnectionOrFile": "新しい接続またはファイルを追加",
|
||||
"privateCloudWidget.addNewFolder": "新しいフォルダーを追加",
|
||||
"privateCloudWidget.administrateAccess": "アクセスを管理",
|
||||
"privateCloudWidget.cloudUnavailable": "DbGateクラウドは一時的に利用できません",
|
||||
"privateCloudWidget.createConnection": "DbGateクラウドに接続を作成",
|
||||
"privateCloudWidget.createSharedFolder": "共有フォルダーを作成",
|
||||
"privateCloudWidget.deleteFolder": "フォルダーを削除",
|
||||
@@ -1170,6 +1208,7 @@
|
||||
"privateCloudWidget.renameFolder": "フォルダー名を変更",
|
||||
"privateCloudWidget.searchPlaceholder": "クラウド接続とファイルを検索",
|
||||
"privateCloudWidget.yourInviteLink": "招待リンク(dbgate://folder/xxx の形式)",
|
||||
"publicCloudWidget.cloudUnavailable": "DbGateクラウドは一時的に利用できません",
|
||||
"publicCloudWidget.noFilesFound": "設定に該当するファイルが見つかりません",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "接続、プラットフォーム、DbGateエディションに関連するファイルのみが一覧表示されます。まず接続を定義してください。",
|
||||
"publicCloudWidget.publicKnowledgeBase": "公開ナレッジベース",
|
||||
@@ -1191,10 +1230,13 @@
|
||||
"query.aggregate": "集計",
|
||||
"query.alias": "エイリアス",
|
||||
"query.columnExpression": "カラム/式",
|
||||
"query.defaultIsolationLevel": "デフォルト",
|
||||
"query.defaultIsolationLevelNamed": "デフォルト ({level})",
|
||||
"query.download": "ダウンロード",
|
||||
"query.filter": "フィルター",
|
||||
"query.groupBy": "グループ化",
|
||||
"query.groupFilter": "グループフィルター",
|
||||
"query.isolationLevel": "分離レベル",
|
||||
"query.limitRows": "{queryRowsLimit}行に制限",
|
||||
"query.named": ":variable",
|
||||
"query.noParameters": "(パラメーターなし)",
|
||||
@@ -1287,6 +1329,7 @@
|
||||
"settings.behaviour.openDetailOnArrows": "キーボードナビゲーションで詳細を開く",
|
||||
"settings.behaviour.singleClickPreview": "\"テーブル、ビュー、関数\"ビューでファイルをシングルクリックまたは選択すると、プレビューモードで表示され、既存のタブ(プレビュータブ)が再利用されます。これは、テーブルを素早く閲覧している際に、訪れたすべてのテーブルに独自のタブを持たせたくない場合に便利です。テーブルの編集を開始するか、\"テーブル\"ビューからダブルクリックでテーブルを開くと、そのテーブル専用の新しいタブが作成されます。",
|
||||
"settings.behaviour.useTabPreviewMode": "タブプレビューモードを使用",
|
||||
"settings.checkAll": "すべてチェック / すべてのチェックを外す",
|
||||
"settings.confirmations": "確認",
|
||||
"settings.confirmations.skipConfirm.collectionDataSave": "コレクションデータ保存時の確認をスキップ (NoSQL)",
|
||||
"settings.confirmations.skipConfirm.tableDataSave": "テーブルデータ保存時の確認をスキップ (SQL)",
|
||||
@@ -1305,6 +1348,7 @@
|
||||
"settings.dataGrid.coloringMode.36": "3行目と6行目ごと",
|
||||
"settings.dataGrid.coloringMode.none": "なし",
|
||||
"settings.dataGrid.defaultAutoRefreshInterval": "デフォルトグリッド自動更新間隔(秒)",
|
||||
"settings.dataGrid.disableCellDataViewAutoOpen": "セルデータビューの自動表示を無効化",
|
||||
"settings.dataGrid.pageSize": "ページサイズ(漸進的読み込みの行数5から50000の間)",
|
||||
"settings.dataGrid.showAllColumnsWhenSearch": "検索時にすべてのカラムを表示",
|
||||
"settings.dataGrid.showHintColumns": "外部キーヒントを表示",
|
||||
@@ -1331,6 +1375,7 @@
|
||||
"settings.defaultActions.tableClick": "テーブルクリック",
|
||||
"settings.defaultActions.useLastUsedAction": "前回使用した動作を使用",
|
||||
"settings.defaultActions.viewClick": "ビュークリック",
|
||||
"settings.drivers": "ドライバー",
|
||||
"settings.editor.keybinds": "エディターキーバインド",
|
||||
"settings.editor.wordWrap": "ワードラップを有効化",
|
||||
"settings.externalTools": "外部ツール",
|
||||
@@ -1355,6 +1400,9 @@
|
||||
"settings.other.licenseKey.invalid": "ライセンスキーが無効です",
|
||||
"settings.other.licenseKey.valid": "ライセンスキーは有効です",
|
||||
"settings.other.licenseKey.validTo": "ライセンス有効期限:",
|
||||
"settings.other.toolBarPosition": "ツールバーの位置",
|
||||
"settings.other.toolBarPosition.bottom": "下",
|
||||
"settings.other.toolBarPosition.top": "上",
|
||||
"settings.session": "クエリセッション",
|
||||
"settings.session.autoClose": "活動がない期間後にクエリセッションを自動的に閉じる",
|
||||
"settings.session.autoCloseTimeout": "活動がないクエリセッションを閉じるまでの間隔(分)",
|
||||
@@ -1393,6 +1441,7 @@
|
||||
"sqlGenerator.omitNulls": "NULL値を省略",
|
||||
"sqlGenerator.searchTablesOrObjects": "テーブルまたはオブジェクトを検索",
|
||||
"sqlGenerator.skipAutoincrementColumn": "自動増分カラムをスキップ",
|
||||
"sqlGenerator.skipComputedColumns": "計算カラムをスキップ",
|
||||
"sqlGenerator.sqlGenerator": "SQLジェネレーター",
|
||||
"sqlGenerator.sqlTruncated": "SQLが切り詰められました。ファイルサイズの制限を超えています",
|
||||
"sqlGenerator.tables": "テーブル",
|
||||
@@ -1467,6 +1516,7 @@
|
||||
"tableEditor.defaultValue": "デフォルト値",
|
||||
"tableEditor.dependencies": "依存関係",
|
||||
"tableEditor.foreignKeys": "外部キー ({foreignKeyCount})",
|
||||
"tableEditor.indexType": "タイプ",
|
||||
"tableEditor.indexes": "インデックス ({indexCount})",
|
||||
"tableEditor.isPersisted": "永続化",
|
||||
"tableEditor.isSparse": "疎",
|
||||
@@ -1485,7 +1535,6 @@
|
||||
"tableEditor.remove": "削除",
|
||||
"tableEditor.tablename": "テーブル名",
|
||||
"tableEditor.tableproperties": "テーブルプロパティ",
|
||||
"tableEditor.unique": "一意",
|
||||
"tableEditor.uniqueConstraints": "一意制約 ({constraintCount})",
|
||||
"tableEditor.yes": "YES",
|
||||
"tableStructure.alter": "テーブルを変更",
|
||||
@@ -1521,6 +1570,7 @@
|
||||
"widget.collectionsContainers": "コレクション/コンテナー",
|
||||
"widget.databaseContent": "データベースの内容",
|
||||
"widget.databases": "データベース",
|
||||
"widget.endpoints": "エンドポイント",
|
||||
"widget.keys": "キー",
|
||||
"widget.pinned": "固定済み",
|
||||
"widget.tablesViewsFunctions": "テーブル、ビュー、関数",
|
||||
@@ -1535,4 +1585,4 @@
|
||||
"widgets.openedTabs": "開いているタブ",
|
||||
"widgets.premiumPromo": "Premiumプロモーション",
|
||||
"widgets.queryHistoryAndClosedTabs": "クエリ履歴と閉じたタブ"
|
||||
}
|
||||
}
|
||||
|
||||
+52
-2
@@ -113,6 +113,7 @@
|
||||
"command.about": "정보",
|
||||
"command.about.show": "표시",
|
||||
"command.about.toolbar": "정보",
|
||||
"command.apiQuery": "API 쿼리",
|
||||
"command.app.checkForUpdates": "업데이트 확인",
|
||||
"command.app.disconnect": "연결 끊기",
|
||||
"command.app.loggedUser": "로그인 사용자",
|
||||
@@ -245,6 +246,7 @@
|
||||
"command.designer": "디자이너",
|
||||
"command.designer.arrange": "정렬",
|
||||
"command.designer.exportDiagram": "다이어그램 내보내기",
|
||||
"command.designer.exportDiagramPng": "다이어그램을 PNG로 내보내기",
|
||||
"command.designer.openSql": "SQL 열기",
|
||||
"command.designer.remove": "제거",
|
||||
"command.designer.removeSelectedTables": "선택한 테이블 제거",
|
||||
@@ -272,6 +274,11 @@
|
||||
"command.folder": "폴더",
|
||||
"command.folder.openData": "데이터 폴더 열기",
|
||||
"command.folder.openLogs": "로그 열기",
|
||||
"command.gqlConnection": "GraphQL 연결",
|
||||
"command.gqlConnection.toggleCellDataView": "셀 데이터 보기 전환",
|
||||
"command.gqlConnection.toggleCellDataView.menu": "셀 데이터 표시",
|
||||
"command.gqlConnection.toggleCellDataView.toolbar": "셀 데이터",
|
||||
"command.graphql.chat": "GraphQL 채팅",
|
||||
"command.internal": "내부",
|
||||
"command.internal.loadCampaigns": "캠페인 목록 로드",
|
||||
"command.internal.showCampaigns": "캠페인 표시",
|
||||
@@ -294,12 +301,14 @@
|
||||
"command.new.connectionFolderToolbar": "연결 폴더 추가",
|
||||
"command.new.diagram": "ER 다이어그램",
|
||||
"command.new.duckdbDatabase": "새 DuckDB 데이터베이스",
|
||||
"command.new.graphqlQuery": "GraphQL 쿼리",
|
||||
"command.new.jsonl": "JSON Lines",
|
||||
"command.new.markdown": "Markdown 페이지",
|
||||
"command.new.modelCompare": "DB 비교",
|
||||
"command.new.modelTransform": "모델 변환",
|
||||
"command.new.newApplication": "새 애플리케이션",
|
||||
"command.new.newDiagram": "새 ER 다이어그램",
|
||||
"command.new.newGraphqlQuery": "새 GraphQL 쿼리",
|
||||
"command.new.newJsonl": "새 JSON Lines 파일",
|
||||
"command.new.newModelTransform": "새 모델 변환",
|
||||
"command.new.newPerspective": "새 퍼스펙티브",
|
||||
@@ -342,6 +351,8 @@
|
||||
"command.redisLikeData.save": "저장",
|
||||
"command.redo": "다시 실행",
|
||||
"command.replace": "바꾸기",
|
||||
"command.restApi": "REST API",
|
||||
"command.restApi.execute": "실행",
|
||||
"command.save": "저장",
|
||||
"command.saveAs": "다른 이름으로 저장",
|
||||
"command.saveToDisk": "디스크에 저장",
|
||||
@@ -432,6 +443,8 @@
|
||||
"common.fileType": "{extension} 파일",
|
||||
"common.files.allFiles": "모든 파일",
|
||||
"common.general": "일반",
|
||||
"common.graphqlChat": "GraphQL 채팅",
|
||||
"common.graphqlQuery": "GraphQL 쿼리",
|
||||
"common.import": "가져오기",
|
||||
"common.kill": "중지",
|
||||
"common.loadingData": "데이터 로딩 중",
|
||||
@@ -534,6 +547,11 @@
|
||||
"connection.accessKeyId": "Access Key ID",
|
||||
"connection.allowedDatabases": "허용된 데이터베이스(한 줄에 하나씩)",
|
||||
"connection.allowedDatabasesRegex": "허용된 데이터베이스 정규식",
|
||||
"connection.apiKeyHeader": "API 키 헤더",
|
||||
"connection.apiKeyValue": "API 키 값",
|
||||
"connection.apiQuery": "API 쿼리",
|
||||
"connection.apiServerUrl1": "API 서버 URL",
|
||||
"connection.apiServerUrl2": "API 보조 서버 URL",
|
||||
"connection.askPassword": "저장하지 않고 비밀번호 묻기",
|
||||
"connection.askUser": "저장하지 않고 로그인/비밀번호 묻기",
|
||||
"connection.authToken": "인증 토큰",
|
||||
@@ -555,6 +573,7 @@
|
||||
"connection.databaseFilePath": "데이터베이스 파일(서버 경로)",
|
||||
"connection.databaseUrl": "데이터베이스 URL",
|
||||
"connection.defaultDatabase": "기본 데이터베이스",
|
||||
"connection.defaultIsolationLevel": "기본 격리 수준",
|
||||
"connection.delete": "삭제",
|
||||
"connection.deleteConfirm": "연결 {name}을(를) 정말 삭제하시겠습니까?",
|
||||
"connection.deleteFolderConfirm": "폴더 {folder}을(를) 정말 삭제하시겠습니까? 폴더 안의 연결은 루트 폴더로 이동됩니다.",
|
||||
@@ -567,6 +586,9 @@
|
||||
"connection.engine": "데이터베이스 엔진",
|
||||
"connection.engineDriverNotFound": "엔진 드라이버 {engine}을(를) 찾을 수 없습니다. 설치된 플러그인을 확인하고 연결 편집 대화상자에서 엔진을 변경하세요",
|
||||
"connection.fillDetails": "데이터베이스 연결 세부 정보 입력",
|
||||
"connection.httpProxyPassword": "HTTP 프록시 비밀번호",
|
||||
"connection.httpProxyUrl": "HTTP 프록시 URL",
|
||||
"connection.httpProxyUser": "HTTP 프록시 사용자",
|
||||
"connection.isReadOnly": "읽기 전용",
|
||||
"connection.keySeparator": "키 구분자",
|
||||
"connection.localDataCenter": "로컬 데이터센터",
|
||||
@@ -626,6 +648,7 @@
|
||||
"dataForm.noData": "데이터 없음",
|
||||
"dataForm.outOfBounds": "범위를 벗어남: {current} / {total}",
|
||||
"dataForm.rowCount": "행: {current} / {total}",
|
||||
"dataForm.rowCountMany": "행: {current} / Many",
|
||||
"dataGrid.chooseValue": "{field}에서 값 선택",
|
||||
"dataGrid.codeHighlighting": "코드 하이라이팅:",
|
||||
"dataGrid.codeHighlighting.none": "없음(원시 텍스트)",
|
||||
@@ -664,6 +687,7 @@
|
||||
"database.export": "내보내기",
|
||||
"database.exportDbModel": "DB 모델 내보내기",
|
||||
"database.generateScript": "스크립트 생성",
|
||||
"database.graphqlChat": "GraphQL 채팅",
|
||||
"database.import": "가져오기",
|
||||
"database.newApplication": "새 애플리케이션",
|
||||
"database.newCollection": "새 컬렉션/컨테이너",
|
||||
@@ -764,6 +788,7 @@
|
||||
"datagrid.openQuery": "쿼리 열기",
|
||||
"datagrid.resetFilter": "필터 초기화",
|
||||
"datagrid.resetView": "보기 초기화",
|
||||
"datagrid.rowCountMany": "Many",
|
||||
"datagrid.rows": "행",
|
||||
"datagrid.searchMacros": "매크로 검색",
|
||||
"datagrid.selectedInfo.count": "개수",
|
||||
@@ -771,6 +796,7 @@
|
||||
"datagrid.selectedInfo.sum": "합계",
|
||||
"datagrid.setFormat": "형식 설정: ",
|
||||
"datagrid.structure": "구조",
|
||||
"datagrid.structure.notLoaded": "구조가 로드되지 않았습니다. 현재 데이터베이스에 테이블이 없을 수 있습니다",
|
||||
"datagrid.structure.waiting": "구조 대기 중",
|
||||
"datagrid.useMacro": "매크로 사용",
|
||||
"dbKeysTreeNode.deleteBranch": "브랜치 삭제",
|
||||
@@ -836,6 +862,7 @@
|
||||
"designer.addAllTables": "모든 테이블 추가",
|
||||
"designer.all": "전체",
|
||||
"designer.allKeys": "모든 키",
|
||||
"designer.chooseTableColor": "테이블 색상 선택",
|
||||
"designer.columnProperties": "컬럼 속성",
|
||||
"designer.columns": "컬럼 - { filterColumns }",
|
||||
"designer.dataTypeYesNo": "데이터 타입: {show}",
|
||||
@@ -900,7 +927,12 @@
|
||||
"file.queryDesignerFiles": "쿼리 디자이너 파일",
|
||||
"file.sqlFiles": "SQL 파일",
|
||||
"file.sqliteDatabase": "SQLite 데이터베이스",
|
||||
"files.allConnections": "모든 연결",
|
||||
"files.allDatabases": "모든 데이터베이스",
|
||||
"files.allSupportedFiles": "지원되는 모든 파일",
|
||||
"files.clearConnectionFilter": "연결 필터 지우기",
|
||||
"files.connection": "연결",
|
||||
"files.currentDatabase": "현재 데이터베이스",
|
||||
"files.openFile": "파일 열기",
|
||||
"files.refreshFiles": "파일 새로 고침",
|
||||
"files.savedFiles": "저장된 파일",
|
||||
@@ -1060,6 +1092,7 @@
|
||||
"importExport.value": "값",
|
||||
"indexEditor.filteredIndexCondition": "필터 인덱스 조건",
|
||||
"indexEditor.indexName": "인덱스 이름",
|
||||
"indexEditor.indexType": "인덱스 유형",
|
||||
"indexEditor.isUnique": "고유 인덱스",
|
||||
"insertJoin.alias": "별칭",
|
||||
"insertJoin.columnFrom": "원본 컬럼",
|
||||
@@ -1135,6 +1168,10 @@
|
||||
"newObject.erDiagramDisabled": "현재 데이터베이스에서는 ER 다이어그램을 사용할 수 없습니다",
|
||||
"newObject.exportDescription": "CSV, JSON, Excel 또는 다른 DB로 내보내기",
|
||||
"newObject.exportDisabled": "현재 데이터베이스에서는 내보내기를 사용할 수 없습니다",
|
||||
"newObject.graphqlChatDescription": "AI를 사용하여 GraphQL API와 대화",
|
||||
"newObject.graphqlChatDisabled": "현재 연결에서는 GraphQL 채팅을 사용할 수 없습니다",
|
||||
"newObject.graphqlQueryDescription": "쿼리를 작성하고 속성과 인수를 선택",
|
||||
"newObject.graphqlQueryDisabled": "현재 데이터베이스에서는 GraphQL 쿼리를 사용할 수 없습니다",
|
||||
"newObject.perspectiveDescription": "여러 데이터베이스의 복잡한 데이터를 조인",
|
||||
"newObject.queryDesignerDescription": "SQL 쿼리를 시각적으로 디자인",
|
||||
"newObject.queryDesignerDisabled": "현재 데이터베이스에서는 쿼리 디자이너를 사용할 수 없습니다",
|
||||
@@ -1158,6 +1195,7 @@
|
||||
"privateCloudWidget.addNewConnectionOrFile": "새 연결 또는 파일 추가",
|
||||
"privateCloudWidget.addNewFolder": "새 폴더 추가",
|
||||
"privateCloudWidget.administrateAccess": "접근 권한 관리",
|
||||
"privateCloudWidget.cloudUnavailable": "DbGate 클라우드는 일시적으로 사용할 수 없습니다",
|
||||
"privateCloudWidget.createConnection": "DbGate 클라우드에 연결 생성",
|
||||
"privateCloudWidget.createSharedFolder": "공유 폴더 생성",
|
||||
"privateCloudWidget.deleteFolder": "폴더 삭제",
|
||||
@@ -1170,6 +1208,7 @@
|
||||
"privateCloudWidget.renameFolder": "폴더 이름 변경",
|
||||
"privateCloudWidget.searchPlaceholder": "클라우드 연결 및 파일 검색",
|
||||
"privateCloudWidget.yourInviteLink": "초대 링크(dbgate://folder/xxx 형식)",
|
||||
"publicCloudWidget.cloudUnavailable": "DbGate 클라우드는 일시적으로 사용할 수 없습니다",
|
||||
"publicCloudWidget.noFilesFound": "구성에 해당하는 파일을 찾을 수 없습니다",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "연결, 플랫폼 및 DbGate 에디션과 관련된 파일만 표시됩니다. 먼저 연결을 정의하세요.",
|
||||
"publicCloudWidget.publicKnowledgeBase": "공개 지식 베이스",
|
||||
@@ -1191,10 +1230,13 @@
|
||||
"query.aggregate": "집계",
|
||||
"query.alias": "별칭",
|
||||
"query.columnExpression": "컬럼/표현식",
|
||||
"query.defaultIsolationLevel": "기본값",
|
||||
"query.defaultIsolationLevelNamed": "기본값({level})",
|
||||
"query.download": "다운로드",
|
||||
"query.filter": "필터",
|
||||
"query.groupBy": "그룹화",
|
||||
"query.groupFilter": "그룹 필터",
|
||||
"query.isolationLevel": "격리 수준",
|
||||
"query.limitRows": "{queryRowsLimit}행 제한",
|
||||
"query.named": ":variable",
|
||||
"query.noParameters": "(매개변수 없음)",
|
||||
@@ -1287,6 +1329,7 @@
|
||||
"settings.behaviour.openDetailOnArrows": "키보드 탐색 시 상세 열기",
|
||||
"settings.behaviour.singleClickPreview": "\"테이블, 뷰, 함수\" 보기에서 파일을 단일 클릭하거나 선택하면 미리보기 모드로 표시되며 기존 탭(미리보기 탭)을 재사용합니다. 이는 테이블을 빠르게 탐색하면서 방문한 각 테이블에 별도 탭을 만들고 싶지 않을 때 유용합니다. 테이블 편집을 시작하거나 \"테이블\" 보기에서 더블 클릭하여 테이블을 열면 해당 테이블에 전용 탭이 생성됩니다.",
|
||||
"settings.behaviour.useTabPreviewMode": "탭 미리보기 모드 사용",
|
||||
"settings.checkAll": "모두 선택 / 모두 선택 해제",
|
||||
"settings.confirmations": "확인",
|
||||
"settings.confirmations.skipConfirm.collectionDataSave": "컬렉션 데이터 저장 시 확인 건너뛰기(NoSQL)",
|
||||
"settings.confirmations.skipConfirm.tableDataSave": "테이블 데이터 저장 시 확인 건너뛰기(SQL)",
|
||||
@@ -1305,6 +1348,7 @@
|
||||
"settings.dataGrid.coloringMode.36": "3번째 및 6번째 행",
|
||||
"settings.dataGrid.coloringMode.none": "없음",
|
||||
"settings.dataGrid.defaultAutoRefreshInterval": "기본 그리드 자동 새로 고침 간격(초)",
|
||||
"settings.dataGrid.disableCellDataViewAutoOpen": "셀 데이터 보기 자동 열기 비활성화",
|
||||
"settings.dataGrid.pageSize": "페이지 크기(증분 로딩 행 수, 5~50000 사이)",
|
||||
"settings.dataGrid.showAllColumnsWhenSearch": "검색 시 모든 컬럼 표시",
|
||||
"settings.dataGrid.showHintColumns": "외래 키 힌트 표시",
|
||||
@@ -1331,6 +1375,7 @@
|
||||
"settings.defaultActions.tableClick": "테이블 클릭",
|
||||
"settings.defaultActions.useLastUsedAction": "마지막 사용 동작 사용",
|
||||
"settings.defaultActions.viewClick": "뷰 클릭",
|
||||
"settings.drivers": "드라이버",
|
||||
"settings.editor.keybinds": "편집기 키 바인딩",
|
||||
"settings.editor.wordWrap": "자동 줄 바꿈 사용",
|
||||
"settings.externalTools": "외부 도구",
|
||||
@@ -1355,6 +1400,9 @@
|
||||
"settings.other.licenseKey.invalid": "라이선스 키가 유효하지 않습니다",
|
||||
"settings.other.licenseKey.valid": "라이선스 키가 유효합니다",
|
||||
"settings.other.licenseKey.validTo": "라이선스 유효 기간:",
|
||||
"settings.other.toolBarPosition": "도구 모음 위치",
|
||||
"settings.other.toolBarPosition.bottom": "아래",
|
||||
"settings.other.toolBarPosition.top": "위",
|
||||
"settings.session": "쿼리 세션",
|
||||
"settings.session.autoClose": "활동이 없는 기간 후 쿼리 세션 자동 종료",
|
||||
"settings.session.autoCloseTimeout": "활동 없는 쿼리 세션을 종료하는 간격(분)",
|
||||
@@ -1393,6 +1441,7 @@
|
||||
"sqlGenerator.omitNulls": "NULL 값 생략",
|
||||
"sqlGenerator.searchTablesOrObjects": "테이블 또는 객체 검색",
|
||||
"sqlGenerator.skipAutoincrementColumn": "자동 증가 컬럼 건너뛰기",
|
||||
"sqlGenerator.skipComputedColumns": "계산 컬럼 건너뛰기",
|
||||
"sqlGenerator.sqlGenerator": "SQL 생성기",
|
||||
"sqlGenerator.sqlTruncated": "SQL이 잘렸습니다. 파일 크기 제한을 초과했습니다",
|
||||
"sqlGenerator.tables": "테이블",
|
||||
@@ -1467,6 +1516,7 @@
|
||||
"tableEditor.defaultValue": "기본값",
|
||||
"tableEditor.dependencies": "종속성",
|
||||
"tableEditor.foreignKeys": "외래 키({foreignKeyCount})",
|
||||
"tableEditor.indexType": "유형",
|
||||
"tableEditor.indexes": "인덱스({indexCount})",
|
||||
"tableEditor.isPersisted": "Persisted 여부",
|
||||
"tableEditor.isSparse": "Sparse 여부",
|
||||
@@ -1485,7 +1535,6 @@
|
||||
"tableEditor.remove": "제거",
|
||||
"tableEditor.tablename": "테이블 이름",
|
||||
"tableEditor.tableproperties": "테이블 속성",
|
||||
"tableEditor.unique": "고유",
|
||||
"tableEditor.uniqueConstraints": "고유 제약 조건({constraintCount})",
|
||||
"tableEditor.yes": "YES",
|
||||
"tableStructure.alter": "테이블 변경",
|
||||
@@ -1521,6 +1570,7 @@
|
||||
"widget.collectionsContainers": "컬렉션/컨테이너",
|
||||
"widget.databaseContent": "데이터베이스 콘텐츠",
|
||||
"widget.databases": "데이터베이스",
|
||||
"widget.endpoints": "엔드포인트",
|
||||
"widget.keys": "키",
|
||||
"widget.pinned": "고정됨",
|
||||
"widget.tablesViewsFunctions": "테이블, 뷰, 함수",
|
||||
@@ -1535,4 +1585,4 @@
|
||||
"widgets.openedTabs": "열린 탭",
|
||||
"widgets.premiumPromo": "프리미엄 프로모션",
|
||||
"widgets.queryHistoryAndClosedTabs": "쿼리 기록 및 닫은 탭"
|
||||
}
|
||||
}
|
||||
|
||||
+52
-2
@@ -113,6 +113,7 @@
|
||||
"command.about": "Sobre",
|
||||
"command.about.show": "Mostrar",
|
||||
"command.about.toolbar": "Sobre",
|
||||
"command.apiQuery": "Consulta API",
|
||||
"command.app.checkForUpdates": "Verificar atualizações",
|
||||
"command.app.disconnect": "Desconectar",
|
||||
"command.app.loggedUser": "Usuário logado",
|
||||
@@ -245,6 +246,7 @@
|
||||
"command.designer": "Designer",
|
||||
"command.designer.arrange": "Organizar",
|
||||
"command.designer.exportDiagram": "Exportar diagrama",
|
||||
"command.designer.exportDiagramPng": "Exportar diagrama como PNG",
|
||||
"command.designer.openSql": "Abrir SQL",
|
||||
"command.designer.remove": "Remover",
|
||||
"command.designer.removeSelectedTables": "Remover tabelas selecionadas",
|
||||
@@ -272,6 +274,11 @@
|
||||
"command.folder": "Pasta",
|
||||
"command.folder.openData": "Abrir pasta de dados",
|
||||
"command.folder.openLogs": "Abrir logs",
|
||||
"command.gqlConnection": "Conexão GraphQL",
|
||||
"command.gqlConnection.toggleCellDataView": "Alternar visualização de dados da célula",
|
||||
"command.gqlConnection.toggleCellDataView.menu": "Mostrar dados da célula",
|
||||
"command.gqlConnection.toggleCellDataView.toolbar": "Dados da célula",
|
||||
"command.graphql.chat": "Chat GraphQL",
|
||||
"command.internal": "Interno",
|
||||
"command.internal.loadCampaigns": "Carregar lista de campanhas",
|
||||
"command.internal.showCampaigns": "Mostrar campanhas",
|
||||
@@ -294,12 +301,14 @@
|
||||
"command.new.connectionFolderToolbar": "Adicionar pasta de conexão",
|
||||
"command.new.diagram": "Diagrama ER",
|
||||
"command.new.duckdbDatabase": "Novo banco de dados DuckDB",
|
||||
"command.new.graphqlQuery": "Consulta GraphQL",
|
||||
"command.new.jsonl": "JSON Lines",
|
||||
"command.new.markdown": "Página Markdown",
|
||||
"command.new.modelCompare": "Comparar BD",
|
||||
"command.new.modelTransform": "Transformar modelo",
|
||||
"command.new.newApplication": "Nova aplicação",
|
||||
"command.new.newDiagram": "Novo diagrama ER",
|
||||
"command.new.newGraphqlQuery": "Nova consulta GraphQL",
|
||||
"command.new.newJsonl": "Novo arquivo JSON lines",
|
||||
"command.new.newModelTransform": "Nova transformação de modelo",
|
||||
"command.new.newPerspective": "Nova perspectiva",
|
||||
@@ -342,6 +351,8 @@
|
||||
"command.redisLikeData.save": "Salvar",
|
||||
"command.redo": "Refazer",
|
||||
"command.replace": "Substituir",
|
||||
"command.restApi": "REST API",
|
||||
"command.restApi.execute": "Executar",
|
||||
"command.save": "Salvar",
|
||||
"command.saveAs": "Salvar como",
|
||||
"command.saveToDisk": "Salvar em disco",
|
||||
@@ -432,6 +443,8 @@
|
||||
"common.fileType": "Arquivos {extension}",
|
||||
"common.files.allFiles": "Todos os arquivos",
|
||||
"common.general": "Geral",
|
||||
"common.graphqlChat": "Chat GraphQL",
|
||||
"common.graphqlQuery": "Consulta GraphQL",
|
||||
"common.import": "Importar",
|
||||
"common.kill": "Encerrar",
|
||||
"common.loadingData": "Carregando dados",
|
||||
@@ -534,6 +547,11 @@
|
||||
"connection.accessKeyId": "ID da Chave de Acesso",
|
||||
"connection.allowedDatabases": "Bancos de dados permitidos, um por linha",
|
||||
"connection.allowedDatabasesRegex": "Expressão regular de bancos de dados permitidos",
|
||||
"connection.apiKeyHeader": "Cabeçalho da API Key",
|
||||
"connection.apiKeyValue": "Valor da API Key",
|
||||
"connection.apiQuery": "Consulta API",
|
||||
"connection.apiServerUrl1": "URL do servidor da API",
|
||||
"connection.apiServerUrl2": "URL secundária do servidor da API",
|
||||
"connection.askPassword": "Não salvar, perguntar senha",
|
||||
"connection.askUser": "Não salvar, perguntar login e senha",
|
||||
"connection.authToken": "Token de autenticação",
|
||||
@@ -555,6 +573,7 @@
|
||||
"connection.databaseFilePath": "Arquivo do banco de dados (caminho no servidor)",
|
||||
"connection.databaseUrl": "URL do banco de dados",
|
||||
"connection.defaultDatabase": "Banco de dados padrão",
|
||||
"connection.defaultIsolationLevel": "Nível de isolamento padrão",
|
||||
"connection.delete": "Excluir",
|
||||
"connection.deleteConfirm": "Realmente excluir conexão {name}?",
|
||||
"connection.deleteFolderConfirm": "Realmente excluir pasta {folder}? Conexões na pasta serão movidas para a pasta raiz.",
|
||||
@@ -567,6 +586,9 @@
|
||||
"connection.engine": "Motor do banco de dados",
|
||||
"connection.engineDriverNotFound": "Driver do motor {engine} não encontrado, revise os plugins instalados e altere o motor no diálogo de editar conexão",
|
||||
"connection.fillDetails": "Preencher detalhes da conexão do banco de dados",
|
||||
"connection.httpProxyPassword": "Senha do proxy HTTP",
|
||||
"connection.httpProxyUrl": "URL do proxy HTTP",
|
||||
"connection.httpProxyUser": "Usuário do proxy HTTP",
|
||||
"connection.isReadOnly": "Somente leitura",
|
||||
"connection.keySeparator": "Separador de chave",
|
||||
"connection.localDataCenter": "DataCenter local",
|
||||
@@ -626,6 +648,7 @@
|
||||
"dataForm.noData": "Sem dados",
|
||||
"dataForm.outOfBounds": "Fora dos limites: {current} / {total}",
|
||||
"dataForm.rowCount": "Linha: {current} / {total}",
|
||||
"dataForm.rowCountMany": "Linha: {current} / Muitas",
|
||||
"dataGrid.chooseValue": "Escolher valor de {field}",
|
||||
"dataGrid.codeHighlighting": "Destaque de código:",
|
||||
"dataGrid.codeHighlighting.none": "Nenhum (texto puro)",
|
||||
@@ -664,6 +687,7 @@
|
||||
"database.export": "Exportar",
|
||||
"database.exportDbModel": "Exportar modelo do BD",
|
||||
"database.generateScript": "Gerar script",
|
||||
"database.graphqlChat": "Chat GraphQL",
|
||||
"database.import": "Importar",
|
||||
"database.newApplication": "Nova aplicação",
|
||||
"database.newCollection": "Nova coleção/contêiner",
|
||||
@@ -764,6 +788,7 @@
|
||||
"datagrid.openQuery": "Abrir consulta",
|
||||
"datagrid.resetFilter": "Resetar filtro",
|
||||
"datagrid.resetView": "Resetar visualização",
|
||||
"datagrid.rowCountMany": "Muitas",
|
||||
"datagrid.rows": "Linhas",
|
||||
"datagrid.searchMacros": "Pesquisar macros",
|
||||
"datagrid.selectedInfo.count": "Contagem",
|
||||
@@ -771,6 +796,7 @@
|
||||
"datagrid.selectedInfo.sum": "Soma",
|
||||
"datagrid.setFormat": "Definir formato: ",
|
||||
"datagrid.structure": "Estrutura",
|
||||
"datagrid.structure.notLoaded": "Nenhuma estrutura foi carregada, provavelmente a tabela não existe no banco de dados atual",
|
||||
"datagrid.structure.waiting": "Aguardando estrutura",
|
||||
"datagrid.useMacro": "Usar macro",
|
||||
"dbKeysTreeNode.deleteBranch": "Excluir ramo",
|
||||
@@ -836,6 +862,7 @@
|
||||
"designer.addAllTables": "Adicionar todas as tabelas",
|
||||
"designer.all": "Todas",
|
||||
"designer.allKeys": "Todas as Chaves",
|
||||
"designer.chooseTableColor": "Escolher cor da tabela",
|
||||
"designer.columnProperties": "Propriedades da coluna",
|
||||
"designer.columns": "Colunas - { filterColumns }",
|
||||
"designer.dataTypeYesNo": "Tipo de dados: {show}",
|
||||
@@ -900,7 +927,12 @@
|
||||
"file.queryDesignerFiles": "Arquivos de designer de consulta",
|
||||
"file.sqlFiles": "Arquivos SQL",
|
||||
"file.sqliteDatabase": "Banco de dados SQLite",
|
||||
"files.allConnections": "Todas as conexões",
|
||||
"files.allDatabases": "todos os bancos de dados",
|
||||
"files.allSupportedFiles": "Todos os arquivos suportados",
|
||||
"files.clearConnectionFilter": "Limpar filtro de conexão",
|
||||
"files.connection": "Conexão",
|
||||
"files.currentDatabase": "Banco de dados atual",
|
||||
"files.openFile": "Abrir arquivo",
|
||||
"files.refreshFiles": "Atualizar arquivos",
|
||||
"files.savedFiles": "Arquivos salvos",
|
||||
@@ -1060,6 +1092,7 @@
|
||||
"importExport.value": "Valor",
|
||||
"indexEditor.filteredIndexCondition": "Condição de índice filtrado",
|
||||
"indexEditor.indexName": "Nome do índice",
|
||||
"indexEditor.indexType": "Tipo de índice",
|
||||
"indexEditor.isUnique": "É índice único",
|
||||
"insertJoin.alias": "Alias",
|
||||
"insertJoin.columnFrom": "Coluna de",
|
||||
@@ -1135,6 +1168,10 @@
|
||||
"newObject.erDiagramDisabled": "Diagrama ER não está disponível para o banco de dados atual",
|
||||
"newObject.exportDescription": "Exportar para arquivo como CSV, JSON, Excel ou outro BD",
|
||||
"newObject.exportDisabled": "Exportação não está disponível para o banco de dados atual",
|
||||
"newObject.graphqlChatDescription": "Converse com sua API GraphQL usando IA",
|
||||
"newObject.graphqlChatDisabled": "Chat GraphQL não está disponível para a conexão atual",
|
||||
"newObject.graphqlQueryDescription": "Escreva consultas, escolha atributos e argumentos",
|
||||
"newObject.graphqlQueryDisabled": "Consulta GraphQL não está disponível para o banco de dados atual",
|
||||
"newObject.perspectiveDescription": "Juntar dados complexos de múltiplos bancos de dados",
|
||||
"newObject.queryDesignerDescription": "Projetar consultas SQL visualmente",
|
||||
"newObject.queryDesignerDisabled": "Designer de Consulta não está disponível para o banco de dados atual",
|
||||
@@ -1158,6 +1195,7 @@
|
||||
"privateCloudWidget.addNewConnectionOrFile": "Adicionar nova conexão ou arquivo",
|
||||
"privateCloudWidget.addNewFolder": "Adicionar nova pasta",
|
||||
"privateCloudWidget.administrateAccess": "Administrar acesso",
|
||||
"privateCloudWidget.cloudUnavailable": "DbGate Cloud está temporariamente indisponível",
|
||||
"privateCloudWidget.createConnection": "Criar conexão no DbGate Cloud",
|
||||
"privateCloudWidget.createSharedFolder": "Criar pasta compartilhada",
|
||||
"privateCloudWidget.deleteFolder": "Excluir pasta",
|
||||
@@ -1170,6 +1208,7 @@
|
||||
"privateCloudWidget.renameFolder": "Renomear pasta",
|
||||
"privateCloudWidget.searchPlaceholder": "Pesquisar conexões e arquivos na nuvem",
|
||||
"privateCloudWidget.yourInviteLink": "Seu link de convite (no formato dbgate://folder/xxx)",
|
||||
"publicCloudWidget.cloudUnavailable": "DbGate Cloud está temporariamente indisponível",
|
||||
"publicCloudWidget.noFilesFound": "Nenhum arquivo encontrado para sua configuração",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Apenas arquivos relevantes para suas conexões, plataforma e edição do DbGate são listados. Defina conexões primeiro.",
|
||||
"publicCloudWidget.publicKnowledgeBase": "Base de Conhecimento Pública",
|
||||
@@ -1191,10 +1230,13 @@
|
||||
"query.aggregate": "Agregação",
|
||||
"query.alias": "Alias",
|
||||
"query.columnExpression": "Coluna/Expressão",
|
||||
"query.defaultIsolationLevel": "Padrão",
|
||||
"query.defaultIsolationLevelNamed": "Padrão ({level})",
|
||||
"query.download": "baixar",
|
||||
"query.filter": "Filtro",
|
||||
"query.groupBy": "Agrupar por",
|
||||
"query.groupFilter": "Filtro de grupo",
|
||||
"query.isolationLevel": "Nível de isolamento",
|
||||
"query.limitRows": "Limitar a {queryRowsLimit} linhas",
|
||||
"query.named": ":variável",
|
||||
"query.noParameters": "(sem parâmetros)",
|
||||
@@ -1287,6 +1329,7 @@
|
||||
"settings.behaviour.openDetailOnArrows": "Abrir detalhe na navegação por teclado",
|
||||
"settings.behaviour.singleClickPreview": "Quando você clica uma vez ou seleciona um arquivo na visão \"Tabelas, Visões, Funções\", ele é mostrado em modo de visualização e reutiliza uma aba existente (aba de visualização). Isso é útil se você está navegando rapidamente pelas tabelas e não quer que cada tabela visitada tenha sua própria aba. Quando você começa a editar a tabela ou usa duplo clique para abrir a tabela da visão \"Tabelas\", uma nova aba é dedicada à essa tabela.",
|
||||
"settings.behaviour.useTabPreviewMode": "Usar modo de visualização de aba",
|
||||
"settings.checkAll": "Marcar todos / Desmarcar todos",
|
||||
"settings.confirmations": "Confirmações",
|
||||
"settings.confirmations.skipConfirm.collectionDataSave": "Pular confirmação ao salvar dados de coleção (NoSQL)",
|
||||
"settings.confirmations.skipConfirm.tableDataSave": "Pular confirmação ao salvar dados de tabela (SQL)",
|
||||
@@ -1305,6 +1348,7 @@
|
||||
"settings.dataGrid.coloringMode.36": "A cada 3ª e 6ª linha",
|
||||
"settings.dataGrid.coloringMode.none": "Nenhum",
|
||||
"settings.dataGrid.defaultAutoRefreshInterval": "Intervalo padrão de atualização automática da grade em segundos",
|
||||
"settings.dataGrid.disableCellDataViewAutoOpen": "Desabilitar abertura automática da Visualização de Dados da Célula",
|
||||
"settings.dataGrid.pageSize": "Tamanho da página (número de linhas para carregamento incremental, deve estar entre 5 e 50000)",
|
||||
"settings.dataGrid.showAllColumnsWhenSearch": "Mostrar todas as colunas ao pesquisar",
|
||||
"settings.dataGrid.showHintColumns": "Mostrar dicas de chave estrangeira",
|
||||
@@ -1331,6 +1375,7 @@
|
||||
"settings.defaultActions.tableClick": "Clique em tabela",
|
||||
"settings.defaultActions.useLastUsedAction": "Usar última ação utilizada",
|
||||
"settings.defaultActions.viewClick": "Clique em visão",
|
||||
"settings.drivers": "Drivers",
|
||||
"settings.editor.keybinds": "Atalhos do editor",
|
||||
"settings.editor.wordWrap": "Habilitar quebra de linha",
|
||||
"settings.externalTools": "Ferramentas externas",
|
||||
@@ -1355,6 +1400,9 @@
|
||||
"settings.other.licenseKey.invalid": "Chave de licença inválida",
|
||||
"settings.other.licenseKey.valid": "Chave de licença válida",
|
||||
"settings.other.licenseKey.validTo": "Licença válida até:",
|
||||
"settings.other.toolBarPosition": "Posição da barra de ferramentas",
|
||||
"settings.other.toolBarPosition.bottom": "Inferior",
|
||||
"settings.other.toolBarPosition.top": "Superior",
|
||||
"settings.session": "Sessões de consulta",
|
||||
"settings.session.autoClose": "Fechar automaticamente sessões de consulta após período sem atividade",
|
||||
"settings.session.autoCloseTimeout": "Intervalo, após o qual a sessão de consulta sem atividade é fechada (em minutos)",
|
||||
@@ -1393,6 +1441,7 @@
|
||||
"sqlGenerator.omitNulls": "Omitir valores NULL",
|
||||
"sqlGenerator.searchTablesOrObjects": "Pesquisar tabelas ou objetos",
|
||||
"sqlGenerator.skipAutoincrementColumn": "Ignorar coluna autoincremento",
|
||||
"sqlGenerator.skipComputedColumns": "Ignorar colunas computadas",
|
||||
"sqlGenerator.sqlGenerator": "Gerador SQL",
|
||||
"sqlGenerator.sqlTruncated": "SQL truncado, limite de tamanho de arquivo excedido",
|
||||
"sqlGenerator.tables": "Tabelas",
|
||||
@@ -1467,6 +1516,7 @@
|
||||
"tableEditor.defaultValue": "Valor padrão",
|
||||
"tableEditor.dependencies": "Dependências",
|
||||
"tableEditor.foreignKeys": "Chaves estrangeiras ({foreignKeyCount})",
|
||||
"tableEditor.indexType": "Tipo",
|
||||
"tableEditor.indexes": "Índices ({indexCount})",
|
||||
"tableEditor.isPersisted": "Está persistido",
|
||||
"tableEditor.isSparse": "Está esparso",
|
||||
@@ -1485,7 +1535,6 @@
|
||||
"tableEditor.remove": "Remover",
|
||||
"tableEditor.tablename": "Nome da tabela",
|
||||
"tableEditor.tableproperties": "Propriedades da tabela",
|
||||
"tableEditor.unique": "Único",
|
||||
"tableEditor.uniqueConstraints": "Restrições únicas ({constraintCount})",
|
||||
"tableEditor.yes": "SIM",
|
||||
"tableStructure.alter": "Alterar tabela",
|
||||
@@ -1521,6 +1570,7 @@
|
||||
"widget.collectionsContainers": "Coleções/contêineres",
|
||||
"widget.databaseContent": "Conteúdo do banco de dados",
|
||||
"widget.databases": "Bancos de dados",
|
||||
"widget.endpoints": "Endpoints",
|
||||
"widget.keys": "Chaves",
|
||||
"widget.pinned": "Fixados",
|
||||
"widget.tablesViewsFunctions": "Tabelas, visões, funções",
|
||||
@@ -1535,4 +1585,4 @@
|
||||
"widgets.openedTabs": "Abas abertas",
|
||||
"widgets.premiumPromo": "Promoção Premium",
|
||||
"widgets.queryHistoryAndClosedTabs": "Histórico de consultas e abas fechadas"
|
||||
}
|
||||
}
|
||||
|
||||
+52
-2
@@ -113,6 +113,7 @@
|
||||
"command.about": "O aplikácii",
|
||||
"command.about.show": "Zobraziť",
|
||||
"command.about.toolbar": "O aplikácii",
|
||||
"command.apiQuery": "API dotaz",
|
||||
"command.app.checkForUpdates": "Skontrolovať dostupnosť aktualizácií",
|
||||
"command.app.disconnect": "Odpojiť",
|
||||
"command.app.loggedUser": "Prihlásený používateľ",
|
||||
@@ -245,6 +246,7 @@
|
||||
"command.designer": "Návrhár",
|
||||
"command.designer.arrange": "Usporiadať",
|
||||
"command.designer.exportDiagram": "Exportovať diagram",
|
||||
"command.designer.exportDiagramPng": "Exportovať diagram ako PNG",
|
||||
"command.designer.openSql": "Otvoriť SQL",
|
||||
"command.designer.remove": "Odstrániť",
|
||||
"command.designer.removeSelectedTables": "Odstrániť vybrané tabuľky",
|
||||
@@ -272,6 +274,11 @@
|
||||
"command.folder": "Priečinok",
|
||||
"command.folder.openData": "Otvoriť priečinok dát",
|
||||
"command.folder.openLogs": "Otvoriť logy",
|
||||
"command.gqlConnection": "GraphQL pripojenie",
|
||||
"command.gqlConnection.toggleCellDataView": "Prepnúť zobrazenie dát bunky",
|
||||
"command.gqlConnection.toggleCellDataView.menu": "Zobraziť dáta bunky",
|
||||
"command.gqlConnection.toggleCellDataView.toolbar": "Dáta bunky",
|
||||
"command.graphql.chat": "GraphQL chat",
|
||||
"command.internal": "Interné",
|
||||
"command.internal.loadCampaigns": "Načítať zoznam kampaní",
|
||||
"command.internal.showCampaigns": "Zobraziť kampane",
|
||||
@@ -294,12 +301,14 @@
|
||||
"command.new.connectionFolderToolbar": "Pridať priečinok pripojení",
|
||||
"command.new.diagram": "ER Diagram",
|
||||
"command.new.duckdbDatabase": "Nová DuckDB databáza",
|
||||
"command.new.graphqlQuery": "GraphQL dotaz",
|
||||
"command.new.jsonl": "JSON Lines",
|
||||
"command.new.markdown": "Markdown stránka",
|
||||
"command.new.modelCompare": "Porovnať DB",
|
||||
"command.new.modelTransform": "Transformácia modelu",
|
||||
"command.new.newApplication": "Nová aplikácia",
|
||||
"command.new.newDiagram": "Nový ER diagram",
|
||||
"command.new.newGraphqlQuery": "Nový GraphQL dotaz",
|
||||
"command.new.newJsonl": "Nový JSON lines súbor",
|
||||
"command.new.newModelTransform": "Nová transformácia modelu",
|
||||
"command.new.newPerspective": "Nová perspektíva",
|
||||
@@ -342,6 +351,8 @@
|
||||
"command.redisLikeData.save": "Uložiť",
|
||||
"command.redo": "Opakovať",
|
||||
"command.replace": "Nahradiť",
|
||||
"command.restApi": "REST API",
|
||||
"command.restApi.execute": "Vykonať",
|
||||
"command.save": "Uložiť",
|
||||
"command.saveAs": "Uložiť ako",
|
||||
"command.saveToDisk": "Uložiť na disk",
|
||||
@@ -432,6 +443,8 @@
|
||||
"common.fileType": "{extension} súbory",
|
||||
"common.files.allFiles": "Všetky súbory",
|
||||
"common.general": "Všeobecné",
|
||||
"common.graphqlChat": "GraphQL Chat",
|
||||
"common.graphqlQuery": "GraphQL dotaz",
|
||||
"common.import": "Importovať",
|
||||
"common.kill": "Ukončiť",
|
||||
"common.loadingData": "Načítavanie dát",
|
||||
@@ -534,6 +547,11 @@
|
||||
"connection.accessKeyId": "ID prístupového kľúča",
|
||||
"connection.allowedDatabases": "Povolené databázy, jedna na riadok",
|
||||
"connection.allowedDatabasesRegex": "Regulárny výraz pre povolené databázy",
|
||||
"connection.apiKeyHeader": "Hlavička API kľúča",
|
||||
"connection.apiKeyValue": "Hodnota API kľúča",
|
||||
"connection.apiQuery": "API dotaz",
|
||||
"connection.apiServerUrl1": "URL API servera",
|
||||
"connection.apiServerUrl2": "URL sekundárneho API servera",
|
||||
"connection.askPassword": "Neukladať, pýtať sa na heslo",
|
||||
"connection.askUser": "Neukladať, pýtať sa na prihlasovacie údaje a heslo",
|
||||
"connection.authToken": "Autentifikačný token",
|
||||
@@ -555,6 +573,7 @@
|
||||
"connection.databaseFilePath": "Súbor databázy (cesta na serveri)",
|
||||
"connection.databaseUrl": "URL databázy",
|
||||
"connection.defaultDatabase": "Predvolená databáza",
|
||||
"connection.defaultIsolationLevel": "Predvolená úroveň izolácie",
|
||||
"connection.delete": "Odstrániť",
|
||||
"connection.deleteConfirm": "Naozaj odstrániť pripojenie {name}?",
|
||||
"connection.deleteFolderConfirm": "Naozaj odstrániť priečinok {folder}? Pripojenia v priečinku budú presunuté do koreňového priečinka.",
|
||||
@@ -567,6 +586,9 @@
|
||||
"connection.engine": "Typ databázy",
|
||||
"connection.engineDriverNotFound": "Driver databázy {engine} nebol nájdený, skontrolujte nainštalované pluginy a zmeňte typ databázy v dialógu úpravy pripojenia",
|
||||
"connection.fillDetails": "Vyplňte údaje o pripojení k databáze",
|
||||
"connection.httpProxyPassword": "Heslo HTTP proxy",
|
||||
"connection.httpProxyUrl": "URL HTTP proxy",
|
||||
"connection.httpProxyUser": "Používateľ HTTP proxy",
|
||||
"connection.isReadOnly": "Je iba na čítanie",
|
||||
"connection.keySeparator": "Oddeľovač kľúčov",
|
||||
"connection.localDataCenter": "Lokálne dátové centrum",
|
||||
@@ -626,6 +648,7 @@
|
||||
"dataForm.noData": "Žiadne dáta",
|
||||
"dataForm.outOfBounds": "Mimo rozsahu: {current} / {total}",
|
||||
"dataForm.rowCount": "Riadok: {current} / {total}",
|
||||
"dataForm.rowCountMany": "Riadok: {current} / mnoho",
|
||||
"dataGrid.chooseValue": "Vybrať hodnotu z {field}",
|
||||
"dataGrid.codeHighlighting": "Zvýraznenie kódu:",
|
||||
"dataGrid.codeHighlighting.none": "Žiadne (neformátovaný text)",
|
||||
@@ -664,6 +687,7 @@
|
||||
"database.export": "Exportovať",
|
||||
"database.exportDbModel": "Exportovať DB model",
|
||||
"database.generateScript": "Generovať skript",
|
||||
"database.graphqlChat": "GraphQL chat",
|
||||
"database.import": "Importovať",
|
||||
"database.newApplication": "Nová aplikácia",
|
||||
"database.newCollection": "Nová kolekcia/kontajner",
|
||||
@@ -764,6 +788,7 @@
|
||||
"datagrid.openQuery": "Otvoriť dotaz",
|
||||
"datagrid.resetFilter": "Resetovať filter",
|
||||
"datagrid.resetView": "Resetovať zobrazenie",
|
||||
"datagrid.rowCountMany": "Mnoho",
|
||||
"datagrid.rows": "Riadky",
|
||||
"datagrid.searchMacros": "Vyhľadať makrá",
|
||||
"datagrid.selectedInfo.count": "Počet",
|
||||
@@ -771,6 +796,7 @@
|
||||
"datagrid.selectedInfo.sum": "Súčet",
|
||||
"datagrid.setFormat": "Nastaviť formát: ",
|
||||
"datagrid.structure": "Štruktúra",
|
||||
"datagrid.structure.notLoaded": "Nebola načítaná žiadna štruktúra, pravdepodobne tabuľka neexistuje v aktuálnej databáze",
|
||||
"datagrid.structure.waiting": "Čaká sa na štruktúru",
|
||||
"datagrid.useMacro": "Použiť makro",
|
||||
"dbKeysTreeNode.deleteBranch": "Odstrániť vetvu",
|
||||
@@ -836,6 +862,7 @@
|
||||
"designer.addAllTables": "Pridať všetky tabuľky",
|
||||
"designer.all": "Všetko",
|
||||
"designer.allKeys": "Všetky kľúče",
|
||||
"designer.chooseTableColor": "Vybrať farbu tabuľky",
|
||||
"designer.columnProperties": "Vlastnosti stĺpca",
|
||||
"designer.columns": "Stĺpce - { filterColumns }",
|
||||
"designer.dataTypeYesNo": "Dátový typ: {show}",
|
||||
@@ -900,7 +927,12 @@
|
||||
"file.queryDesignerFiles": "Súbory návrhu dotazu",
|
||||
"file.sqlFiles": "SQL súbory",
|
||||
"file.sqliteDatabase": "SQLite databáza",
|
||||
"files.allConnections": "Všetky pripojenia",
|
||||
"files.allDatabases": "všetky databázy",
|
||||
"files.allSupportedFiles": "Všetky podporované súbory",
|
||||
"files.clearConnectionFilter": "Vymazať filter pripojení",
|
||||
"files.connection": "Pripojenie",
|
||||
"files.currentDatabase": "Aktuálna databáza",
|
||||
"files.openFile": "Otvoriť súbor",
|
||||
"files.refreshFiles": "Obnoviť súbory",
|
||||
"files.savedFiles": "Uložené súbory",
|
||||
@@ -1060,6 +1092,7 @@
|
||||
"importExport.value": "Hodnota",
|
||||
"indexEditor.filteredIndexCondition": "Podmienka filtrovaného indexu",
|
||||
"indexEditor.indexName": "Názov indexu",
|
||||
"indexEditor.indexType": "Typ indexu",
|
||||
"indexEditor.isUnique": "Je jedinečný index",
|
||||
"insertJoin.alias": "Alias",
|
||||
"insertJoin.columnFrom": "Stĺpec z",
|
||||
@@ -1135,6 +1168,10 @@
|
||||
"newObject.erDiagramDisabled": "ER Diagram nie je k dispozícii pre aktuálnu databázu",
|
||||
"newObject.exportDescription": "Exportovať do súboru ako CSV, JSON, Excel alebo inej DB",
|
||||
"newObject.exportDisabled": "Export nie je k dispozícii pre aktuálnu databázu",
|
||||
"newObject.graphqlChatDescription": "Chat s vaším GraphQL API pomocou AI",
|
||||
"newObject.graphqlChatDisabled": "GraphQL chat nie je k dispozícii pre aktuálne pripojenie",
|
||||
"newObject.graphqlQueryDescription": "Písať dotazy, vyberať atribúty a argumenty",
|
||||
"newObject.graphqlQueryDisabled": "GraphQL dotaz nie je k dispozícii pre aktuálnu databázu",
|
||||
"newObject.perspectiveDescription": "Spojiť údaje z viacerých databáz",
|
||||
"newObject.queryDesignerDescription": "Navrhnúť SQL dotazy vizuálne",
|
||||
"newObject.queryDesignerDisabled": "Návrhár dotazov nie je k dispozícii pre aktuálnu databázu",
|
||||
@@ -1158,6 +1195,7 @@
|
||||
"privateCloudWidget.addNewConnectionOrFile": "Pridať nové pripojenie alebo súbor",
|
||||
"privateCloudWidget.addNewFolder": "Pridať nový priečinok",
|
||||
"privateCloudWidget.administrateAccess": "Spravovať prístup",
|
||||
"privateCloudWidget.cloudUnavailable": "DbGate Cloud je dočasne nedostupný",
|
||||
"privateCloudWidget.createConnection": "Vytvoriť pripojenie na DbGate Cloud",
|
||||
"privateCloudWidget.createSharedFolder": "Vytvoriť zdieľaný priečinok",
|
||||
"privateCloudWidget.deleteFolder": "Odstrániť priečinok",
|
||||
@@ -1170,6 +1208,7 @@
|
||||
"privateCloudWidget.renameFolder": "Premenovať priečinok",
|
||||
"privateCloudWidget.searchPlaceholder": "Hľadať cloud pripojenia a súbory",
|
||||
"privateCloudWidget.yourInviteLink": "Váš pozývací odkaz (vo forme dbgate://folder/xxx)",
|
||||
"publicCloudWidget.cloudUnavailable": "DbGate Cloud je dočasne nedostupný",
|
||||
"publicCloudWidget.noFilesFound": "Pre vašu konfiguráciu neboli nájdené žiadne súbory",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Sú zobrazené iba súbory relevantné pre vaše pripojenia, platformu a edíciu DbGate. Najprv definujte pripojenia.",
|
||||
"publicCloudWidget.publicKnowledgeBase": "Verejná znalostná báza",
|
||||
@@ -1191,10 +1230,13 @@
|
||||
"query.aggregate": "Agregácia",
|
||||
"query.alias": "Alias",
|
||||
"query.columnExpression": "Stĺpec/Výraz",
|
||||
"query.defaultIsolationLevel": "Predvolená",
|
||||
"query.defaultIsolationLevelNamed": "Predvolená ({level})",
|
||||
"query.download": "stiahnuť",
|
||||
"query.filter": "Filter",
|
||||
"query.groupBy": "Zoskupiť podľa",
|
||||
"query.groupFilter": "Filter skupiny",
|
||||
"query.isolationLevel": "Úroveň izolácie",
|
||||
"query.limitRows": "Obmedziť na {queryRowsLimit} riadkov",
|
||||
"query.named": ":premenná",
|
||||
"query.noParameters": "(žiadne parametre)",
|
||||
@@ -1287,6 +1329,7 @@
|
||||
"settings.behaviour.openDetailOnArrows": "Otvoriť detail pri navigácii klávesnicou",
|
||||
"settings.behaviour.singleClickPreview": "Pri jednoduchom kliknutí alebo výbere súboru v zobrazení \"Tabuľky, pohľady, funkcie\" sa zobrazí v režime náhľadu a znovu použije existujúcu kartu (karta náhľadu). Toto je užitočné, ak rýchlo prehliadate tabuľky a nechcete, aby každá navštívená tabuľka mala svoju vlastnú kartu. Keď začnete upravovať tabuľku alebo použijete dvojklik na otvorenie tabuľky zo zobrazenia \"Tabuľky\", nová karta bude venovaná tejto tabuľke.",
|
||||
"settings.behaviour.useTabPreviewMode": "Použiť režim náhľadu na karte",
|
||||
"settings.checkAll": "Označiť všetko / Zrušiť označenie všetkých",
|
||||
"settings.confirmations": "Potvrdenia",
|
||||
"settings.confirmations.skipConfirm.collectionDataSave": "Preskočiť potvrdenie pri ukladaní údajov kolekcie (NoSQL)",
|
||||
"settings.confirmations.skipConfirm.tableDataSave": "Preskočiť potvrdenie pri ukladaní údajov tabuľky (SQL)",
|
||||
@@ -1305,6 +1348,7 @@
|
||||
"settings.dataGrid.coloringMode.36": "Každý 3. a 6. riadok",
|
||||
"settings.dataGrid.coloringMode.none": "Žiadne",
|
||||
"settings.dataGrid.defaultAutoRefreshInterval": "Predvolený interval automatického obnovenia mriežky v sekundách",
|
||||
"settings.dataGrid.disableCellDataViewAutoOpen": "Zakázať automatické otvorenie zobrazenia dát bunky",
|
||||
"settings.dataGrid.pageSize": "Veľkosť stránky (počet riadkov pre inkrementálne načítanie, musí byť medzi 5 a 50000)",
|
||||
"settings.dataGrid.showAllColumnsWhenSearch": "Zobraziť všetky stĺpce pri vyhľadávaní",
|
||||
"settings.dataGrid.showHintColumns": "Zobraziť nápovedy pre cudzie kľúče",
|
||||
@@ -1331,6 +1375,7 @@
|
||||
"settings.defaultActions.tableClick": "Kliknutie na tabuľku",
|
||||
"settings.defaultActions.useLastUsedAction": "Použiť naposledy použitú akciu",
|
||||
"settings.defaultActions.viewClick": "Kliknutie na pohľad",
|
||||
"settings.drivers": "Ovládače",
|
||||
"settings.editor.keybinds": "Klávesové skratky editora",
|
||||
"settings.editor.wordWrap": "Povoliť zalomovanie riadkov",
|
||||
"settings.externalTools": "Externé nástroje",
|
||||
@@ -1355,6 +1400,9 @@
|
||||
"settings.other.licenseKey.invalid": "Licenčný kľúč je neplatný",
|
||||
"settings.other.licenseKey.valid": "Licenčný kľúč je platný",
|
||||
"settings.other.licenseKey.validTo": "Licencia platná do:",
|
||||
"settings.other.toolBarPosition": "Pozícia panela nástrojov",
|
||||
"settings.other.toolBarPosition.bottom": "Dole",
|
||||
"settings.other.toolBarPosition.top": "Hore",
|
||||
"settings.session": "Dotazové relácie",
|
||||
"settings.session.autoClose": "Automaticky zatvoriť relácie dotazov po čase nečinnosti",
|
||||
"settings.session.autoCloseTimeout": "Interval, po ktorom sa relácia dotazov bez aktivity zatvorí (v minútach)",
|
||||
@@ -1393,6 +1441,7 @@
|
||||
"sqlGenerator.omitNulls": "Vynechať NULL hodnoty",
|
||||
"sqlGenerator.searchTablesOrObjects": "Hľadať tabuľky alebo objekty",
|
||||
"sqlGenerator.skipAutoincrementColumn": "Preskočiť autoinkrement stĺpec",
|
||||
"sqlGenerator.skipComputedColumns": "Preskočiť vypočítané stĺpce",
|
||||
"sqlGenerator.sqlGenerator": "SQL Generátor",
|
||||
"sqlGenerator.sqlTruncated": "SQL skrátené, prekročený limit veľkosti súboru",
|
||||
"sqlGenerator.tables": "Tabuľky",
|
||||
@@ -1467,6 +1516,7 @@
|
||||
"tableEditor.defaultValue": "Predvolená hodnota",
|
||||
"tableEditor.dependencies": "Závislosti",
|
||||
"tableEditor.foreignKeys": "Cudzie kľúče ({foreignKeyCount})",
|
||||
"tableEditor.indexType": "Typ",
|
||||
"tableEditor.indexes": "Indexy ({indexCount})",
|
||||
"tableEditor.isPersisted": "Je perzistentný",
|
||||
"tableEditor.isSparse": "Je riedky",
|
||||
@@ -1485,7 +1535,6 @@
|
||||
"tableEditor.remove": "Odstrániť",
|
||||
"tableEditor.tablename": "Názov tabuľky",
|
||||
"tableEditor.tableproperties": "Vlastnosti tabuľky",
|
||||
"tableEditor.unique": "Jedinečné",
|
||||
"tableEditor.uniqueConstraints": "Obmedzenia jedinečnosti ({constraintCount})",
|
||||
"tableEditor.yes": "ÁNO",
|
||||
"tableStructure.alter": "Úprava tabuľky",
|
||||
@@ -1521,6 +1570,7 @@
|
||||
"widget.collectionsContainers": "Kolekcie/kontajnery",
|
||||
"widget.databaseContent": "Obsah databázy",
|
||||
"widget.databases": "Databázy",
|
||||
"widget.endpoints": "Endpointy",
|
||||
"widget.keys": "Kľúče",
|
||||
"widget.pinned": "Pripnuté",
|
||||
"widget.tablesViewsFunctions": "Tabuľky, pohľady, funkcie",
|
||||
@@ -1535,4 +1585,4 @@
|
||||
"widgets.openedTabs": "Otvorené karty",
|
||||
"widgets.premiumPromo": "Premium promo",
|
||||
"widgets.queryHistoryAndClosedTabs": "História dotazov a zatvorené karty"
|
||||
}
|
||||
}
|
||||
|
||||
+52
-2
@@ -113,6 +113,7 @@
|
||||
"command.about": "关于",
|
||||
"command.about.show": "显示",
|
||||
"command.about.toolbar": "关于",
|
||||
"command.apiQuery": "API 查询",
|
||||
"command.app.checkForUpdates": "检查更新",
|
||||
"command.app.disconnect": "断开连接",
|
||||
"command.app.loggedUser": "已登录用户",
|
||||
@@ -245,6 +246,7 @@
|
||||
"command.designer": "设计器",
|
||||
"command.designer.arrange": "排列",
|
||||
"command.designer.exportDiagram": "导出图表",
|
||||
"command.designer.exportDiagramPng": "导出图表为 PNG",
|
||||
"command.designer.openSql": "打开 SQL",
|
||||
"command.designer.remove": "删除",
|
||||
"command.designer.removeSelectedTables": "删除选中的表",
|
||||
@@ -272,6 +274,11 @@
|
||||
"command.folder": "文件夹",
|
||||
"command.folder.openData": "打开数据文件夹",
|
||||
"command.folder.openLogs": "打开日志",
|
||||
"command.gqlConnection": "GraphQL 连接",
|
||||
"command.gqlConnection.toggleCellDataView": "切换单元格数据视图",
|
||||
"command.gqlConnection.toggleCellDataView.menu": "显示单元格数据",
|
||||
"command.gqlConnection.toggleCellDataView.toolbar": "单元格数据",
|
||||
"command.graphql.chat": "GraphQL 聊天",
|
||||
"command.internal": "内部",
|
||||
"command.internal.loadCampaigns": "加载活动列表",
|
||||
"command.internal.showCampaigns": "显示活动",
|
||||
@@ -294,12 +301,14 @@
|
||||
"command.new.connectionFolderToolbar": "添加连接文件夹",
|
||||
"command.new.diagram": "ER 图",
|
||||
"command.new.duckdbDatabase": "新建 DuckDB 数据库",
|
||||
"command.new.graphqlQuery": "GraphQL 查询",
|
||||
"command.new.jsonl": "JSON 行文件",
|
||||
"command.new.markdown": "Markdown 页面",
|
||||
"command.new.modelCompare": "比较数据库",
|
||||
"command.new.modelTransform": "模型转换",
|
||||
"command.new.newApplication": "新建应用程序",
|
||||
"command.new.newDiagram": "新建 ER 图",
|
||||
"command.new.newGraphqlQuery": "新建 GraphQL 查询",
|
||||
"command.new.newJsonl": "新建 JSON 行文件",
|
||||
"command.new.newModelTransform": "新建模型转换",
|
||||
"command.new.newPerspective": "新建视图",
|
||||
@@ -342,6 +351,8 @@
|
||||
"command.redisLikeData.save": "保存",
|
||||
"command.redo": "重做",
|
||||
"command.replace": "替换",
|
||||
"command.restApi": "REST API",
|
||||
"command.restApi.execute": "执行",
|
||||
"command.save": "保存",
|
||||
"command.saveAs": "另存为",
|
||||
"command.saveToDisk": "保存到磁盘",
|
||||
@@ -432,6 +443,8 @@
|
||||
"common.fileType": "{extension} 文件",
|
||||
"common.files.allFiles": "所有文件",
|
||||
"common.general": "常规",
|
||||
"common.graphqlChat": "GraphQL 聊天",
|
||||
"common.graphqlQuery": "GraphQL 查询",
|
||||
"common.import": "导入",
|
||||
"common.kill": "终止",
|
||||
"common.loadingData": "正在加载数据",
|
||||
@@ -534,6 +547,11 @@
|
||||
"connection.accessKeyId": "访问密钥 ID",
|
||||
"connection.allowedDatabases": "允许的数据库,每行一个",
|
||||
"connection.allowedDatabasesRegex": "允许的数据库正则表达式",
|
||||
"connection.apiKeyHeader": "API 密钥请求头",
|
||||
"connection.apiKeyValue": "API 密钥值",
|
||||
"connection.apiQuery": "API 查询",
|
||||
"connection.apiServerUrl1": "API 服务器 URL",
|
||||
"connection.apiServerUrl2": "API 备用服务器 URL",
|
||||
"connection.askPassword": "不保存,询问密码",
|
||||
"connection.askUser": "不保存,询问登录名和密码",
|
||||
"connection.authToken": "认证令牌",
|
||||
@@ -555,6 +573,7 @@
|
||||
"connection.databaseFilePath": "数据库文件(服务器上的路径)",
|
||||
"connection.databaseUrl": "数据库 URL",
|
||||
"connection.defaultDatabase": "默认数据库",
|
||||
"connection.defaultIsolationLevel": "默认隔离级别",
|
||||
"connection.delete": "删除",
|
||||
"connection.deleteConfirm": "确定删除连接 {name} 吗?",
|
||||
"connection.deleteFolderConfirm": "确定删除文件夹 {folder} 吗?文件夹中的连接将移动到根文件夹。",
|
||||
@@ -567,6 +586,9 @@
|
||||
"connection.engine": "数据库引擎",
|
||||
"connection.engineDriverNotFound": "未找到引擎驱动程序 {engine},请检查已安装的插件并在编辑连接对话框中更改引擎",
|
||||
"connection.fillDetails": "填写数据库连接详情",
|
||||
"connection.httpProxyPassword": "HTTP 代理密码",
|
||||
"connection.httpProxyUrl": "HTTP 代理 URL",
|
||||
"connection.httpProxyUser": "HTTP 代理用户",
|
||||
"connection.isReadOnly": "是否只读",
|
||||
"connection.keySeparator": "键分隔符",
|
||||
"connection.localDataCenter": "本地数据中心",
|
||||
@@ -626,6 +648,7 @@
|
||||
"dataForm.noData": "无数据",
|
||||
"dataForm.outOfBounds": "超出范围:{current} / {total}",
|
||||
"dataForm.rowCount": "行:{current} / {total}",
|
||||
"dataForm.rowCountMany": "行:{current} / 多个",
|
||||
"dataGrid.chooseValue": "从 {field} 中选择值",
|
||||
"dataGrid.codeHighlighting": "代码高亮:",
|
||||
"dataGrid.codeHighlighting.none": "无(原始文本)",
|
||||
@@ -664,6 +687,7 @@
|
||||
"database.export": "导出",
|
||||
"database.exportDbModel": "导出数据库模型",
|
||||
"database.generateScript": "生成脚本",
|
||||
"database.graphqlChat": "GraphQL 聊天",
|
||||
"database.import": "导入",
|
||||
"database.newApplication": "新建应用程序",
|
||||
"database.newCollection": "新建集合/容器",
|
||||
@@ -764,6 +788,7 @@
|
||||
"datagrid.openQuery": "打开查询",
|
||||
"datagrid.resetFilter": "重置筛选",
|
||||
"datagrid.resetView": "重置视图",
|
||||
"datagrid.rowCountMany": "多个",
|
||||
"datagrid.rows": "行",
|
||||
"datagrid.searchMacros": "搜索宏",
|
||||
"datagrid.selectedInfo.count": "数量",
|
||||
@@ -771,6 +796,7 @@
|
||||
"datagrid.selectedInfo.sum": "合计",
|
||||
"datagrid.setFormat": "设置格式:",
|
||||
"datagrid.structure": "结构",
|
||||
"datagrid.structure.notLoaded": "未加载任何结构,可能当前数据库中不存在该表",
|
||||
"datagrid.structure.waiting": "正在等待结构",
|
||||
"datagrid.useMacro": "使用宏",
|
||||
"dbKeysTreeNode.deleteBranch": "删除分支",
|
||||
@@ -836,6 +862,7 @@
|
||||
"designer.addAllTables": "添加所有表",
|
||||
"designer.all": "全部",
|
||||
"designer.allKeys": "所有键",
|
||||
"designer.chooseTableColor": "选择表颜色",
|
||||
"designer.columnProperties": "列属性",
|
||||
"designer.columns": "列 - { filterColumns }",
|
||||
"designer.dataTypeYesNo": "数据类型:{show}",
|
||||
@@ -900,7 +927,12 @@
|
||||
"file.queryDesignerFiles": "查询设计器文件",
|
||||
"file.sqlFiles": "SQL文件",
|
||||
"file.sqliteDatabase": "SQLite数据库",
|
||||
"files.allConnections": "所有连接",
|
||||
"files.allDatabases": "所有数据库",
|
||||
"files.allSupportedFiles": "所有支持的文件",
|
||||
"files.clearConnectionFilter": "清除连接筛选",
|
||||
"files.connection": "连接",
|
||||
"files.currentDatabase": "当前数据库",
|
||||
"files.openFile": "打开文件",
|
||||
"files.refreshFiles": "刷新文件",
|
||||
"files.savedFiles": "已保存文件",
|
||||
@@ -1060,6 +1092,7 @@
|
||||
"importExport.value": "值",
|
||||
"indexEditor.filteredIndexCondition": "过滤索引条件",
|
||||
"indexEditor.indexName": "索引名称",
|
||||
"indexEditor.indexType": "索引类型",
|
||||
"indexEditor.isUnique": "是唯一索引",
|
||||
"insertJoin.alias": "别名",
|
||||
"insertJoin.columnFrom": "源列",
|
||||
@@ -1135,6 +1168,10 @@
|
||||
"newObject.erDiagramDisabled": "当前数据库不支持ER关系图",
|
||||
"newObject.exportDescription": "导出为CSV、JSON、Excel或其他数据库文件",
|
||||
"newObject.exportDisabled": "当前数据库不支持导出",
|
||||
"newObject.graphqlChatDescription": "使用 AI 与 GraphQL API 聊天",
|
||||
"newObject.graphqlChatDisabled": "当前连接不支持 GraphQL 聊天",
|
||||
"newObject.graphqlQueryDescription": "编写查询,选择属性和参数",
|
||||
"newObject.graphqlQueryDisabled": "当前数据库不支持 GraphQL 查询",
|
||||
"newObject.perspectiveDescription": "从多个数据库中联接复杂数据",
|
||||
"newObject.queryDesignerDescription": "可视化设计SQL查询",
|
||||
"newObject.queryDesignerDisabled": "当前数据库不支持查询设计器",
|
||||
@@ -1158,6 +1195,7 @@
|
||||
"privateCloudWidget.addNewConnectionOrFile": "添加新连接或文件",
|
||||
"privateCloudWidget.addNewFolder": "添加新文件夹",
|
||||
"privateCloudWidget.administrateAccess": "管理访问权限",
|
||||
"privateCloudWidget.cloudUnavailable": "DbGate 云暂时不可用",
|
||||
"privateCloudWidget.createConnection": "在 DbGate 云上创建连接",
|
||||
"privateCloudWidget.createSharedFolder": "创建共享文件夹",
|
||||
"privateCloudWidget.deleteFolder": "删除文件夹",
|
||||
@@ -1170,6 +1208,7 @@
|
||||
"privateCloudWidget.renameFolder": "重命名文件夹",
|
||||
"privateCloudWidget.searchPlaceholder": "搜索云连接和文件",
|
||||
"privateCloudWidget.yourInviteLink": "您的邀请链接(格式为 dbgate://folder/xxx)",
|
||||
"publicCloudWidget.cloudUnavailable": "DbGate 云暂时不可用",
|
||||
"publicCloudWidget.noFilesFound": "未找到适合您配置的文件",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "仅列出与您的连接、平台和 DbGate 版本相关的文件。请先定义连接。",
|
||||
"publicCloudWidget.publicKnowledgeBase": "公共知识库",
|
||||
@@ -1191,10 +1230,13 @@
|
||||
"query.aggregate": "聚合",
|
||||
"query.alias": "别名",
|
||||
"query.columnExpression": "列/表达式",
|
||||
"query.defaultIsolationLevel": "默认",
|
||||
"query.defaultIsolationLevelNamed": "默认({level})",
|
||||
"query.download": "下载",
|
||||
"query.filter": "筛选",
|
||||
"query.groupBy": "分组依据",
|
||||
"query.groupFilter": "分组筛选",
|
||||
"query.isolationLevel": "隔离级别",
|
||||
"query.limitRows": "限制 {queryRowsLimit} 行",
|
||||
"query.named": ":variable",
|
||||
"query.noParameters": "(无参数)",
|
||||
@@ -1287,6 +1329,7 @@
|
||||
"settings.behaviour.openDetailOnArrows": "在键盘导航时打开详情",
|
||||
"settings.behaviour.singleClickPreview": "当您在\"表、视图、函数\"视图中单击或选择文件时,它将以预览模式显示并重用现有标签页(预览标签页)。如果您快速浏览表并不希望每个访问的表都有自己的标签页,这很有用。当您开始编辑表或使用双击从\"表\"视图打开表时,将为该表专门分配一个新标签页。",
|
||||
"settings.behaviour.useTabPreviewMode": "使用标签页预览模式",
|
||||
"settings.checkAll": "全选 / 取消全选",
|
||||
"settings.confirmations": "确认",
|
||||
"settings.confirmations.skipConfirm.collectionDataSave": "保存集合数据时跳过确认(NoSQL)",
|
||||
"settings.confirmations.skipConfirm.tableDataSave": "保存表数据时跳过确认(SQL)",
|
||||
@@ -1305,6 +1348,7 @@
|
||||
"settings.dataGrid.coloringMode.36": "每第3和第6行",
|
||||
"settings.dataGrid.coloringMode.none": "无",
|
||||
"settings.dataGrid.defaultAutoRefreshInterval": "默认网格自动刷新间隔(秒)",
|
||||
"settings.dataGrid.disableCellDataViewAutoOpen": "禁用自动打开单元格数据视图",
|
||||
"settings.dataGrid.pageSize": "页面大小(增量加载的行数,必须在5到50000之间)",
|
||||
"settings.dataGrid.showAllColumnsWhenSearch": "搜索时显示所有列",
|
||||
"settings.dataGrid.showHintColumns": "显示外键提示",
|
||||
@@ -1331,6 +1375,7 @@
|
||||
"settings.defaultActions.tableClick": "表点击",
|
||||
"settings.defaultActions.useLastUsedAction": "使用上次使用的操作",
|
||||
"settings.defaultActions.viewClick": "视图点击",
|
||||
"settings.drivers": "驱动",
|
||||
"settings.editor.keybinds": "编辑器快捷键",
|
||||
"settings.editor.wordWrap": "启用自动换行",
|
||||
"settings.externalTools": "外部工具",
|
||||
@@ -1355,6 +1400,9 @@
|
||||
"settings.other.licenseKey.invalid": "许可证密钥无效",
|
||||
"settings.other.licenseKey.valid": "许可证密钥有效",
|
||||
"settings.other.licenseKey.validTo": "许可证有效期至:",
|
||||
"settings.other.toolBarPosition": "工具栏位置",
|
||||
"settings.other.toolBarPosition.bottom": "底部",
|
||||
"settings.other.toolBarPosition.top": "顶部",
|
||||
"settings.session": "查询会话",
|
||||
"settings.session.autoClose": "在无活动期间后自动关闭查询会话",
|
||||
"settings.session.autoCloseTimeout": "关闭无活动查询会话的间隔(分钟)",
|
||||
@@ -1393,6 +1441,7 @@
|
||||
"sqlGenerator.omitNulls": "忽略 NULL 值",
|
||||
"sqlGenerator.searchTablesOrObjects": "搜索表或对象",
|
||||
"sqlGenerator.skipAutoincrementColumn": "跳过自增列",
|
||||
"sqlGenerator.skipComputedColumns": "跳过计算列",
|
||||
"sqlGenerator.sqlGenerator": "SQL 生成器",
|
||||
"sqlGenerator.sqlTruncated": "SQL 已被截断,超过文件大小限制",
|
||||
"sqlGenerator.tables": "表",
|
||||
@@ -1467,6 +1516,7 @@
|
||||
"tableEditor.defaultValue": "默认值",
|
||||
"tableEditor.dependencies": "依赖项",
|
||||
"tableEditor.foreignKeys": "外键 ({foreignKeyCount})",
|
||||
"tableEditor.indexType": "类型",
|
||||
"tableEditor.indexes": "索引 ({indexCount})",
|
||||
"tableEditor.isPersisted": "是否持久化",
|
||||
"tableEditor.isSparse": "是否稀疏",
|
||||
@@ -1485,7 +1535,6 @@
|
||||
"tableEditor.remove": "删除",
|
||||
"tableEditor.tablename": "表名称",
|
||||
"tableEditor.tableproperties": "表属性",
|
||||
"tableEditor.unique": "唯一",
|
||||
"tableEditor.uniqueConstraints": "唯一约束 ({constraintCount})",
|
||||
"tableEditor.yes": "是",
|
||||
"tableStructure.alter": "修改表",
|
||||
@@ -1521,6 +1570,7 @@
|
||||
"widget.collectionsContainers": "集合/容器",
|
||||
"widget.databaseContent": "数据库内容",
|
||||
"widget.databases": "数据库",
|
||||
"widget.endpoints": "端点",
|
||||
"widget.keys": "键",
|
||||
"widget.pinned": "已固定",
|
||||
"widget.tablesViewsFunctions": "表、视图、函数",
|
||||
@@ -1535,4 +1585,4 @@
|
||||
"widgets.openedTabs": "已打开的标签页",
|
||||
"widgets.premiumPromo": "高级版推广",
|
||||
"widgets.queryHistoryAndClosedTabs": "查询历史和已关闭标签页"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
@@ -52,7 +51,7 @@ jobs:
|
||||
- name: yarn install
|
||||
run: |
|
||||
yarn install
|
||||
|
||||
|
||||
- name: setCurrentVersion
|
||||
run: |
|
||||
yarn setCurrentVersion
|
||||
@@ -79,7 +78,12 @@ jobs:
|
||||
working-directory: packages/sqltree
|
||||
run: |
|
||||
npm publish --tag "$NPM_TAG"
|
||||
|
||||
|
||||
- name: Publish rest
|
||||
working-directory: packages/rest
|
||||
run: |
|
||||
npm publish --tag "$NPM_TAG"
|
||||
|
||||
- name: Publish api
|
||||
working-directory: packages/api
|
||||
run: |
|
||||
|
||||
@@ -101,12 +101,12 @@ jobs:
|
||||
--health-retries 5
|
||||
env:
|
||||
POSTGRES_PASSWORD: Pwd2020Db
|
||||
ports:
|
||||
ports:
|
||||
- 16000:5432
|
||||
|
||||
mysql-cypress:
|
||||
image: mysql:8.0.18
|
||||
ports:
|
||||
ports:
|
||||
- 16004:3306
|
||||
env:
|
||||
MYSQL_ROOT_PASSWORD: Pwd2020Db
|
||||
@@ -118,7 +118,7 @@ jobs:
|
||||
|
||||
mysql-ssh-keyfile:
|
||||
image: ghcr.io/dbgate/mysql-ssh-keyfile:latest
|
||||
ports:
|
||||
ports:
|
||||
- '16008:22'
|
||||
|
||||
dex:
|
||||
@@ -139,6 +139,11 @@ jobs:
|
||||
ports:
|
||||
- 16011:6379
|
||||
|
||||
dynamodb:
|
||||
image: amazon/dynamodb-local
|
||||
ports:
|
||||
- 16015:8000
|
||||
|
||||
mssql:
|
||||
image: mcr.microsoft.com/mssql/server
|
||||
ports:
|
||||
|
||||
@@ -7,7 +7,7 @@ checkout-and-merge-pro:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: c33e71a6ddc30d8ce59cf0351e04e08f6be272a3
|
||||
ref: 5baa88d0ad253537298e911868579bae0835888d
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -7247,6 +7247,11 @@ doctrine@^3.0.0:
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
|
||||
dom-to-image@^2.6.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-to-image/-/dom-to-image-2.6.0.tgz#8a503608088c87b1c22f9034ae032e1898955867"
|
||||
integrity sha512-Dt0QdaHmLpjURjU7Tnu3AgYSF2LuOmksSGsUcE6ItvJoCWTBEmiMXcqBdNSAm9+QbbwD7JMoVsuuKX6ZVQv1qA==
|
||||
|
||||
dotenv@^16.0.0:
|
||||
version "16.4.5"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f"
|
||||
|
||||
Reference in New Issue
Block a user