Giter Site home page Giter Site logo

synle / sqlui-native Goto Github PK

View Code? Open in Web Editor NEW
55.0 7.0 8.0 14.21 MB

SQLUI Native (sqluinative) is a simple UI client for most SQL Engines written in Electron. It is compatible with Windows, Mac, Ubuntu / Debian and Redhat. It supports most dialects of RMBDs like MySQL, Microsoft SQL Server, Postgres, SQLite and has limited supports for Cassandra, MongoDB, Redis, CockroachDB, Azure CosmosDB and Azure Storage Tab

Home Page: https://synle.github.io/sqlui-native/

License: MIT License

JavaScript 0.91% HTML 1.11% TypeScript 97.41% SCSS 0.57%
sql mysql postgresql sqlite mssql cassandra mongodb redis sqluinative azure

sqlui-native's Introduction

build-main

64

sqlui-native is a simple UI client for most SQL Engines written in Electron. It is compatible with most desktop OS's and support most dialects of RDBMS like MySQL, Microsoft SQL Server, Postgres, SQLite, Cassandra, MongoDB, Redis, Azure CosmosDB and Azure Storage Table.

It supports multiple Windows, so you can have different sets of queries and connections side by side. The connections and queries are all stored locally, so you can continue where you left off in later visits.

Downloads

Refer to the following link for download information.

Supported OS's

Supported Database Adapters

The list below are supported data stores. You can also refer to this link for General Queries

Features

Overall Demo

demo-full

Import and Export

Import and Export can be used to share connections across different machines and users. Below is a sample import config.

[
  {
    "_type": "connection",
    "id": "connection.1643485516220.4798705129674932",
    "connection": "postgres://postgres:password@localhost:5432",
    "name": "sy postgres"
  },
  {
    "_type": "query",
    "id": "query.1643561715854.5278536054107370",
    "name": "Employee Query on Postgres",
    "sql": "SELECT\n  *\nFROM\n  employees\nLIMIT\n  10",
    "connectionId": "connection.1643485516220.4798705129674932",
    "databaseId": "music_store"
  }
]

You can also drag and drop the file directly into sqlui-native application. At the moment, we only support drag and drop for a single file.

demo-import-export

Session Management

This application supports multiple windows / instances. Sessions are used to control which instances it persist the data with. Also these sessions, and the associated connections and queries are persisted locally. So you can continue where you left off in the future.

demo-session

Dark Mode

Dark mode will be turned on automatically with respect to your OS Preference. You can update settings to prefer Dark Mode or Light Mode if desired.

demo-darkmode

Query Tabs

Query Tab Orientation

When there is more than 20 tabs, the query tabs will be wrapped vertically.

image

Reordering Query Tabs

Query tabs can be re-ordered by drag and drop the query tabs bar.

tab-ordering

Resizing the sidebar

The left sidebar can be resized by clicking and dragging the small section between the sidebar and the query box.

sidebar-resize

Command Palette

Similar to VS Code and Sublime Text, sqlui-native comes with a command palette that lets you reach your mostly used command via a key combo CMD + P or Ctrl + P on Windows.

image

Connection Hints

Sample URI connection string can be accessed by clicking on the Show Connection Hints on New / Edit Connection Page. Then you can click on the sample URI connection to use that sample connection string as a starting place.

image

Settings

Settings can be accessed via the top right menu icon. It allows you to set up preferred settings for things like Editor and Color Theme, etc...

image

image

Data Migration

If you happens to work with different database engine, there's a chance you want to move data from one engine to another engine. You can use Data Migration to craft a query to pull in data from the old engine and select a destination to generate the new schema / data for the new engine.

  • Data Migration can be accessed from the top right hamburger icon
  • From there, you have 2 options to migrate data. Either by a raw JSON or by data from an existing connection.

image

image

Migration of Real Existing Connection

Use this data migration option to move data from an existing connection

image

Migration of Raw JSON Data

Use this data migration option to move raw JSON data

image

Bookmarks

The system allows you to bookmark connections and queries. Bookmarked items can be applied to any workspace.

Adding new bookmark

  • To bookmark a connection or query, open the context menu on the Connection name or Query tab name and choose Add to Bookmark.
  • Give the bookmarked item a name and hit Save.

image

image

Open a bookmark

You can select and apply a bookmarked item from bookmarks page which can be accessed via the hamburger menu bar on the top right and select Bookmarks

  • From there, you can click on the bookmarked name to apply that bookmark item.

image

image

Recycle bin

By default, all closed queries and deleted connections will be stored inside of a recycle bin which you can always restore at a later. To access the recycle bin, click on the hamburger menu bar on the top right and select Recycle Bin.

  • From there you can choose to Restore the deleted connections or closed queries.
  • To permanently delete the items from sqlui-native, you can choose either Empty Trash or Delete individual items permanently.

image

image

Hard Delete

If you want to permanently delete those and not put it in the recycle bin, you can set the Delete Mode to be hard delete.

image

Record Pages

New Record Page

  • New record page can be opened using the New Record button underneath the query editor.
  • There you need to select Connection / Database / Table you want to create a new record for.
  • The form will render where you need to fill out the form data.
  • Click on Generate Script to generate the query for the insert.

image

image

Record Details / Edit Record Page

  • Clicking on any record on the query results will bring up the Record Detail page
  • There you can toggle the edit mode.
  • The form will render where you need to fill out the form data.
  • Click on Generate Script to generate the query for the insert.

Contributing

Dev Note

Here is the link where you can find information about how run this application locally.

Features / TODO's:

  • Consolidate the interface for mocked server and the main.ts page.
  • Make a build for Windows and Darwin.
  • Added Basic CI/CD to package electron
  • Make a build for other systems like Debian / Ubuntu and Redhat.
  • Add a configuration / option page for color mode.
  • Enhance the table with pagination.
  • Enhance the table for result with sorting, and searching.
  • Add quick query queries (such as select from a table or do update / insert).
  • Add quick query to recreate the table definition (Create Table), Drop Table, etc....
  • Add a full screen mode (F11)
  • Add ability to save CSV / JSON / Table to files.
  • Add ability to support multiple windows and sessions..
  • Add ability to import and export connections and queries.
  • Add ability to work with multiple instances.
  • Add autocomplete tokens for the query.
  • Add dark theme (Dark mode respect system color theme).
  • Add auto update features.
  • Push a build to Microsoft Store.
  • Add supports for Cassandra.
  • Add supports for Azure CosmosDB.
  • Add supports for Azure Table (Azure Table storage).
  • Add supports for AWS Redshift.

Limitations

sqlite Limitations

sqlite doesn't support multiple statements. So if you have multiple inserts or updates in a single query, it will not work. Refer to this Stackoverflow post for more details related to sqlite.

If you want to do bulk inserts, use bulk inserts API instead.

INSERT INTO
  art (Name)
VALUES
  ('Queen'),
  ('Kiss'),
  ('Spyro Gyra')

CockroachDB Limitations

CockroachDB can be connected using postgresSQL. Replace ?sslmode=require with sslmode=no-verify

Sample connection will look like this

postgres://demo:[email protected]:26257/movr?sslmode=no-verify

Cassandra Limitations

Cassandra Keyspaces are mapped to sqlui-native databases. And Cassandra Column Families are mapped to sqlui-native table.

How to get connection string for CosmosDB with Cassandra API?

  • Go to Connection String of the Azure CosmosDB Cassandra

image

Sample CosmosDB with Cassandra API Connection String

It will look something like this.

cassandra://USERNAME:PRIMARY PASSWORD@CONTACT POINT:PORT

MongoDB Limitations

MongoDB Collections is mapped to sqlui-native table. We scan the first 5 Documents to come up with the schema for the columns.

Create new MongoDB Database

As of now (v1.27.0), you can create new mongodb using the following syntax

db.createDatabase('new-database-name');

Redis Limitations

Due to the size of keys within Redis connection, we will not show all keys in the Redis cache.

  • As for SSL Redis support, use the rediss:// connection scheme.

How to get connection string for Azure Redis Cache?

  • Go to Access Keys on Azure Redis Cache. image
  • Connection will look like rediss://<username>:<password>@<your_redis_host>:<redis_port>
  • Sample connection will look like this. Due to how the URL scheme is parsed, a non empty string is required for the username placeholder. It can be anything but empty string. rediss://azure:[email protected]:6380

Azure CosmosDB Limitations

Azure CosmosDB Databases are mapped to sqlui-native Databases. And Azure CosmosDB Containers are mapped to sqlui-native Tables. We scan the first 5 items to come up with the schema for the columns.

Tested for Azure CosmosDB (with Core SQL).

How to get connection string for CosmosDB with Core SQL API?

Here's how to set up the connection. Open your resource, and click on Keys. Then copy and use either PRIMARY CONNECTION STRING or SECONDARY CONNECTION STRING

image image

Sample CosmosDB with Core SQL API Connection String

It will look something like this.

cosmosdb://<your_primary_connection_string>

or

cosmosdb://<your_secondary_connection_string>

Azure Table Storage Limitations

Azure Table Storage tables are mapped to sqlui-native Tables. We scan the first 5 items to come up with the schema for the columns.

Setting up connection string

Here's how to set up the connection.

image image

Sample connection will look like this

aztable://<your_connection_string>

Suggestion?

Use the following link to file a bug or a suggestion.

sqlui-native's People

Contributors

dependabot[bot] avatar synle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

sqlui-native's Issues

Starter Code Snippet Generator

Will allow users to generate starter code.

  • Added sample code snippets to let you write your node js code.
  • This basically generates starter code where you can use to run in your language of choice. At the moment only node js is supported. We'll plan to add more snippets like Java and Python.

To be supported Language

To be supported Database Engine

  • Relational Database (with Sequelize)
    • mysql
      • Node JS
      • Python
      • Java
    • mariadb
      • Node JS
      • Python
      • Java
    • mssql
      • Node JS
      • Python
      • Java
    • postgres
      • Node JS
      • Python
      • Java
    • sqlite
      • Node JS
      • Python
      • Java
  • cassandra
    • Node JS
    • Python
    • Java
  • mongodb
    • Node JS
    • Python
    • Java
  • redis
    • Node JS
    • Python
    • Java
  • cosmosdb
    • Node JS
    • Python
    • Java
  • aztable
    • Node JS
    • Python
    • Java

Screenshots

image

image

Support azure table

Sample connection string

aztable://DefaultEndpointsProtocol=https;AccountName=<your_account_name>;AccountKey=<your_account_key>;EndpointSuffix=core.windows.net

Screenshots

image
image
image
image
image

`Undo` does not work in the code editor after applying any query

Undo does not work in the code editor after applying any query

  • Right now after you apply the query, the undo stack is completely wiped out (editor.setValue) will destroy the undo stack.
  • Need to execute edits and push undo stop to simulate regular edits and persist the undo operation.

Below is the sample code

const newValue = props.value || '';

// https://stackoverflow.com/questions/60965171/not-able-to-do-undo-in-monaco-editor
// NOTE we can't do setValue here because it will wipe out the undo stack
// Select all text
const fullRange = editor.getModel()?.getFullModelRange();

if(fullRange !== undefined){
  // Apply the text over the range
  editor.executeEdits(null, [{
    text: newValue,
    range: fullRange
  }]);

  // Indicates the above edit is a complete undo/redo change.
  editor.pushUndoStop();
} else {
  // fall back to use setValue if we can't find the range
  editor.setValue(newValue);
}

TLS Socket errors for Redis - Error: Got an unexpected reply from Redis

[0] Error: Got an unexpected reply from Redis
[0]     at Object.onReply (/home/syle/git/sqlui-native/node_modules/@redis/client/dist/lib/client/commands-queue.js:57:27)
[0]     at RESP2Decoder.write (/home/syle/git/sqlui-native/node_modules/@redis/client/dist/lib/client/RESP2/decoder.js:119:26)
[0]     at RedisCommandsQueue.onReplyChunk (/home/syle/git/sqlui-native/node_modules/@redis/client/dist/lib/client/commands-queue.js:203:72)
[0]     at RedisSocket.<anonymous> (/home/syle/git/sqlui-native/node_modules/@redis/client/dist/lib/client/index.js:342:84)
[0]     at RedisSocket.emit (events.js:400:28)
[0]     at TLSSocket.<anonymous> (/home/syle/git/sqlui-native/node_modules/@redis/client/dist/lib/client/socket.js:163:42)
[0]     at TLSSocket.emit (events.js:400:28)
[0]     at addChunk (internal/streams/readable.js:293:12)
[0]     at readableAddChunk (internal/streams/readable.js:267:9)
[0]     at TLSSocket.Readable.push (internal/streams/readable.js:206:10)
error Command failed with exit code 1.

CosmosDB support - Added support for new dialect Azure CosmosDB

Changes:

Azure CosmosDB required that we provides the tableID, so we'll change the connection selector to add the optional tableId when the dialect is detected as cosmosdb
image

Connection String

cosmosdb://AccountEndpoint=some_cosmos_endpoint;AccountKey=some_cosmos_account_key

Screenshots

image
image
image
image

Recycle bin and ability to restore recently closed tabs and connections.

Features:

  • Should be able to make a backup and restore for connection and query before it's deleted.
  • Should allow a global flag to bypass recycle bin and delete everything for goods.
  • Add a UI to restore connection / connection query

Sample JSON for Recycle Bin Item

>>> cat /home/syle/.sqlui-native/folders.recycleBin.json

Queries Backup

{
  "recycleBin.1656299786451.7141772469794720": {
    "id": "recycleBin.1656299786451.7141772469794720",
    "name": "Tab 2",
    "type": "Query",
    "data": {
      "id": "queryId.1656299775866.9765773352545586",
      "name": "Tab 2",
      "sql": ""
    }
  },
  "recycleBin.1656299786760.4011666588716109": {
    "id": "recycleBin.1656299786760.4011666588716109",
    "name": "Tab 3",
    "type": "Query",
    "data": {
      "id": "queryId.1656299776525.193067786210257",
      "name": "Tab 3",
      "sql": ""
    }
  }
}

Connection Backup

{
  "id": "recycleBin.1656300821267.4191296173010423",
  "name": "mysql Connection - 6/26/2022",
  "type": "Connection",
  "data": {
    "id": "connection.1656300705160.7654608070047222",
    "connection": "mysql://root:password@localhost:3306",
    "name": "mysql Connection - 6/26/2022"
  }
}

Screenshots

image
image

Redis only - scan and map records based on a max num

This is iffy, not sure if it's a good idea to support and if it is, should it be done as a map for table vs columns?

image

Sample PR code

The code for this is ready here, but will not merge until we can find a better UX.
https://github.com/synle/sqlui-native/pull/331/files

Sample code used to scan the iterator

for await (const key of client.scanIterator(iteratorParams)) {
        res.push({
          name: key,
          columns: [],
        })

        if(res.length === 15){
          // top it off at max records
          break;
        }
      }

Can't render array of primitives properly inside of the table

  • Can't render array of primitives properly inside of the table

Sample query to generate this behavior

Use any one of the select distinct inside of MongoDB

db.collection('sy-collection-1a')
  .distinct(
    'location', {
    }
  )

Issue

Raw JSON input

This is the raw JSON that causes this issue

[
  "",
  "Bay Area",
  "Morgan Hill",
  "San Jose, CA",
  "sdfgdsf"
]

Bug

image

Expected

Will render the column for these primitives as standalone

image

Record Details page to make read / edit / delete easier

A custom route / modal to make read and edit / delete record easier

Limitations

  • Currently we don't automatically apply the query for inserts and update and requires one additional step to verify if the generated query is correct.
  • For update queries, we will attempt to only do partial update queries, but if none of the fields are updated by the user, we will attempt to generate the update on all fields.

Screenshots

Click to Show Record Details in Modal

image
image

New Record Page

image
image
image

Edit Record Page

image
image
image
image
image

Connection Actions - Create Database, etc...

Add Connection Actions - Create Database, etc...

  • Some brand new connections without any databases might be hard to use when it doesn't have a database. Most actions are tied to databases and tables.

Show constraints / foreign key metadata in relational database

Sequelize Interface : https://sequelize.org/api/v6/class/src/dialects/abstract/query-interface.js~queryinterface#instance-method-getForeignKeysForTables

Sample code to get foreignKeys for relational database

try {
  const res1 = await this.getConnection(database)
    .getQueryInterface()
    .getForeignKeyReferencesForTable(table);

  console.log(this.dialect, database, table, res1);
} catch (err) {}

Sample query to create table with foreignKeys

CREATE TABLE users (
  id serial,
  username VARCHAR(25) NOT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE addresses (
  user_id int NOT NULL,
  street VARCHAR(50) NOT NULL,
  city VARCHAR(50) NOT NULL,
  state VARCHAR(50) NOT NULL,
  PRIMARY KEY (user_id),
  CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users (id)
);

Sample foreignKey responses from relational databases in Sequelize

Postgres
{
  "constraintName": "fk_user_id",
  "constraintSchema": "public",
  "constraintCatalog": "og_music_store",
  "tableName": "addresses",
  "tableSchema": "public",
  "tableCatalog": "og_music_store",
  "columnName": "user_id",
  "referencedTableSchema": "public",
  "referencedTableCatalog": "og_music_store",
  "referencedTableName": "users",
  "referencedColumnName": "id"
}
Mysql
{
  "tableName": "addresses",
  "columnName": "user_id",
  "referencedTableName": "users",
  "referencedColumnName": "id",
  "tableCatalog": undefined,
  "referencedTableCatalog": undefined
}

Recommendation:

Maybe consider visualize it with this library
https://github.com/projectstorm/react-diagrams/tree/master/diagrams-demo-project

image

query problem

{ "code": "ER_BAD_DB_ERROR", "errno": 1049, "sqlState": "42000", "sqlMessage": "Unknown database ':undefined/users_dev'" }

MongoDB doesn't render `findOne` nicely

  • MongoDB doesn't render findOne nicely
  • It does render, but it shows up as a raw JSON object, will be nice to render it as a table row.

Issue

image

Expected

Should render it in the table format
image

Ability to delete a session

There is no place to delete a session.

  • A place to delete session.
  • electron-default should not be allowed to be deleted.
  • Special handling for cases where users open a deleted session.

screenshots

image
image
image

Delete session in command palette

image

Error for default session delete

image

Connect via the Cassandra support to Cosmos DB

@cicorias found a bug in the Cassandra setup from within CosmosDB

I haven't tested that scenario, most of my locals are with docker container for Cassandra and as for CosmosDB (Core SQL). I can take a look

image

Potential Issues:

SSL Check

Refer to this for more info: https://docs.microsoft.com/en-us/azure/developer/javascript/how-to/with-database/use-cassandra-as-cosmos-db#use-native-sdk-packages-to-connect-to-cassandra-db-on-azure

const client = new cassandra.Client({
  ...clientOptions,
  ...{
    sslOptions: {
      rejectUnauthorized: false,
    }
  }
});

Connection string needs be properly escaped.

Needs to use encodeURIComponent

Azure Redis connection not working

Issue is caused by us not support SSL for Redis and no option to enter the password.

How to construct the Connection for Azure Redis

  • Go to Access Keys on Azure Redis
  • Connection will look like
    rediss://:<password>@<your_redis_host>:<redis_port>
  • Sample connection will look like this
    rediss://:[email protected]:6380

Screenshots

image

Ability to bookmark queries / connections

Sample JSON

Query

>>> cat /home/syle/.sqlui-native/folders.bookmarks.json
{
  "bookmarks.1656457990125.7306698064745569": {
    "id": "bookmarks.1656457990125.7306698064745569",
    "type": "Query",
    "data": {
      "id": "queryId.1656386963631.7337545015452436",
      "name": "Sy test 123",
      "sql": "SELECT\n  *\nFROM\n  albums_snapshot4\nLIMIT\n  100",
      "connectionId": "connection.1656340917546.3396115637536507",
      "databaseId": "Sqlite"
    }
  }
}

Add query to bookmark screenshots

image
image

Add connection to bookmark screenshots

image

bookmarks link

image

Bookmark landing page

image

Overhaul session

  • Don't allow using the same session in different windows due to conflicts of Save operations
  • Attached windowId to each of the opened window so we can keep track of opened session id and properly free up closed session id.
  • Introduce a windowId that mapped to sessionId
  • New window will be presented with an option to select a choice of sessions on page load
  • Re-useable session selection components
  • Disabled state for sessions you can't select (either opened by another window or not)
  • No longer requires a concept of DEFAULT_SESSION_ID which can't be deleted.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.