mirror of
https://github.com/Fabio286/antares.git
synced 2025-06-05 21:59:22 +02:00
Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
014257147e | |||
970de4962b | |||
b5a828309f | |||
5b21d17f3a | |||
2c6e35288f | |||
bcadac6e95 | |||
|
18a93ef1aa | ||
6c62052b47 | |||
9d5ebefdce | |||
34ebc6b72d | |||
288ff4c1a1 | |||
a176174b8d | |||
0f69d1dbb7 | |||
0386bbac50 | |||
b0576acdf6 | |||
9a190854fe |
25
CHANGELOG.md
25
CHANGELOG.md
@@ -2,6 +2,31 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [0.0.17](https://github.com/Fabio286/antares/compare/v0.0.16...v0.0.17) (2021-02-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Added french language ([18a93ef](https://github.com/Fabio286/antares/commit/18a93ef1aae530e69c9062bbeb08a3beec206eda))
|
||||
* fake table data generator ([a176174](https://github.com/Fabio286/antares/commit/a176174b8d7dc232920f4cd7c5e3f8e4c58d51a0))
|
||||
* min and max option for random floats and numbers ([6c62052](https://github.com/Fabio286/antares/commit/6c62052b4764731c774fef90784342447b36deb7))
|
||||
* support to fake data locales ([970de49](https://github.com/Fabio286/antares/commit/970de4962b3bffec271bfa6d4747e6fb9d408ba6))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **UI:** file uploader in table filler ([b5a8283](https://github.com/Fabio286/antares/commit/b5a828309f067636eae2120032f07e01233706e2))
|
||||
* **UI:** no foreign key select editing query results ([5b21d17](https://github.com/Fabio286/antares/commit/5b21d17f3a8f2482c3aafe85f26c34cd3c0a1fcf))
|
||||
* cut faker text based on field length ([288ff4c](https://github.com/Fabio286/antares/commit/288ff4c1a1c77f4b8b86b24649d805836366fdd3))
|
||||
* wrong date or time detection in field default ([9d5ebef](https://github.com/Fabio286/antares/commit/9d5ebefdced999af595f3d8dc2fac2b18fa8258b))
|
||||
* **UI:** better text on ssl file selectors ([9a19085](https://github.com/Fabio286/antares/commit/9a190854fe3c73ed4e7f89545ff259e15ee9f947))
|
||||
* **UI:** wrong length for char fields on table header ([0f69d1d](https://github.com/Fabio286/antares/commit/0f69d1dbb7958e45059b6b738c845abea1ad3225))
|
||||
|
||||
|
||||
### Improvements
|
||||
|
||||
* **core:** bulk inserts support ([b0576ac](https://github.com/Fabio286/antares/commit/b0576acdf65d41c1c8e0b0bca6cf6522dcb372be))
|
||||
|
||||
### [0.0.16](https://github.com/Fabio286/antares/compare/v0.0.15...v0.0.16) (2021-02-06)
|
||||
|
||||
|
||||
|
14
README.md
14
README.md
@@ -33,6 +33,7 @@ An application created with minimalism and semplicity in mind, with features in
|
||||
- Database management (add/edit/delete).
|
||||
- Full tables management, including indexes and foreign keys.
|
||||
- Views, triggers, stored routines, functions and schedulers management (add/edit/delete).
|
||||
- Fake table data filler.
|
||||
- Run queries on multiple tabs.
|
||||
- Query suggestions and auto complete.
|
||||
- Native dark theme.
|
||||
@@ -53,10 +54,20 @@ This is a roadmap with major features will come in near future.
|
||||
- More context menu shortcuts.
|
||||
- More keyboard shortcuts.
|
||||
- Query logs console.
|
||||
- Fake data filler.
|
||||
- Import/export and migration.
|
||||
- Light theme.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### **Linux**
|
||||
|
||||
With KDE may need necessary installation of the additional `gnome-keyring` package.
|
||||
Depending on your distribution, you will need to run the following command:
|
||||
|
||||
- Debian/Ubuntu: `sudo apt-get install gnome-keyring`
|
||||
- Red Hat-based: `sudo yum install gnome-keyring`
|
||||
- Arch Linux: `sudo pacman -S gnome-keyring`
|
||||
|
||||
## Currently supported
|
||||
|
||||
### Databases
|
||||
@@ -87,6 +98,7 @@ This is a roadmap with major features will come in near future.
|
||||
**Italian Translation** (46%) / [Giuseppe Gigliotti](https://github.com/ReverbOD) [[#20](https://github.com/Fabio286/antares/pull/20)]
|
||||
**Arabic Translation** (45%) / [Mohd-PH](https://github.com/Mohd-PH) [[#29](https://github.com/Fabio286/antares/pull/29)]
|
||||
**Spanish Translation** (46%) / [hongkfui](https://github.com/hongkfui) [[#32](https://github.com/Fabio286/antares/pull/32)]
|
||||
**French Translation** (100%) / [MrAnyx](https://github.com/MrAnyx) [[#44](https://github.com/Fabio286/antares/pull/44)]
|
||||
|
||||
## Reviews
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "antares",
|
||||
"productName": "Antares",
|
||||
"version": "0.0.16",
|
||||
"version": "0.0.17",
|
||||
"description": "A cross-platform easy to use SQL client.",
|
||||
"license": "MIT",
|
||||
"repository": "https://github.com/Fabio286/antares.git",
|
||||
@@ -56,6 +56,7 @@
|
||||
"electron-log": "^4.3.0",
|
||||
"electron-store": "^7.0.0",
|
||||
"electron-updater": "^4.3.5",
|
||||
"faker": "^5.3.1",
|
||||
"keytar": "^7.3.0",
|
||||
"lodash": "^4.17.20",
|
||||
"moment": "^2.29.1",
|
||||
|
217
src/common/FakerMethods.js
Normal file
217
src/common/FakerMethods.js
Normal file
@@ -0,0 +1,217 @@
|
||||
export default class {
|
||||
static get _methods () {
|
||||
return [
|
||||
{ name: 'zipCode', group: 'address', types: ['string'] },
|
||||
{ name: 'zipCodeByState', group: 'address', types: ['string'] },
|
||||
{ name: 'city', group: 'address', types: ['string'] },
|
||||
{ name: 'cityPrefix', group: 'address', types: ['string'] },
|
||||
{ name: 'citySuffix', group: 'address', types: ['string'] },
|
||||
{ name: 'streetName', group: 'address', types: ['string'] },
|
||||
{ name: 'streetAddress', group: 'address', types: ['string'] },
|
||||
{ name: 'streetSuffix', group: 'address', types: ['string'] },
|
||||
{ name: 'streetPrefix', group: 'address', types: ['string'] },
|
||||
{ name: 'secondaryAddress', group: 'address', types: ['string'] },
|
||||
{ name: 'county', group: 'address', types: ['string'] },
|
||||
{ name: 'country', group: 'address', types: ['string'] },
|
||||
{ name: 'countryCode', group: 'address', types: ['string'] },
|
||||
{ name: 'state', group: 'address', types: ['string'] },
|
||||
{ name: 'stateAbbr', group: 'address', types: ['string'] },
|
||||
{ name: 'latitude', group: 'address', types: ['string'] },
|
||||
{ name: 'longitude', group: 'address', types: ['string'] },
|
||||
{ name: 'direction', group: 'address', types: ['string'] },
|
||||
{ name: 'cardinalDirection', group: 'address', types: ['string'] },
|
||||
{ name: 'ordinalDirection', group: 'address', types: ['string'] },
|
||||
// { name: 'nearbyGPSCoordinate', group: 'address', types: ['string'] },
|
||||
{ name: 'timeZone', group: 'address', types: ['string'] },
|
||||
|
||||
{ name: 'color', group: 'commerce', types: ['string'] },
|
||||
{ name: 'department', group: 'commerce', types: ['string'] },
|
||||
{ name: 'productName', group: 'commerce', types: ['string'] },
|
||||
{ name: 'price', group: 'commerce', types: ['string', 'float'] },
|
||||
{ name: 'productAdjective', group: 'commerce', types: ['string'] },
|
||||
{ name: 'productMaterial', group: 'commerce', types: ['string'] },
|
||||
{ name: 'product', group: 'commerce', types: ['string'] },
|
||||
{ name: 'productDescription', group: 'commerce', types: ['string'] },
|
||||
|
||||
{ name: 'suffixes', group: 'company', types: ['string'] },
|
||||
{ name: 'companyName', group: 'company', types: ['string'] },
|
||||
{ name: 'companySuffix', group: 'company', types: ['string'] },
|
||||
{ name: 'catchPhrase', group: 'company', types: ['string'] },
|
||||
{ name: 'bs', group: 'company', types: ['string'] },
|
||||
{ name: 'catchPhraseAdjective', group: 'company', types: ['string'] },
|
||||
{ name: 'catchPhraseDescriptor', group: 'company', types: ['string'] },
|
||||
{ name: 'catchPhraseNoun', group: 'company', types: ['string'] },
|
||||
{ name: 'bsAdjective', group: 'company', types: ['string'] },
|
||||
{ name: 'bsBuzz', group: 'company', types: ['string'] },
|
||||
{ name: 'bsNoun', group: 'company', types: ['string'] },
|
||||
|
||||
{ name: 'column', group: 'database', types: ['string'] },
|
||||
{ name: 'type', group: 'database', types: ['string'] },
|
||||
{ name: 'collation', group: 'database', types: ['string'] },
|
||||
{ name: 'engine', group: 'database', types: ['string'] },
|
||||
|
||||
{ name: 'past', group: 'date', types: ['string', 'datetime'] },
|
||||
{ name: 'future', group: 'date', types: ['string', 'datetime'] },
|
||||
// { name: 'between', group: 'date', types: ['string'] },
|
||||
{ name: 'recent', group: 'date', types: ['string', 'datetime'] },
|
||||
{ name: 'soon', group: 'date', types: ['string', 'datetime'] },
|
||||
{ name: 'month', group: 'date', types: ['string'] },
|
||||
{ name: 'weekday', group: 'date', types: ['string'] },
|
||||
|
||||
{ name: 'account', group: 'finance', types: ['string', 'number'] },
|
||||
{ name: 'accountName', group: 'finance', types: ['string'] },
|
||||
{ name: 'routingNumber', group: 'finance', types: ['string', 'number'] },
|
||||
{ name: 'mask', group: 'finance', types: ['string', 'number'] },
|
||||
{ name: 'amount', group: 'finance', types: ['string', 'float'] },
|
||||
{ name: 'transactionType', group: 'finance', types: ['string'] },
|
||||
{ name: 'currencyCode', group: 'finance', types: ['string'] },
|
||||
{ name: 'currencyName', group: 'finance', types: ['string'] },
|
||||
{ name: 'currencySymbol', group: 'finance', types: ['string'] },
|
||||
{ name: 'bitcoinAddress', group: 'finance', types: ['string'] },
|
||||
{ name: 'litecoinAddress', group: 'finance', types: ['string'] },
|
||||
{ name: 'creditCardNumber', group: 'finance', types: ['string'] },
|
||||
{ name: 'creditCardCVV', group: 'finance', types: ['string', 'number'] },
|
||||
{ name: 'ethereumAddress', group: 'finance', types: ['string'] },
|
||||
{ name: 'iban', group: 'finance', types: ['string'] },
|
||||
{ name: 'bic', group: 'finance', types: ['string'] },
|
||||
{ name: 'transactionDescription', group: 'finance', types: ['string'] },
|
||||
|
||||
{ name: 'branch', group: 'git', types: ['string'] },
|
||||
{ name: 'commitEntry', group: 'git', types: ['string'] },
|
||||
{ name: 'commitMessage', group: 'git', types: ['string'] },
|
||||
{ name: 'commitSha', group: 'git', types: ['string'] },
|
||||
{ name: 'shortSha', group: 'git', types: ['string'] },
|
||||
|
||||
{ name: 'abbreviation', group: 'hacker', types: ['string'] },
|
||||
{ name: 'adjective', group: 'hacker', types: ['string'] },
|
||||
{ name: 'noun', group: 'hacker', types: ['string'] },
|
||||
{ name: 'verb', group: 'hacker', types: ['string'] },
|
||||
{ name: 'ingverb', group: 'hacker', types: ['string'] },
|
||||
{ name: 'phrase', group: 'hacker', types: ['string'] },
|
||||
|
||||
// { name: 'avatar', group: 'internet', types: ['string'] },
|
||||
{ name: 'email', group: 'internet', types: ['string'] },
|
||||
{ name: 'exampleEmail', group: 'internet', types: ['string'] },
|
||||
{ name: 'userName', group: 'internet', types: ['string'] },
|
||||
{ name: 'protocol', group: 'internet', types: ['string'] },
|
||||
{ name: 'url', group: 'internet', types: ['string'] },
|
||||
{ name: 'domainName', group: 'internet', types: ['string'] },
|
||||
{ name: 'domainSuffix', group: 'internet', types: ['string'] },
|
||||
{ name: 'domainWord', group: 'internet', types: ['string'] },
|
||||
{ name: 'ip', group: 'internet', types: ['string'] },
|
||||
{ name: 'ipv6', group: 'internet', types: ['string'] },
|
||||
{ name: 'userAgent', group: 'internet', types: ['string'] },
|
||||
{ name: 'color', group: 'internet', types: ['string'] },
|
||||
{ name: 'mac', group: 'internet', types: ['string'] },
|
||||
{ name: 'password', group: 'internet', types: ['string'] },
|
||||
|
||||
{ name: 'word', group: 'lorem', types: ['string'] },
|
||||
{ name: 'words', group: 'lorem', types: ['string'] },
|
||||
{ name: 'sentence', group: 'lorem', types: ['string'] },
|
||||
{ name: 'slug', group: 'lorem', types: ['string'] },
|
||||
{ name: 'sentences', group: 'lorem', types: ['string'] },
|
||||
{ name: 'paragraph', group: 'lorem', types: ['string'] },
|
||||
{ name: 'paragraphs', group: 'lorem', types: ['string'] },
|
||||
{ name: 'text', group: 'lorem', types: ['string'] },
|
||||
{ name: 'lines', group: 'lorem', types: ['string'] },
|
||||
|
||||
{ name: 'genre', group: 'music', types: ['string'] },
|
||||
|
||||
{ name: 'firstName', group: 'name', types: ['string'] },
|
||||
{ name: 'lastName', group: 'name', types: ['string'] },
|
||||
{ name: 'middleName', group: 'name', types: ['string'] },
|
||||
{ name: 'findName', group: 'name', types: ['string'] },
|
||||
{ name: 'jobTitle', group: 'name', types: ['string'] },
|
||||
{ name: 'gender', group: 'name', types: ['string'] },
|
||||
{ name: 'prefix', group: 'name', types: ['string'] },
|
||||
{ name: 'suffix', group: 'name', types: ['string'] },
|
||||
{ name: 'title', group: 'name', types: ['string'] },
|
||||
{ name: 'jobDescriptor', group: 'name', types: ['string'] },
|
||||
{ name: 'jobArea', group: 'name', types: ['string'] },
|
||||
{ name: 'jobType', group: 'name', types: ['string'] },
|
||||
|
||||
{ name: 'phoneNumber', group: 'phone', types: ['string'] },
|
||||
{ name: 'phoneNumberFormat', group: 'phone', types: ['string'] },
|
||||
{ name: 'phoneFormats', group: 'phone', types: ['string'] },
|
||||
|
||||
{ name: 'number', group: 'random', types: ['string', 'number'], params: ['min', 'max'] },
|
||||
{ name: 'float', group: 'random', types: ['string', 'float'], params: ['min', 'max'] },
|
||||
{ name: 'arrayElement', group: 'random', types: ['string'] },
|
||||
{ name: 'arrayElements', group: 'random', types: ['string'] },
|
||||
{ name: 'objectElement', group: 'random', types: ['string'] },
|
||||
{ name: 'uuid', group: 'random', types: ['string'] },
|
||||
{ name: 'boolean', group: 'random', types: ['string'] },
|
||||
{ name: 'word', group: 'random', types: ['string'] },
|
||||
{ name: 'words', group: 'random', types: ['string'] },
|
||||
// { name: 'image', group: 'random', types: ['string'] },
|
||||
{ name: 'locale', group: 'random', types: ['string'] },
|
||||
{ name: 'alpha', group: 'random', types: ['string'] },
|
||||
{ name: 'alphaNumeric', group: 'random', types: ['string'] },
|
||||
{ name: 'hexaDecimal', group: 'random', types: ['string'] },
|
||||
|
||||
{ name: 'fileName', group: 'system', types: ['string'] },
|
||||
{ name: 'commonFileName', group: 'system', types: ['string'] },
|
||||
{ name: 'mimeType', group: 'system', types: ['string'] },
|
||||
{ name: 'commonFileType', group: 'system', types: ['string'] },
|
||||
{ name: 'commonFileExt', group: 'system', types: ['string'] },
|
||||
{ name: 'fileType', group: 'system', types: ['string'] },
|
||||
{ name: 'fileExt', group: 'system', types: ['string'] },
|
||||
{ name: 'directoryPath', group: 'system', types: ['string'] },
|
||||
{ name: 'filePath', group: 'system', types: ['string'] },
|
||||
{ name: 'semver', group: 'system', types: ['string'] },
|
||||
|
||||
{ name: 'recent', group: 'time', types: ['string', 'time'] },
|
||||
|
||||
{ name: 'vehicle', group: 'vehicle', types: ['string'] },
|
||||
{ name: 'manufacturer', group: 'vehicle', types: ['string'] },
|
||||
{ name: 'model', group: 'vehicle', types: ['string'] },
|
||||
{ name: 'type', group: 'vehicle', types: ['string'] },
|
||||
{ name: 'fuel', group: 'vehicle', types: ['string'] },
|
||||
{ name: 'vin', group: 'vehicle', types: ['string'] },
|
||||
{ name: 'color', group: 'vehicle', types: ['string'] }
|
||||
];
|
||||
}
|
||||
|
||||
static getGroups () {
|
||||
const groupsObj = this._methods.reduce((acc, curr) => {
|
||||
if (curr.group in acc)
|
||||
curr.types.forEach(type => acc[curr.group].add(type));
|
||||
else
|
||||
acc[curr.group] = new Set(curr.types);
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const groupsArr = [];
|
||||
|
||||
for (const key in groupsObj)
|
||||
groupsArr.push({ name: key, types: [...groupsObj[key]] });
|
||||
|
||||
return groupsArr.sort((a, b) => {
|
||||
if (a.name < b.name)
|
||||
return -1;
|
||||
|
||||
if (b.name > a.name)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}); ;
|
||||
}
|
||||
|
||||
static getGroupsByType (type) {
|
||||
if (!type) return [];
|
||||
return this.getGroups().filter(group => group.types.includes(type));
|
||||
}
|
||||
|
||||
static getMethods ({ type, group }) {
|
||||
return this._methods.filter(method => method.group === group && method.types.includes(type)).sort((a, b) => {
|
||||
if (a.name < b.name)
|
||||
return -1;
|
||||
|
||||
if (b.name > a.name)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
}
|
@@ -1,7 +1,8 @@
|
||||
export const TEXT = ['CHAR', 'VARCHAR'];
|
||||
export const LONG_TEXT = ['TEXT', 'MEDIUMTEXT', 'LONGTEXT'];
|
||||
|
||||
export const NUMBER = ['INT', 'TINYINT', 'SMALLINT', 'MEDIUMINT', 'BIGINT', 'FLOAT', 'DOUBLE', 'DECIMAL', 'BOOL'];
|
||||
export const NUMBER = ['INT', 'TINYINT', 'SMALLINT', 'MEDIUMINT', 'BIGINT', 'DECIMAL', 'BOOL'];
|
||||
export const FLOAT = ['FLOAT', 'DOUBLE'];
|
||||
|
||||
export const DATE = ['DATE'];
|
||||
export const TIME = ['TIME'];
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import { ipcMain } from 'electron';
|
||||
import faker from 'faker';
|
||||
import moment from 'moment';
|
||||
import { sqlEscaper } from 'common/libs/sqlEscaper';
|
||||
import { TEXT, LONG_TEXT, NUMBER, BLOB, BIT } from 'common/fieldTypes';
|
||||
import { TEXT, LONG_TEXT, NUMBER, FLOAT, BLOB, BIT, DATE, DATETIME } from 'common/fieldTypes';
|
||||
import fs from 'fs';
|
||||
|
||||
export default (connections) => {
|
||||
@@ -62,7 +64,7 @@ export default (connections) => {
|
||||
let reload = false;
|
||||
const id = typeof params.id === 'number' ? params.id : `"${params.id}"`;
|
||||
|
||||
if (NUMBER.includes(params.type))
|
||||
if ([...NUMBER, ...FLOAT].includes(params.type))
|
||||
escapedParam = params.content;
|
||||
else if ([...TEXT, ...LONG_TEXT].includes(params.type))
|
||||
escapedParam = `"${sqlEscaper(params.content)}"`;
|
||||
@@ -171,7 +173,7 @@ export default (connections) => {
|
||||
|
||||
if (params.row[key] === null)
|
||||
escapedParam = 'NULL';
|
||||
else if (NUMBER.includes(type))
|
||||
else if ([...NUMBER, ...FLOAT].includes(type))
|
||||
escapedParam = params.row[key];
|
||||
else if ([...TEXT, ...LONG_TEXT].includes(type))
|
||||
escapedParam = `"${sqlEscaper(params.row[key])}"`;
|
||||
@@ -189,13 +191,89 @@ export default (connections) => {
|
||||
insertObj[key] = escapedParam;
|
||||
}
|
||||
|
||||
for (let i = 0; i < params.repeat; i++) {
|
||||
const rows = new Array(+params.repeat).fill(insertObj);
|
||||
|
||||
await connections[params.uid]
|
||||
.schema(params.schema)
|
||||
.into(params.table)
|
||||
.insert(insertObj)
|
||||
.insert(rows)
|
||||
.run();
|
||||
|
||||
return { status: 'success' };
|
||||
}
|
||||
catch (err) {
|
||||
return { status: 'error', response: err.toString() };
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('insert-table-fake-rows', async (event, params) => {
|
||||
try {
|
||||
const rows = [];
|
||||
|
||||
for (let i = 0; i < +params.repeat; i++) {
|
||||
const insertObj = {};
|
||||
|
||||
for (const key in params.row) {
|
||||
const type = params.fields[key];
|
||||
let escapedParam;
|
||||
|
||||
if (!('group' in params.row[key]) || params.row[key].group === 'manual') { // Manual value
|
||||
if (params.row[key].value === null || params.row[key].value === undefined)
|
||||
escapedParam = 'NULL';
|
||||
else if ([...NUMBER, ...FLOAT].includes(type))
|
||||
escapedParam = params.row[key].value;
|
||||
else if ([...TEXT, ...LONG_TEXT].includes(type))
|
||||
escapedParam = `"${sqlEscaper(params.row[key].value)}"`;
|
||||
else if (BLOB.includes(type)) {
|
||||
if (params.row[key].value) {
|
||||
const fileBlob = fs.readFileSync(params.row[key].value);
|
||||
escapedParam = `0x${fileBlob.toString('hex')}`;
|
||||
}
|
||||
else
|
||||
escapedParam = '""';
|
||||
}
|
||||
else
|
||||
escapedParam = `"${sqlEscaper(params.row[key].value)}"`;
|
||||
|
||||
insertObj[key] = escapedParam;
|
||||
}
|
||||
else { // Faker value
|
||||
const parsedParams = {};
|
||||
let fakeValue;
|
||||
|
||||
if (params.locale)
|
||||
faker.locale = params.locale;
|
||||
|
||||
if (Object.keys(params.row[key].params).length) {
|
||||
Object.keys(params.row[key].params).forEach(param => {
|
||||
if (!isNaN(params.row[key].params[param]))
|
||||
parsedParams[param] = +params.row[key].params[param];
|
||||
});
|
||||
fakeValue = faker[params.row[key].group][params.row[key].method](parsedParams);
|
||||
}
|
||||
else
|
||||
fakeValue = faker[params.row[key].group][params.row[key].method]();
|
||||
|
||||
if (typeof fakeValue === 'string') {
|
||||
if (params.row[key].length)
|
||||
fakeValue = fakeValue.substr(0, params.row[key].length);
|
||||
fakeValue = `"${sqlEscaper(fakeValue)}"`;
|
||||
}
|
||||
else if ([...DATE, ...DATETIME].includes(type))
|
||||
fakeValue = `"${moment(fakeValue).format('YYYY-MM-DD HH:mm:ss.SSSSSS')}"`;
|
||||
|
||||
insertObj[key] = fakeValue;
|
||||
}
|
||||
}
|
||||
|
||||
rows.push(insertObj);
|
||||
}
|
||||
|
||||
await connections[params.uid]
|
||||
.schema(params.schema)
|
||||
.into(params.table)
|
||||
.insert(rows)
|
||||
.run();
|
||||
|
||||
return { status: 'success' };
|
||||
}
|
||||
|
@@ -28,7 +28,7 @@ export class AntaresCore {
|
||||
limit: [],
|
||||
join: [],
|
||||
update: [],
|
||||
insert: {},
|
||||
insert: [],
|
||||
delete: false
|
||||
};
|
||||
this._query = Object.assign({}, this._queryDefaults);
|
||||
@@ -120,12 +120,12 @@ export class AntaresCore {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} obj field: value
|
||||
* @param {Array} arr Array of row objects
|
||||
* @returns
|
||||
* @memberof AntaresCore
|
||||
*/
|
||||
insert (obj) {
|
||||
this._query.insert = { ...this._query.insert, ...obj };
|
||||
insert (arr) {
|
||||
this._query.insert = [...this._query.insert, ...arr];
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@@ -1157,18 +1157,11 @@ export class MySQLClient extends AntaresCore {
|
||||
// INSERT
|
||||
let insertRaw = '';
|
||||
|
||||
if (Object.keys(this._query.insert).length) {
|
||||
const fieldsList = [];
|
||||
const valueList = [];
|
||||
const fields = this._query.insert;
|
||||
if (this._query.insert.length) {
|
||||
const fieldsList = Object.keys(this._query.insert[0]);
|
||||
const rowsList = this._query.insert.map(el => `(${Object.values(el).join(', ')})`);
|
||||
|
||||
for (const key in fields) {
|
||||
if (fields[key] === null) continue;
|
||||
fieldsList.push(key);
|
||||
valueList.push(fields[key]);
|
||||
}
|
||||
|
||||
insertRaw = `(${fieldsList.join(', ')}) VALUES (${valueList.join(', ')}) `;
|
||||
insertRaw = `(${fieldsList.join(', ')}) VALUES ${rowsList.join(', ')} `;
|
||||
}
|
||||
|
||||
// GROUP BY
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<label :for="`id_${id}`" class="file-uploader">
|
||||
<span class="file-uploader-message">
|
||||
<i class="mdi mdi-upload mr-1" />{{ message }}
|
||||
<i class="mdi mdi-folder-open mr-1" />{{ message }}
|
||||
</span>
|
||||
<span class="text-ellipsis file-uploader-value">
|
||||
{{ value | lastPart }}
|
||||
@@ -37,7 +37,7 @@ export default {
|
||||
},
|
||||
props: {
|
||||
message: {
|
||||
default: 'Upload',
|
||||
default: 'Browse',
|
||||
type: String
|
||||
},
|
||||
value: {
|
||||
@@ -72,6 +72,7 @@ export default {
|
||||
background-color: $bg-color-gray;
|
||||
transition: background 0.2s, border 0.2s, box-shadow 0.2s, color 0.2s;
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
|
||||
> span {
|
||||
padding: 0.25rem 0.4rem;
|
||||
@@ -97,7 +98,7 @@ export default {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 25%;
|
||||
top: calc(50% - 8px);
|
||||
}
|
||||
}
|
||||
|
||||
|
233
src/renderer/components/FakerSelect.vue
Normal file
233
src/renderer/components/FakerSelect.vue
Normal file
@@ -0,0 +1,233 @@
|
||||
<template>
|
||||
<fieldset class="input-group mb-0">
|
||||
<select
|
||||
v-model="selectedGroup"
|
||||
class="form-select"
|
||||
:disabled="!isChecked"
|
||||
style="flex-grow: 0;"
|
||||
@change="onChange"
|
||||
>
|
||||
<option value="manual">
|
||||
{{ $t('message.manualValue') }}
|
||||
</option>
|
||||
<option
|
||||
v-for="group in fakerGroups"
|
||||
:key="group.name"
|
||||
:value="group.name"
|
||||
>
|
||||
{{ $t(`faker.${group.name}`) }}
|
||||
</option>
|
||||
</select>
|
||||
<select
|
||||
v-if="selectedGroup !== 'manual'"
|
||||
v-model="selectedMethod"
|
||||
class="form-select"
|
||||
:disabled="!isChecked"
|
||||
@change="onChange"
|
||||
>
|
||||
<option
|
||||
v-for="method in fakerMethods"
|
||||
:key="method.name"
|
||||
:value="method.name"
|
||||
>
|
||||
{{ $t(`faker.${method.name}`) }}
|
||||
</option>
|
||||
</select>
|
||||
<ForeignKeySelect
|
||||
v-else-if="foreignKeys.includes(field.name)"
|
||||
ref="formInput"
|
||||
class="form-select"
|
||||
:value.sync="selectedValue"
|
||||
:key-usage="getKeyUsage(field.name)"
|
||||
:disabled="!isChecked"
|
||||
/>
|
||||
<input
|
||||
v-else-if="inputProps().mask"
|
||||
ref="formInput"
|
||||
v-model="selectedValue"
|
||||
v-mask="inputProps().mask"
|
||||
class="form-input"
|
||||
:type="inputProps().type"
|
||||
:disabled="!isChecked"
|
||||
>
|
||||
<BaseUploadInput
|
||||
v-else-if="inputProps().type === 'file'"
|
||||
:value="selectedValue"
|
||||
:message="$t('word.browse')"
|
||||
@clear="clearValue"
|
||||
@change="filesChange($event)"
|
||||
/>
|
||||
<input
|
||||
v-else-if="inputProps().type === 'number'"
|
||||
ref="formInput"
|
||||
v-model="selectedValue"
|
||||
class="form-input"
|
||||
step="any"
|
||||
:type="inputProps().type"
|
||||
:disabled="!isChecked"
|
||||
>
|
||||
<input
|
||||
v-else
|
||||
ref="formInput"
|
||||
v-model="selectedValue"
|
||||
class="form-input"
|
||||
:type="inputProps().type"
|
||||
:disabled="!isChecked"
|
||||
>
|
||||
<template v-if="methodData && 'params' in methodData" class="columns">
|
||||
<input
|
||||
v-for="(option, key) in methodData.params"
|
||||
:key="key"
|
||||
v-model="methodParams[option]"
|
||||
class="form-input column"
|
||||
:type="inputProps().type"
|
||||
:disabled="!isChecked"
|
||||
:placeholder="option"
|
||||
>
|
||||
</template>
|
||||
<slot />
|
||||
</fieldset>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mask } from 'vue-the-mask';
|
||||
import { TEXT, LONG_TEXT, NUMBER, FLOAT, DATE, TIME, DATETIME, BLOB, BIT } from 'common/fieldTypes';
|
||||
import BaseUploadInput from '@/components/BaseUploadInput';
|
||||
import ForeignKeySelect from '@/components/ForeignKeySelect';
|
||||
import FakerMethods from 'common/FakerMethods';
|
||||
|
||||
export default {
|
||||
name: 'FakerSelect',
|
||||
components: {
|
||||
ForeignKeySelect,
|
||||
BaseUploadInput
|
||||
},
|
||||
directives: {
|
||||
mask
|
||||
},
|
||||
props: {
|
||||
type: String,
|
||||
field: Object,
|
||||
isChecked: Boolean,
|
||||
foreignKeys: Array,
|
||||
keyUsage: Array,
|
||||
fieldLength: Number,
|
||||
fieldObj: Object
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
localType: null,
|
||||
selectedGroup: 'manual',
|
||||
selectedMethod: '',
|
||||
selectedValue: '',
|
||||
debounceTimeout: null,
|
||||
methodParams: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
fakerGroups () {
|
||||
if ([...TEXT, ...LONG_TEXT].includes(this.type))
|
||||
this.localType = 'string';
|
||||
else if (NUMBER.includes(this.type))
|
||||
this.localType = 'number';
|
||||
else if (FLOAT.includes(this.type))
|
||||
this.localType = 'float';
|
||||
else if ([...DATE, ...DATETIME].includes(this.type))
|
||||
this.localType = 'datetime';
|
||||
else if (TIME.includes(this.type))
|
||||
this.localType = 'time';
|
||||
|
||||
return FakerMethods.getGroupsByType(this.localType);
|
||||
},
|
||||
fakerMethods () {
|
||||
return FakerMethods.getMethods({ type: this.localType, group: this.selectedGroup });
|
||||
},
|
||||
methodData () {
|
||||
return this.fakerMethods.find(method => method.name === this.selectedMethod);
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
fieldObj () {
|
||||
if (this.fieldObj)
|
||||
this.selectedValue = this.fieldObj.value;
|
||||
},
|
||||
selectedGroup () {
|
||||
if (this.fakerMethods.length)
|
||||
this.selectedMethod = this.fakerMethods[0].name;
|
||||
else
|
||||
this.selectedMethod = '';
|
||||
},
|
||||
selectedMethod () {
|
||||
this.onChange();
|
||||
},
|
||||
selectedValue () {
|
||||
clearTimeout(this.debounceTimeout);
|
||||
this.debounceTimeout = null;
|
||||
this.debounceTimeout = setTimeout(() => {
|
||||
this.onChange();
|
||||
}, 200);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
inputProps () {
|
||||
if ([...TEXT, ...LONG_TEXT].includes(this.type))
|
||||
return { type: 'text', mask: false };
|
||||
|
||||
if ([...NUMBER, ...FLOAT].includes(this.type))
|
||||
return { type: 'number', mask: false };
|
||||
|
||||
if (TIME.includes(this.type)) {
|
||||
let timeMask = '##:##:##';
|
||||
const precision = this.fieldLength;
|
||||
|
||||
for (let i = 0; i < precision; i++)
|
||||
timeMask += i === 0 ? '.#' : '#';
|
||||
|
||||
return { type: 'text', mask: timeMask };
|
||||
}
|
||||
|
||||
if (DATE.includes(this.type))
|
||||
return { type: 'text', mask: '####-##-##' };
|
||||
|
||||
if (DATETIME.includes(this.type)) {
|
||||
let datetimeMask = '####-##-## ##:##:##';
|
||||
const precision = this.fieldLength;
|
||||
|
||||
for (let i = 0; i < precision; i++)
|
||||
datetimeMask += i === 0 ? '.#' : '#';
|
||||
|
||||
return { type: 'text', mask: datetimeMask };
|
||||
}
|
||||
|
||||
if (BLOB.includes(this.type))
|
||||
return { type: 'file', mask: false };
|
||||
|
||||
if (BIT.includes(this.type))
|
||||
return { type: 'text', mask: false };
|
||||
|
||||
return { type: 'text', mask: false };
|
||||
},
|
||||
getKeyUsage (keyName) {
|
||||
return this.keyUsage.find(key => key.field === keyName);
|
||||
},
|
||||
filesChange (event) {
|
||||
const { files } = event.target;
|
||||
if (!files.length) return;
|
||||
|
||||
this.selectedValue = files[0].path;
|
||||
},
|
||||
clearValue () {
|
||||
this.selectedValue = '';
|
||||
},
|
||||
onChange () {
|
||||
this.$emit('update:value', {
|
||||
group: this.selectedGroup,
|
||||
method: this.selectedMethod,
|
||||
params: this.methodParams,
|
||||
value: this.selectedValue,
|
||||
length: this.fieldLength
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@@ -50,6 +50,7 @@ export default {
|
||||
selectedWorkspace: 'workspaces/getSelected'
|
||||
}),
|
||||
isValidDefault () {
|
||||
if (!this.foreignList.length) return true;
|
||||
return this.foreignList.some(foreign => foreign.foreignColumn.toString() === this.value.toString());
|
||||
}
|
||||
},
|
||||
|
@@ -164,6 +164,7 @@
|
||||
<div class="col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:value="localConnection.key"
|
||||
:message="$t('word.browse')"
|
||||
@clear="pathClear('key')"
|
||||
@change="pathSelection($event, 'key')"
|
||||
/>
|
||||
@@ -176,6 +177,7 @@
|
||||
<div class="col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:value="localConnection.cert"
|
||||
:message="$t('word.browse')"
|
||||
@clear="pathClear('cert')"
|
||||
@change="pathSelection($event, 'cert')"
|
||||
/>
|
||||
@@ -188,6 +190,7 @@
|
||||
<div class="col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:value="localConnection.ca"
|
||||
:message="$t('word.browse')"
|
||||
@clear="pathClear('ca')"
|
||||
@change="pathSelection($event, 'ca')"
|
||||
/>
|
||||
|
388
src/renderer/components/ModalFakerRows.vue
Normal file
388
src/renderer/components/ModalFakerRows.vue
Normal file
@@ -0,0 +1,388 @@
|
||||
<template>
|
||||
<div class="modal active">
|
||||
<a class="modal-overlay" @click.stop="closeModal" />
|
||||
<div class="modal-container p-0">
|
||||
<div class="modal-header pl-2">
|
||||
<div class="modal-title h6">
|
||||
<div class="d-flex">
|
||||
<i class="mdi mdi-24px mdi-playlist-plus mr-1" /> {{ $t('message.tableFiller') }}
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn btn-clear c-hand" @click.stop="closeModal" />
|
||||
</div>
|
||||
<div class="modal-body pb-0">
|
||||
<div class="content">
|
||||
<form class="form-horizontal">
|
||||
<fieldset :disabled="isInserting">
|
||||
<div
|
||||
v-for="field in fields"
|
||||
:key="field.name"
|
||||
class="form-group"
|
||||
>
|
||||
<div class="col-3 col-sm-12">
|
||||
<label class="form-label" :title="field.name">{{ field.name }}</label>
|
||||
</div>
|
||||
<div class="column columns col-sm-12">
|
||||
<FakerSelect
|
||||
:type="field.type"
|
||||
class="column columns pr-0"
|
||||
:is-checked="!fieldsToExclude.includes(field.name)"
|
||||
:foreign-keys="foreignKeys"
|
||||
:key-usage="keyUsage"
|
||||
:field="field"
|
||||
:field-length="fieldLength(field)"
|
||||
:field-obj="localRow[field.name]"
|
||||
:value.sync="localRow[field.name]"
|
||||
>
|
||||
<span class="input-group-addon field-type" :class="`type-${field.type.toLowerCase()}`">
|
||||
{{ field.type }} {{ fieldLength(field) | wrapNumber }}
|
||||
</span>
|
||||
<label class="form-checkbox ml-3" :title="$t('word.insert')">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="!field.autoIncrement"
|
||||
@change.prevent="toggleFields($event, field)"
|
||||
><i class="form-icon" />
|
||||
</label>
|
||||
</FakerSelect>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer text-light columns">
|
||||
<div class="column d-flex" :class="hasFakes ? 'col-4' : 'col-2'">
|
||||
<div class="input-group tooltip tooltip-right" :data-tooltip="$t('message.numberOfInserts')">
|
||||
<input
|
||||
v-model="nInserts"
|
||||
type="number"
|
||||
class="form-input"
|
||||
min="1"
|
||||
:disabled="isInserting"
|
||||
>
|
||||
<span class="input-group-addon">
|
||||
<i class="mdi mdi-24px mdi-repeat" />
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
v-if="hasFakes"
|
||||
class="tooltip tooltip-right ml-2"
|
||||
:data-tooltip="$t('message.fakeDataLanguage')"
|
||||
>
|
||||
<select v-model="fakerLocale" class="form-select">
|
||||
<option value="ar">
|
||||
Arabic
|
||||
</option><option value="az">
|
||||
Azerbaijani
|
||||
</option><option value="zh_CN">
|
||||
Chinese
|
||||
</option><option value="zh_TW">
|
||||
Chinese (Taiwan)
|
||||
</option><option value="cz">
|
||||
Czech
|
||||
</option><option value="nl">
|
||||
Dutch
|
||||
</option><option value="nl_BE">
|
||||
Dutch (Belgium)
|
||||
</option><option value="en">
|
||||
English
|
||||
</option><option value="en_AU_ocker">
|
||||
English (Australia Ocker)
|
||||
</option><option value="en_AU">
|
||||
English (Australia)
|
||||
</option><option value="en_BORK">
|
||||
English (Bork)
|
||||
</option><option value="en_CA">
|
||||
English (Canada)
|
||||
</option><option value="en_GB">
|
||||
English (Great Britain)
|
||||
</option><option value="en_IND">
|
||||
English (India)
|
||||
</option><option value="en_IE">
|
||||
English (Ireland)
|
||||
</option><option value="en_ZA">
|
||||
English (South Africa)
|
||||
</option><option value="en_US">
|
||||
English (United States)
|
||||
</option><option value="fa">
|
||||
Farsi
|
||||
</option><option value="fi">
|
||||
Finnish
|
||||
</option><option value="fr">
|
||||
French
|
||||
</option><option value="fr_CA">
|
||||
French (Canada)
|
||||
</option><option value="fr_CH">
|
||||
French (Switzerland)
|
||||
</option><option value="ge">
|
||||
Georgian
|
||||
</option><option value="de">
|
||||
German
|
||||
</option><option value="de_AT">
|
||||
German (Austria)
|
||||
</option><option value="de_CH">
|
||||
German (Switzerland)
|
||||
</option><option value="hr">
|
||||
Hrvatski
|
||||
</option><option value="id_ID">
|
||||
Indonesia
|
||||
</option><option value="it">
|
||||
Italian
|
||||
</option><option value="ja">
|
||||
Japanese
|
||||
</option><option value="ko">
|
||||
Korean
|
||||
</option><option value="nep">
|
||||
Nepalese
|
||||
</option><option value="nb_NO">
|
||||
Norwegian
|
||||
</option><option value="pl">
|
||||
Polish
|
||||
</option><option value="pt_BR">
|
||||
Portuguese (Brazil)
|
||||
</option><option value="pt_PT">
|
||||
Portuguese (Portugal)
|
||||
</option><option value="ro">
|
||||
Romanian
|
||||
</option><option value="ru">
|
||||
Russian
|
||||
</option><option value="sk">
|
||||
Slovakian
|
||||
</option><option value="es">
|
||||
Spanish
|
||||
</option><option value="es_MX">
|
||||
Spanish (Mexico)
|
||||
</option><option value="sv">
|
||||
Swedish
|
||||
</option><option value="tr">
|
||||
Turkish
|
||||
</option><option value="uk">
|
||||
Ukrainian
|
||||
</option><option value="vi">
|
||||
Vietnamese
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column col-auto">
|
||||
<button
|
||||
class="btn btn-primary mr-2"
|
||||
:class="{'loading': isInserting}"
|
||||
@click.stop="insertRows"
|
||||
>
|
||||
{{ $t('word.insert') }}
|
||||
</button>
|
||||
<button class="btn btn-link" @click.stop="closeModal">
|
||||
{{ $t('word.close') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
import { TEXT, LONG_TEXT, NUMBER, FLOAT, DATE, TIME, DATETIME, BLOB } from 'common/fieldTypes';
|
||||
import { mask } from 'vue-the-mask';
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
import FakerSelect from '@/components/FakerSelect';
|
||||
|
||||
export default {
|
||||
name: 'ModalFakerRows',
|
||||
components: {
|
||||
FakerSelect
|
||||
},
|
||||
directives: {
|
||||
mask
|
||||
},
|
||||
filters: {
|
||||
wrapNumber (num) {
|
||||
if (!num) return '';
|
||||
return `(${num})`;
|
||||
}
|
||||
},
|
||||
props: {
|
||||
tabUid: [String, Number],
|
||||
fields: Array,
|
||||
keyUsage: Array
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
localRow: {},
|
||||
fieldsToExclude: [],
|
||||
nInserts: 1,
|
||||
isInserting: false,
|
||||
fakerLocale: 'en'
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
selectedWorkspace: 'workspaces/getSelected',
|
||||
getWorkspace: 'workspaces/getWorkspace',
|
||||
getWorkspaceTab: 'workspaces/getWorkspaceTab'
|
||||
}),
|
||||
workspace () {
|
||||
return this.getWorkspace(this.selectedWorkspace);
|
||||
},
|
||||
foreignKeys () {
|
||||
return this.keyUsage.map(key => key.field);
|
||||
},
|
||||
hasFakes () {
|
||||
return Object.keys(this.localRow).some(field => 'group' in this.localRow[field] && this.localRow[field].group !== 'manual');
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
nInserts (val) {
|
||||
if (!val || val < 1)
|
||||
this.nInserts = 1;
|
||||
else if (val > 1000)
|
||||
this.nInserts = 1000;
|
||||
}
|
||||
},
|
||||
created () {
|
||||
window.addEventListener('keydown', this.onKey);
|
||||
},
|
||||
mounted () {
|
||||
const rowObj = {};
|
||||
|
||||
for (const field of this.fields) {
|
||||
let fieldDefault;
|
||||
|
||||
if (field.default === 'NULL') fieldDefault = null;
|
||||
else {
|
||||
if ([...NUMBER, ...FLOAT].includes(field.type))
|
||||
fieldDefault = +field.default;
|
||||
|
||||
if ([...TEXT, ...LONG_TEXT].includes(field.type))
|
||||
fieldDefault = field.default ? field.default.substring(1, field.default.length - 1) : '';
|
||||
|
||||
if ([...TIME, ...DATE].includes(field.type))
|
||||
fieldDefault = field.default;
|
||||
|
||||
if (DATETIME.includes(field.type)) {
|
||||
if (field.default && field.default.toLowerCase().includes('current_timestamp')) {
|
||||
let datePrecision = '';
|
||||
for (let i = 0; i < field.datePrecision; i++)
|
||||
datePrecision += i === 0 ? '.S' : 'S';
|
||||
fieldDefault = moment().format(`YYYY-MM-DD HH:mm:ss${datePrecision}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rowObj[field.name] = { value: fieldDefault };
|
||||
|
||||
if (field.autoIncrement)// Disable by default auto increment fields
|
||||
this.fieldsToExclude = [...this.fieldsToExclude, field.name];
|
||||
}
|
||||
|
||||
this.localRow = { ...rowObj };
|
||||
},
|
||||
beforeDestroy () {
|
||||
window.removeEventListener('keydown', this.onKey);
|
||||
},
|
||||
methods: {
|
||||
...mapActions({
|
||||
addNotification: 'notifications/addNotification'
|
||||
}),
|
||||
async insertRows () {
|
||||
this.isInserting = true;
|
||||
const rowToInsert = this.localRow;
|
||||
|
||||
Object.keys(rowToInsert).forEach(key => {
|
||||
if (this.fieldsToExclude.includes(key))
|
||||
delete rowToInsert[key];
|
||||
|
||||
if (typeof rowToInsert[key] === 'undefined')
|
||||
delete rowToInsert[key];
|
||||
});
|
||||
|
||||
const fieldTypes = {};
|
||||
this.fields.forEach(field => {
|
||||
fieldTypes[field.name] = field.type;
|
||||
});
|
||||
|
||||
try {
|
||||
const { status, response } = await Tables.insertTableFakeRows({
|
||||
uid: this.selectedWorkspace,
|
||||
schema: this.workspace.breadcrumbs.schema,
|
||||
table: this.workspace.breadcrumbs.table,
|
||||
row: rowToInsert,
|
||||
repeat: this.nInserts,
|
||||
fields: fieldTypes,
|
||||
locale: this.fakerLocale
|
||||
});
|
||||
|
||||
if (status === 'success') {
|
||||
this.closeModal();
|
||||
this.$emit('reload');
|
||||
}
|
||||
else
|
||||
this.addNotification({ status: 'error', message: response });
|
||||
}
|
||||
catch (err) {
|
||||
this.addNotification({ status: 'error', message: err.stack });
|
||||
}
|
||||
|
||||
this.isInserting = false;
|
||||
},
|
||||
closeModal () {
|
||||
this.$emit('hide');
|
||||
},
|
||||
fieldLength (field) {
|
||||
if ([...BLOB, ...LONG_TEXT].includes(field.type)) return null;
|
||||
else if (TEXT.includes(field.type)) return field.charLength;
|
||||
return field.length;
|
||||
},
|
||||
toggleFields (event, field) {
|
||||
if (event.target.checked)
|
||||
this.fieldsToExclude = this.fieldsToExclude.filter(f => f !== field.name);
|
||||
else
|
||||
this.fieldsToExclude = [...this.fieldsToExclude, field.name];
|
||||
},
|
||||
filesChange (event, field) {
|
||||
const { files } = event.target;
|
||||
if (!files.length) return;
|
||||
|
||||
this.localRow[field] = files[0].path;
|
||||
},
|
||||
getKeyUsage (keyName) {
|
||||
return this.keyUsage.find(key => key.field === keyName);
|
||||
},
|
||||
onKey (e) {
|
||||
e.stopPropagation();
|
||||
if (e.key === 'Escape')
|
||||
this.closeModal();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.modal-container {
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
overflow: hidden;
|
||||
white-space: normal;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.input-group-addon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.field-type {
|
||||
font-size: 0.6rem;
|
||||
}
|
||||
</style>
|
@@ -168,6 +168,7 @@
|
||||
<div class="col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:value="connection.key"
|
||||
:message="$t('word.browse')"
|
||||
@clear="pathClear('key')"
|
||||
@change="pathSelection($event, 'key')"
|
||||
/>
|
||||
@@ -180,6 +181,7 @@
|
||||
<div class="col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:value="connection.cert"
|
||||
:message="$t('word.browse')"
|
||||
@clear="pathClear('cert')"
|
||||
@change="pathSelection($event, 'cert')"
|
||||
/>
|
||||
@@ -192,6 +194,7 @@
|
||||
<div class="col-8 col-sm-12">
|
||||
<BaseUploadInput
|
||||
:value="connection.ca"
|
||||
:message="$t('word.browse')"
|
||||
@clear="pathClear('ca')"
|
||||
@change="pathSelection($event, 'ca')"
|
||||
/>
|
||||
|
@@ -50,6 +50,16 @@
|
||||
:tabindex="key+1"
|
||||
@change="filesChange($event,field.name)"
|
||||
>
|
||||
<input
|
||||
v-else-if="inputProps(field).type === 'number'"
|
||||
ref="formInput"
|
||||
v-model="localRow[field.name]"
|
||||
class="form-input"
|
||||
step="any"
|
||||
:type="inputProps(field).type"
|
||||
:disabled="fieldsToExclude.includes(field.name)"
|
||||
:tabindex="key+1"
|
||||
>
|
||||
<input
|
||||
v-else
|
||||
ref="formInput"
|
||||
@@ -107,7 +117,7 @@
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
import { TEXT, LONG_TEXT, NUMBER, DATE, TIME, DATETIME, BLOB, BIT } from 'common/fieldTypes';
|
||||
import { TEXT, LONG_TEXT, NUMBER, FLOAT, DATE, TIME, DATETIME, BLOB, BIT } from 'common/fieldTypes';
|
||||
import { mask } from 'vue-the-mask';
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
@@ -157,6 +167,8 @@ export default {
|
||||
nInserts (val) {
|
||||
if (!val || val < 1)
|
||||
this.nInserts = 1;
|
||||
else if (val > 1000)
|
||||
this.nInserts = 1000;
|
||||
}
|
||||
},
|
||||
created () {
|
||||
@@ -170,7 +182,7 @@ export default {
|
||||
|
||||
if (field.default === 'NULL') fieldDefault = null;
|
||||
else {
|
||||
if (NUMBER.includes(field.type))
|
||||
if ([...NUMBER, ...FLOAT].includes(field.type))
|
||||
fieldDefault = +field.default;
|
||||
|
||||
if ([...TEXT, ...LONG_TEXT].includes(field.type))
|
||||
@@ -253,13 +265,14 @@ export default {
|
||||
},
|
||||
fieldLength (field) {
|
||||
if ([...BLOB, ...LONG_TEXT].includes(field.type)) return null;
|
||||
else if (TEXT.includes(field.type)) return field.charLength;
|
||||
return field.length;
|
||||
},
|
||||
inputProps (field) {
|
||||
if ([...TEXT, ...LONG_TEXT].includes(field.type))
|
||||
return { type: 'text', mask: false };
|
||||
|
||||
if (NUMBER.includes(field.type))
|
||||
if ([...NUMBER, ...FLOAT].includes(field.type))
|
||||
return { type: 'number', mask: false };
|
||||
|
||||
if (TIME.includes(field.type)) {
|
||||
|
@@ -437,7 +437,7 @@ export default {
|
||||
schema: this.schema,
|
||||
table: this.table,
|
||||
numPrecision: null,
|
||||
numLength: null,
|
||||
numLength: 11,
|
||||
datePrecision: null,
|
||||
charLength: null,
|
||||
nullable: false,
|
||||
|
@@ -400,7 +400,7 @@ export default {
|
||||
this.defaultValue.type = 'custom';
|
||||
this.defaultValue.custom = this.localRow.default.replace(/(^')|('$)/g, '');
|
||||
}
|
||||
else if (!isNaN(this.localRow.default)) {
|
||||
else if (!isNaN(this.localRow.default.replace(/[:.-\s]/g, ''))) {
|
||||
this.defaultValue.type = 'custom';
|
||||
this.defaultValue.custom = this.localRow.default;
|
||||
}
|
||||
|
@@ -81,7 +81,7 @@
|
||||
<script>
|
||||
import { uidGen } from 'common/libs/uidGen';
|
||||
import arrayToFile from '../libs/arrayToFile';
|
||||
import { LONG_TEXT, BLOB } from 'common/fieldTypes';
|
||||
import { TEXT, LONG_TEXT, BLOB } from 'common/fieldTypes';
|
||||
import BaseVirtualScroll from '@/components/BaseVirtualScroll';
|
||||
import WorkspaceQueryTableRow from '@/components/WorkspaceQueryTableRow';
|
||||
import TableContext from '@/components/WorkspaceQueryTableContext';
|
||||
@@ -196,6 +196,7 @@ export default {
|
||||
},
|
||||
fieldLength (field) {
|
||||
if ([...BLOB, ...LONG_TEXT].includes(field.type)) return null;
|
||||
else if (TEXT.includes(field.type)) return field.charLength;
|
||||
return field.length;
|
||||
},
|
||||
keyName (key) {
|
||||
|
@@ -16,7 +16,7 @@
|
||||
@dblclick="editON($event, col, cKey)"
|
||||
>{{ col | typeFormat(getFieldType(cKey), getFieldPrecision(cKey)) | cutText }}</span>
|
||||
<ForeignKeySelect
|
||||
v-else-if="foreignKeys.includes(cKey)"
|
||||
v-else-if="isForeignKey(cKey)"
|
||||
class="editable-field"
|
||||
:value.sync="editingContent"
|
||||
:key-usage="getKeyUsage(cKey)"
|
||||
@@ -135,7 +135,7 @@ import { mimeFromHex } from 'common/libs/mimeFromHex';
|
||||
import { formatBytes } from 'common/libs/formatBytes';
|
||||
import { bufferToBase64 } from 'common/libs/bufferToBase64';
|
||||
import hexToBinary from 'common/libs/hexToBinary';
|
||||
import { TEXT, LONG_TEXT, NUMBER, DATE, TIME, DATETIME, BLOB, BIT } from 'common/fieldTypes';
|
||||
import { TEXT, LONG_TEXT, NUMBER, FLOAT, DATE, TIME, DATETIME, BLOB, BIT } from 'common/fieldTypes';
|
||||
import { mask } from 'vue-the-mask';
|
||||
import ConfirmModal from '@/components/BaseConfirmModal';
|
||||
import ForeignKeySelect from '@/components/ForeignKeySelect';
|
||||
@@ -219,7 +219,7 @@ export default {
|
||||
if ([...TEXT, ...LONG_TEXT].includes(this.editingType))
|
||||
return { type: 'text', mask: false };
|
||||
|
||||
if (NUMBER.includes(this.editingType))
|
||||
if ([...NUMBER, ...FLOAT].includes(this.editingType))
|
||||
return { type: 'number', mask: false };
|
||||
|
||||
if (TIME.includes(this.editingType)) {
|
||||
@@ -260,7 +260,19 @@ export default {
|
||||
return this.keyUsage.map(key => key.field);
|
||||
},
|
||||
isEditable () {
|
||||
return this.fields ? !!(this.fields[0].schema && this.fields[0].table) : false;
|
||||
if (this.fields) {
|
||||
const nElements = this.fields.reduce((acc, curr) => {
|
||||
acc.add(curr.table);
|
||||
acc.add(curr.schema);
|
||||
return acc;
|
||||
}, new Set([]));
|
||||
|
||||
if (nElements.size > 2) return false;
|
||||
|
||||
return !!(this.fields[0].schema && this.fields[0].table);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -271,6 +283,12 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isForeignKey (key) {
|
||||
if (key.includes('.'))
|
||||
key = key.split('.').pop();
|
||||
|
||||
return this.foreignKeys.includes(key);
|
||||
},
|
||||
getFieldType (cKey) {
|
||||
let type = 'unknown';
|
||||
const field = this.getFieldObj(cKey);
|
||||
@@ -423,6 +441,8 @@ export default {
|
||||
this.$emit('select-row', event, row);
|
||||
},
|
||||
getKeyUsage (keyName) {
|
||||
if (keyName.includes('.'))
|
||||
return this.keyUsage.find(key => key.field === keyName.split('.').pop());
|
||||
return this.keyUsage.find(key => key.field === keyName);
|
||||
}
|
||||
}
|
||||
|
@@ -33,11 +33,16 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-dark btn-sm" @click="showAddModal">
|
||||
<span>{{ $t('word.add') }}</span>
|
||||
<button
|
||||
v-if="isTable"
|
||||
class="btn btn-dark btn-sm"
|
||||
@click="showFakerModal"
|
||||
>
|
||||
<span>{{ $t('message.tableFiller') }}</span>
|
||||
<i class="mdi mdi-24px mdi-playlist-plus ml-1" />
|
||||
</button>
|
||||
<div class="dropdown export-dropdown">
|
||||
|
||||
<div class="dropdown export-dropdown pr-2">
|
||||
<button
|
||||
:disabled="isQuering"
|
||||
class="btn btn-dark btn-sm dropdown-toggle mr-0 pr-0"
|
||||
@@ -91,6 +96,14 @@
|
||||
@hide="hideAddModal"
|
||||
@reload="reloadTable"
|
||||
/>
|
||||
<ModalFakerRows
|
||||
v-if="isFakerModal"
|
||||
:fields="fields"
|
||||
:key-usage="keyUsage"
|
||||
:tab-uid="tabUid"
|
||||
@hide="hideFakerModal"
|
||||
@reload="reloadTable"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -98,6 +111,7 @@
|
||||
import Tables from '@/ipc-api/Tables';
|
||||
import WorkspaceQueryTable from '@/components/WorkspaceQueryTable';
|
||||
import ModalNewTableRow from '@/components/ModalNewTableRow';
|
||||
import ModalFakerRows from '@/components/ModalFakerRows';
|
||||
import { mapGetters, mapActions } from 'vuex';
|
||||
import tableTabs from '@/mixins/tableTabs';
|
||||
|
||||
@@ -105,7 +119,8 @@ export default {
|
||||
name: 'WorkspaceTableTab',
|
||||
components: {
|
||||
WorkspaceQueryTable,
|
||||
ModalNewTableRow
|
||||
ModalNewTableRow,
|
||||
ModalFakerRows
|
||||
},
|
||||
mixins: [tableTabs],
|
||||
props: {
|
||||
@@ -119,6 +134,7 @@ export default {
|
||||
results: [],
|
||||
lastTable: null,
|
||||
isAddModal: false,
|
||||
isFakerModal: false,
|
||||
autorefreshTimer: 0,
|
||||
refreshInterval: null,
|
||||
sortParams: {}
|
||||
@@ -134,6 +150,9 @@ export default {
|
||||
isSelected () {
|
||||
return this.workspace.selected_tab === 'data';
|
||||
},
|
||||
isTable () {
|
||||
return !!this.workspace.breadcrumbs.table;
|
||||
},
|
||||
fields () {
|
||||
return this.results.length ? this.results[0].fields : [];
|
||||
},
|
||||
@@ -222,6 +241,12 @@ export default {
|
||||
hideAddModal () {
|
||||
this.isAddModal = false;
|
||||
},
|
||||
showFakerModal () {
|
||||
this.isFakerModal = true;
|
||||
},
|
||||
hideFakerModal () {
|
||||
this.isFakerModal = false;
|
||||
},
|
||||
onKey (e) {
|
||||
if (this.isSelected) {
|
||||
e.stopPropagation();
|
||||
|
@@ -69,19 +69,5 @@ module.exports = {
|
||||
uploadFile: 'رفع ملف',
|
||||
addNewRow: 'إضافة صف جديد',
|
||||
numberOfInserts: 'عدد الإدراجات'
|
||||
},
|
||||
// Date and Time
|
||||
short: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
},
|
||||
long: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
weekday: 'short',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric'
|
||||
}
|
||||
};
|
||||
|
@@ -90,7 +90,10 @@ module.exports = {
|
||||
privateKey: 'Private key',
|
||||
certificate: 'Certificate',
|
||||
caCertificate: 'CA certificate',
|
||||
ciphers: 'Ciphers'
|
||||
ciphers: 'Ciphers',
|
||||
upload: 'Upload',
|
||||
browse: 'Browse',
|
||||
faker: 'Faker'
|
||||
},
|
||||
message: {
|
||||
appWelcome: 'Welcome to Antares SQL Client!',
|
||||
@@ -178,20 +181,173 @@ module.exports = {
|
||||
createNewScheduler: 'Create new scheduler',
|
||||
deleteScheduler: 'Delete scheduler',
|
||||
preserveOnCompletion: 'Preserve on completion',
|
||||
enableSsl: 'Enable SSL'
|
||||
enableSsl: 'Enable SSL',
|
||||
manualValue: 'Manual value',
|
||||
tableFiller: 'Table Filler',
|
||||
fakeDataLanguage: 'Fake data language'
|
||||
},
|
||||
// Date and Time
|
||||
short: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
},
|
||||
long: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
weekday: 'short',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric'
|
||||
faker: {
|
||||
address: 'Address',
|
||||
commerce: 'Commerce',
|
||||
company: 'Company',
|
||||
database: 'Database',
|
||||
date: 'Date',
|
||||
finance: 'Finance',
|
||||
git: 'Git',
|
||||
hacker: 'Hacker',
|
||||
internet: 'Internet',
|
||||
lorem: 'Lorem',
|
||||
name: 'Name',
|
||||
music: 'Music',
|
||||
phone: 'Phone',
|
||||
random: 'Random',
|
||||
system: 'System',
|
||||
time: 'Time',
|
||||
vehicle: 'Vehicle',
|
||||
zipCode: 'Zip code',
|
||||
zipCodeByState: 'Zip code by state',
|
||||
city: 'City',
|
||||
cityPrefix: 'City prefix',
|
||||
citySuffix: 'City suffix',
|
||||
streetName: 'Street name',
|
||||
streetAddress: 'Street address',
|
||||
streetSuffix: 'Street suffix',
|
||||
streetPrefix: 'Street prefix',
|
||||
secondaryAddress: 'Secondary address',
|
||||
county: 'County',
|
||||
country: 'Country',
|
||||
countryCode: 'Country code',
|
||||
state: 'State',
|
||||
stateAbbr: 'State abbreviation',
|
||||
latitude: 'Latitude',
|
||||
longitude: 'Longitude',
|
||||
direction: 'Direction',
|
||||
cardinalDirection: 'Cardinal direction',
|
||||
ordinalDirection: 'Ordinal direction',
|
||||
nearbyGPSCoordinate: 'Nearby GPS coordinate',
|
||||
timeZone: 'Time zone',
|
||||
color: 'Color',
|
||||
department: 'Department',
|
||||
productName: 'Product name',
|
||||
price: 'Price',
|
||||
productAdjective: 'Product adjective',
|
||||
productMaterial: 'Product material',
|
||||
product: 'Product',
|
||||
productDescription: 'Product description',
|
||||
suffixes: 'Suffixes',
|
||||
companyName: 'Company name',
|
||||
companySuffix: 'Company suffix',
|
||||
catchPhrase: 'Catch phrase',
|
||||
bs: 'BS',
|
||||
catchPhraseAdjective: 'Catch phrase adjective',
|
||||
catchPhraseDescriptor: 'Catch phrase descriptor',
|
||||
catchPhraseNoun: 'Catch phrase noun',
|
||||
bsAdjective: 'BS adjective',
|
||||
bsBuzz: 'BS buzz',
|
||||
bsNoun: 'BS noun',
|
||||
column: 'Column',
|
||||
type: 'Type',
|
||||
collation: 'Collation',
|
||||
engine: 'Engine',
|
||||
past: 'Past',
|
||||
future: 'Future',
|
||||
between: 'Between',
|
||||
recent: 'Recent',
|
||||
soon: 'Soon',
|
||||
month: 'Month',
|
||||
weekday: 'Weekday',
|
||||
account: 'Account',
|
||||
accountName: 'Account name',
|
||||
routingNumber: 'Routing number',
|
||||
mask: 'Mask',
|
||||
amount: 'Amount',
|
||||
transactionType: 'Transaction type',
|
||||
currencyCode: 'Currency code',
|
||||
currencyName: 'Currency name',
|
||||
currencySymbol: 'Currency symbol',
|
||||
bitcoinAddress: 'Bitcoin address',
|
||||
litecoinAddress: 'Litecoin address',
|
||||
creditCardNumber: 'Credit card number',
|
||||
creditCardCVV: 'Credit card CVV',
|
||||
ethereumAddress: 'Ethereum address',
|
||||
iban: 'Iban',
|
||||
bic: 'Bic',
|
||||
transactionDescription: 'Transaction description',
|
||||
branch: 'Branch',
|
||||
commitEntry: 'Commit entry',
|
||||
commitMessage: 'Commit message',
|
||||
commitSha: 'Commit SHA',
|
||||
shortSha: 'Short SHA',
|
||||
abbreviation: 'Abbreviation',
|
||||
adjective: 'Adjective',
|
||||
noun: 'Noun',
|
||||
verb: 'Verb',
|
||||
ingverb: 'Ingverb',
|
||||
phrase: 'Phrase',
|
||||
avatar: 'Avatar',
|
||||
email: 'Email',
|
||||
exampleEmail: 'Example email',
|
||||
userName: 'Username',
|
||||
protocol: 'Protocol',
|
||||
url: 'Url',
|
||||
domainName: 'Domin name',
|
||||
domainSuffix: 'Domain suffix',
|
||||
domainWord: 'Domain word',
|
||||
ip: 'Ip',
|
||||
ipv6: 'Ipv6',
|
||||
userAgent: 'User agent',
|
||||
mac: 'Mac',
|
||||
password: 'Password',
|
||||
word: 'Word',
|
||||
words: 'Words',
|
||||
sentence: 'Sentence',
|
||||
slug: 'Slug',
|
||||
sentences: 'Sentences',
|
||||
paragraph: 'Paragraph',
|
||||
paragraphs: 'Paragraphs',
|
||||
text: 'Text',
|
||||
lines: 'Lines',
|
||||
genre: 'Genre',
|
||||
firstName: 'First name',
|
||||
lastName: 'Last name',
|
||||
middleName: 'Middle name',
|
||||
findName: 'Full name',
|
||||
jobTitle: 'Job title',
|
||||
gender: 'Gender',
|
||||
prefix: 'Prefix',
|
||||
suffix: 'Suffix',
|
||||
title: 'Title',
|
||||
jobDescriptor: 'Job descriptor',
|
||||
jobArea: 'Job area',
|
||||
jobType: 'Job type',
|
||||
phoneNumber: 'Phone number',
|
||||
phoneNumberFormat: 'Phone number format',
|
||||
phoneFormats: 'Phone formats',
|
||||
number: 'Number',
|
||||
float: 'Float',
|
||||
arrayElement: 'Array element',
|
||||
arrayElements: 'Array elements',
|
||||
objectElement: 'Object element',
|
||||
uuid: 'Uuid',
|
||||
boolean: 'Boolean',
|
||||
image: 'Image',
|
||||
locale: 'Locale',
|
||||
alpha: 'Alpha',
|
||||
alphaNumeric: 'Alphanumeric',
|
||||
hexaDecimal: 'Hexadecimal',
|
||||
fileName: 'File name',
|
||||
commonFileName: 'Common file name',
|
||||
mimeType: 'Mime type',
|
||||
commonFileType: 'Common file type',
|
||||
commonFileExt: 'Common file extension',
|
||||
fileType: 'File type',
|
||||
fileExt: 'File extension',
|
||||
directoryPath: 'Directory path',
|
||||
filePath: 'File path',
|
||||
semver: 'Semver',
|
||||
manufacturer: 'Manufacturer',
|
||||
model: 'Model',
|
||||
fuel: 'Fuel',
|
||||
vin: 'Vin'
|
||||
}
|
||||
};
|
||||
|
@@ -72,19 +72,5 @@ module.exports = {
|
||||
numberOfInserts: 'Numero de inserciones',
|
||||
openNewTab: 'Abrir nueva pestaña',
|
||||
affectedRows: 'Filas afectadas'
|
||||
},
|
||||
// Date and Time
|
||||
short: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
},
|
||||
long: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
weekday: 'short',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric'
|
||||
}
|
||||
};
|
||||
|
352
src/renderer/i18n/fr-FR.js
Normal file
352
src/renderer/i18n/fr-FR.js
Normal file
@@ -0,0 +1,352 @@
|
||||
module.exports = {
|
||||
word: {
|
||||
edit: 'Éditer',
|
||||
save: 'Enregistrer',
|
||||
close: 'Fermer',
|
||||
delete: 'Supprimer',
|
||||
confirm: 'Confirmer',
|
||||
cancel: 'Annuler',
|
||||
send: 'Envoyer',
|
||||
connectionName: 'Nom de connexion',
|
||||
client: 'Client',
|
||||
hostName: 'Nom d\'hôte',
|
||||
port: 'Port',
|
||||
user: 'Utilisateur',
|
||||
password: 'Mot de passe',
|
||||
credentials: 'Identifiants',
|
||||
connect: 'Se connecter',
|
||||
connected: 'Connecté',
|
||||
disconnect: 'Se déconnecter',
|
||||
disconnected: 'Déconnecté',
|
||||
refresh: 'Rafraichir',
|
||||
settings: 'Paramètres',
|
||||
general: 'Général',
|
||||
themes: 'Thèmes',
|
||||
update: 'Mise à jour',
|
||||
about: 'À propos',
|
||||
language: 'Langue',
|
||||
version: 'Version',
|
||||
donate: 'Faire un don',
|
||||
run: 'Exécuter',
|
||||
schema: 'Schéma',
|
||||
results: 'Résutats',
|
||||
size: 'Taille',
|
||||
seconds: 'Secondes',
|
||||
type: 'Type',
|
||||
mimeType: 'Mime-Type',
|
||||
download: 'Télécharger',
|
||||
add: 'Ajouter',
|
||||
data: 'Données',
|
||||
properties: 'Propriétés',
|
||||
insert: 'Insérer',
|
||||
connecting: 'Connexion',
|
||||
name: 'Nom',
|
||||
collation: 'Collation',
|
||||
clear: 'Effacer',
|
||||
options: 'Options',
|
||||
autoRefresh: 'Auto-rafraichissement',
|
||||
indexes: 'Index',
|
||||
foreignKeys: 'Clés étrangères',
|
||||
length: 'Taille',
|
||||
unsigned: 'Non-signé',
|
||||
default: 'Défaut',
|
||||
comment: 'Commentaire',
|
||||
key: 'Clé | Clés',
|
||||
order: 'Ordre',
|
||||
expression: 'Expression',
|
||||
autoIncrement: 'Auto Increment',
|
||||
engine: 'Engine',
|
||||
field: 'Champ | Champs',
|
||||
approximately: 'Approximativement',
|
||||
total: 'Totale',
|
||||
table: 'Table',
|
||||
discard: 'Abandonner',
|
||||
stay: 'Rester',
|
||||
author: 'Auteur',
|
||||
light: 'Clair',
|
||||
dark: 'Sombre',
|
||||
autoCompletion: 'Completion auto',
|
||||
application: 'Application',
|
||||
editor: 'Editeur',
|
||||
view: 'Vue',
|
||||
definer: 'Définisseur',
|
||||
algorithm: 'Algorithme',
|
||||
trigger: 'Déclencheur | Déclencheurs',
|
||||
storedRoutine: 'Procedure stockée | Procedures stockées',
|
||||
scheduler: 'Opération planifiée | Opérations planifiées',
|
||||
event: 'Evenement',
|
||||
parameters: 'Paramètres',
|
||||
function: 'Fonction | Fonctions',
|
||||
deterministic: 'Déterministe',
|
||||
context: 'Contextz',
|
||||
export: 'Exporter',
|
||||
returns: 'Retourner',
|
||||
timing: 'Horaire',
|
||||
state: 'État',
|
||||
execution: 'Exécution',
|
||||
starts: 'Débuts',
|
||||
ends: 'Fins',
|
||||
ssl: 'SSL',
|
||||
privateKey: 'Clé privée',
|
||||
certificate: 'Certificat',
|
||||
caCertificate: 'CA certificat',
|
||||
ciphers: 'Chiffrement',
|
||||
upload: 'Charger',
|
||||
browse: 'Parcourir',
|
||||
faker: 'Faker'
|
||||
},
|
||||
message: {
|
||||
appWelcome: 'Bienvenu sur le client SQL Antares!',
|
||||
appFirstStep: 'Première étape: Créer une nouvelle connexion à une base de données.',
|
||||
addConnection: 'Ajouter une connexion',
|
||||
createConnection: 'Créer une connexion',
|
||||
createNewConnection: 'Créer une nouvelle connexion',
|
||||
askCredentials: 'Demander les identifiants',
|
||||
testConnection: 'Tester la connexion',
|
||||
editConnection: 'Editer la connexion',
|
||||
deleteConnection: 'Supprimer la connexion',
|
||||
deleteCorfirm: 'Êtes-vous sûr de vouloir annuler',
|
||||
connectionSuccessfullyMade: 'Connexion établie avec succès!',
|
||||
madeWithJS: 'Créé avec 💛 et JavaScript!',
|
||||
checkForUpdates: 'Rechercher des mises à jour',
|
||||
noUpdatesAvailable: 'Aucune mise à jour disponible',
|
||||
checkingForUpdate: 'Recherche de mise à jour',
|
||||
checkFailure: 'Erreur lors de la recherche, essayez plus tard',
|
||||
updateAvailable: 'Une mise à jour est disponible',
|
||||
downloadingUpdate: 'Téléchargement de la mise à jour',
|
||||
updateDownloaded: 'Mise à jour téléchargée',
|
||||
restartToInstall: 'Redémarrer Antares pour l\'installer',
|
||||
unableEditFieldWithoutPrimary: 'Impossible de modifier un champ sans clé primaire dans l\'ensemble de résultats',
|
||||
editCell: 'Modifier une cellule',
|
||||
deleteRows: 'Supprimer une ligne | Supprimer {count} lignes',
|
||||
confirmToDeleteRows: 'Êtes-vous sûr de vouloir supprimer une ligne? | Êtes-vous sûr de vouloir supprimer {count} lignes?',
|
||||
notificationsTimeout: 'Délai d\'expiration des notifications',
|
||||
uploadFile: 'Charger un fichier',
|
||||
addNewRow: 'Ajouter une ligne',
|
||||
numberOfInserts: 'Nombre d\'insertions',
|
||||
openNewTab: 'Ouvrir un nouvel onglet',
|
||||
affectedRows: 'Lignes concernées',
|
||||
createNewDatabase: 'Créer une nouvelle base de données',
|
||||
databaseName: 'Nom par défaut',
|
||||
serverDefault: 'Serveur par défaut',
|
||||
deleteDatabase: 'Supprimer la base de données',
|
||||
editDatabase: 'Modifier la base de données',
|
||||
clearChanges: 'Effacer les modifications',
|
||||
addNewField: 'Ajouter un champ',
|
||||
manageIndexes: 'Gérer les index',
|
||||
manageForeignKeys: 'Gérer les clés étrangères',
|
||||
allowNull: 'NULL autorisé',
|
||||
zeroFill: 'Remplissage zéro',
|
||||
customValue: 'Valeur personnalisée',
|
||||
onUpdate: 'Lors d\'une mise à jour',
|
||||
deleteField: 'Supprimer le champ',
|
||||
createNewIndex: 'Créer un index',
|
||||
addToIndex: 'Ajouter à l\'index',
|
||||
createNewTable: 'Créer une nouvelle table',
|
||||
emptyTable: 'Table vide',
|
||||
deleteTable: 'Supprimer la table',
|
||||
emptyCorfirm: 'Êtes-vous sûr de vouloir videz',
|
||||
unsavedChanges: 'Changements non sauvegardés',
|
||||
discardUnsavedChanges: 'Vous avez des modifications non sauvegardées. En quittant cet onglet, ces changements seront supprimés.',
|
||||
thereAreNoIndexes: 'Il n\'y a pas d\'indexes',
|
||||
thereAreNoForeign: 'Il n\'y a pas de clés étrangères',
|
||||
createNewForeign: 'Créer une clés étrangère',
|
||||
referenceTable: 'Table de référence',
|
||||
referenceField: 'CHamp de référence',
|
||||
foreignFields: 'Champ étrangé',
|
||||
invalidDefault: 'Valeur par défaut invalide',
|
||||
onDelete: 'Lors de la suppression',
|
||||
applicationTheme: 'Thème de l\'application',
|
||||
editorTheme: 'Thème de l\'éditeur',
|
||||
wrapLongLines: 'Retour à la ligne automatique',
|
||||
selectStatement: 'Sélectionnez la déclaration',
|
||||
triggerStatement: 'Déclaration de déclencheur',
|
||||
sqlSecurity: 'Sécurité SQL',
|
||||
updateOption: 'Options de mises à jour',
|
||||
deleteView: 'Supprimer la vue',
|
||||
createNewView: 'Créer une nouvelle vue',
|
||||
deleteTrigger: 'Supprimer le déclencheur',
|
||||
createNewTrigger: 'Créer un nouveau déclencheur',
|
||||
currentUser: 'Utilisateur actuel',
|
||||
routineBody: 'Contenu de la procédure',
|
||||
dataAccess: 'Accès aux données',
|
||||
thereAreNoParameters: 'Il n\'y a pas de paramètres',
|
||||
createNewParameter: 'Créer un nouveau paramètre',
|
||||
createNewRoutine: 'Créer une nouvelle procédure stockée',
|
||||
deleteRoutine: 'Supprimer une procédure stockée',
|
||||
functionBody: 'Contenu de la fonction',
|
||||
createNewFunction: 'Créer une nouvelle fonction',
|
||||
deleteFunction: 'Supprimer la fonction',
|
||||
schedulerBody: 'Contenu du opération planifiée',
|
||||
createNewScheduler: 'Créere une nouvelle opération planifiée',
|
||||
deleteScheduler: 'Supprimer l\'opération planifiée',
|
||||
preserveOnCompletion: 'Préserver à l\'achèvement',
|
||||
enableSsl: 'Activer le SSL',
|
||||
manualValue: 'Valeur manuelle',
|
||||
tableFiller: 'Remplisseur de table'
|
||||
},
|
||||
faker: {
|
||||
address: 'Adresse',
|
||||
commerce: 'Commerce',
|
||||
company: 'Entreprise',
|
||||
database: 'Base de données',
|
||||
date: 'Date',
|
||||
finance: 'Finance',
|
||||
git: 'Git',
|
||||
hacker: 'Hacker',
|
||||
internet: 'Internet',
|
||||
lorem: 'Lorem',
|
||||
name: 'Nom',
|
||||
music: 'Musique',
|
||||
phone: 'Téléphone',
|
||||
random: 'Aléatoire',
|
||||
system: 'Système',
|
||||
time: 'Temps',
|
||||
vehicle: 'Véhicle',
|
||||
zipCode: 'Code postal',
|
||||
zipCodeByState: 'Code postal par région',
|
||||
city: 'Ville',
|
||||
cityPrefix: 'Préfixe de la ville',
|
||||
citySuffix: 'Suffixe de la ville',
|
||||
streetName: 'Ne de la rue',
|
||||
streetAddress: 'Adresse',
|
||||
streetSuffix: 'Suffixe de la rue',
|
||||
streetPrefix: 'Préfixe de la rue',
|
||||
secondaryAddress: 'Adresse secondaire',
|
||||
county: 'Comté',
|
||||
country: 'Pays',
|
||||
countryCode: 'Code du pays',
|
||||
state: 'Région',
|
||||
stateAbbr: 'Abbreviation de la région',
|
||||
latitude: 'Latitude',
|
||||
longitude: 'Longitude',
|
||||
direction: 'Direction',
|
||||
cardinalDirection: 'Orientation cardinale',
|
||||
ordinalDirection: 'Orientation originale',
|
||||
nearbyGPSCoordinate: 'Coordonnées GPS des environs',
|
||||
timeZone: 'Fuseau horaire',
|
||||
color: 'Couleur',
|
||||
department: 'Département',
|
||||
productName: 'Nom de produit',
|
||||
price: 'Prix',
|
||||
productAdjective: 'Adjectif du produit',
|
||||
productMaterial: 'Matériau du produit',
|
||||
product: 'Produit',
|
||||
productDescription: 'Description du produit',
|
||||
suffixes: 'Suffixes',
|
||||
companyName: 'Nom de l\'entreprise',
|
||||
companySuffix: 'Suffixe de l\'entreprise',
|
||||
catchPhrase: 'Slogan',
|
||||
bs: 'BS',
|
||||
catchPhraseAdjective: 'Adjectif du slogan',
|
||||
catchPhraseDescriptor: 'Descripteur de slogan',
|
||||
catchPhraseNoun: 'Nom de la phrase d\'accroche',
|
||||
bsAdjective: 'Adjectif BS',
|
||||
bsBuzz: 'BS buzz',
|
||||
bsNoun: 'Nom BS',
|
||||
column: 'Colonne',
|
||||
type: 'Type',
|
||||
collation: 'Collation',
|
||||
engine: 'Engine',
|
||||
past: 'Passé',
|
||||
future: 'Futur',
|
||||
between: 'Entre',
|
||||
recent: 'Récent',
|
||||
soon: 'Bientôt',
|
||||
month: 'Mois',
|
||||
weekday: 'Mercredi',
|
||||
account: 'Compte',
|
||||
accountName: 'Nom de compte',
|
||||
routingNumber: 'Numéros de routage',
|
||||
mask: 'Masque',
|
||||
amount: 'Quantité',
|
||||
transactionType: 'Type de transaction',
|
||||
currencyCode: 'Code de la devise',
|
||||
currencyName: 'Nom de la devise',
|
||||
currencySymbol: 'Symbole de la devise',
|
||||
bitcoinAddress: 'Adresse Bitcoin',
|
||||
litecoinAddress: 'Adresse Litecoin',
|
||||
creditCardNumber: 'Numero de carte de crédit',
|
||||
creditCardCVV: 'Cryptogramme',
|
||||
ethereumAddress: 'Adresse Ethereum',
|
||||
iban: 'Iban',
|
||||
bic: 'Bic',
|
||||
transactionDescription: 'Description de la transaction',
|
||||
branch: 'Branche',
|
||||
commitEntry: 'Valider l\'entrée',
|
||||
commitMessage: 'Valider le message',
|
||||
commitSha: 'Valider le SHA',
|
||||
shortSha: 'SHA court',
|
||||
abbreviation: 'Abbréviation',
|
||||
adjective: 'Adjectif',
|
||||
noun: 'Nom',
|
||||
verb: 'Verbe',
|
||||
ingverb: 'Ingverb',
|
||||
phrase: 'Phrase',
|
||||
avatar: 'Avatar',
|
||||
email: 'Email',
|
||||
exampleEmail: 'Exemple d\'email',
|
||||
userName: 'Nom d\'utilisateur',
|
||||
protocol: 'Protocole',
|
||||
url: 'Url',
|
||||
domainName: 'Nom de domaine',
|
||||
domainSuffix: 'Suffixe du nom de domaine',
|
||||
domainWord: 'Mot de domaine',
|
||||
ip: 'Ip',
|
||||
ipv6: 'Ipv6',
|
||||
userAgent: 'User agent',
|
||||
mac: 'Mac',
|
||||
password: 'Mot de passe',
|
||||
word: 'Mot',
|
||||
words: 'Mots',
|
||||
sentence: 'Phrase',
|
||||
slug: 'Slug',
|
||||
sentences: 'Phrases',
|
||||
paragraph: 'Paragraphe',
|
||||
paragraphs: 'Paragraphes',
|
||||
text: 'Texte',
|
||||
lines: 'Lignes',
|
||||
genre: 'Genre',
|
||||
firstName: 'Prénom',
|
||||
lastName: 'Nom',
|
||||
middleName: 'Deuxième prénom',
|
||||
findName: 'Nom et prénom',
|
||||
jobTitle: 'Intitulé du poste',
|
||||
gender: 'Genre',
|
||||
prefix: 'Préfixe',
|
||||
suffix: 'Suffixe',
|
||||
title: 'Titre',
|
||||
jobDescriptor: 'Descripteur de poste',
|
||||
jobArea: 'Domaine d\'activité',
|
||||
jobType: 'Type de poste',
|
||||
phoneNumber: 'Numéro de téléphone',
|
||||
phoneNumberFormat: 'Format du numéro de téléphone',
|
||||
phoneFormats: 'Formats de téléphone',
|
||||
number: 'Numéro',
|
||||
float: 'Nombre décimaux',
|
||||
arrayElement: 'Élément de Liste',
|
||||
arrayElements: 'Éléments de liste',
|
||||
objectElement: 'Élément d\'objet',
|
||||
uuid: 'Uuid',
|
||||
boolean: 'Boolean',
|
||||
image: 'Image',
|
||||
locale: 'Locale',
|
||||
alpha: 'Alpha',
|
||||
alphaNumeric: 'Alphanumerique',
|
||||
hexaDecimal: 'Hexadecimale',
|
||||
fileName: 'Nom deu fichier',
|
||||
commonFileName: 'Nom de fichier commun',
|
||||
mimeType: 'Mime type',
|
||||
commonFileType: 'Type de dossier commun',
|
||||
commonFileExt: 'Extension de fichier commun',
|
||||
fileType: 'Type de fichier',
|
||||
fileExt: 'Extension de fichier',
|
||||
directoryPath: 'Chemin du répertoire',
|
||||
filePath: 'Chemin d\'accès au fichier',
|
||||
semver: 'Semver',
|
||||
manufacturer: 'Fabricant',
|
||||
model: 'Modèle',
|
||||
fuel: 'Carburant',
|
||||
vin: 'Vin'
|
||||
}
|
||||
};
|
@@ -8,7 +8,8 @@ const i18n = new VueI18n({
|
||||
'en-US': require('./en-US'),
|
||||
'it-IT': require('./it-IT'),
|
||||
'ar-SA': require('./ar-SA'),
|
||||
'es-ES': require('./es-ES')
|
||||
'es-ES': require('./es-ES'),
|
||||
'fr-FR': require('./fr-FR')
|
||||
}
|
||||
});
|
||||
export default i18n;
|
||||
|
@@ -72,19 +72,5 @@ module.exports = {
|
||||
numberOfInserts: 'Numero di insert',
|
||||
openNewTab: 'Apri nuova scheda',
|
||||
affectedRows: 'Righe interessate'
|
||||
},
|
||||
// Date and Time
|
||||
short: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
},
|
||||
long: {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
weekday: 'short',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric'
|
||||
}
|
||||
};
|
||||
|
@@ -2,5 +2,6 @@ export default {
|
||||
'en-US': 'English',
|
||||
'it-IT': 'Italiano',
|
||||
'ar-SA': 'العربية',
|
||||
'es-ES': 'Español'
|
||||
'es-ES': 'Español',
|
||||
'fr-FR': 'Français'
|
||||
};
|
||||
|
@@ -30,6 +30,10 @@ export default class {
|
||||
return ipcRenderer.invoke('insert-table-rows', params);
|
||||
}
|
||||
|
||||
static insertTableFakeRows (params) {
|
||||
return ipcRenderer.invoke('insert-table-fake-rows', params);
|
||||
}
|
||||
|
||||
static getForeignList (params) {
|
||||
return ipcRenderer.invoke('get-foreign-list', params);
|
||||
}
|
||||
|
Reference in New Issue
Block a user