Documentation v.1

Current version: 0.1.5
Last review: 5/26/2024

Requirements

To run MginDB locally, ensure your system meets the following requirements:

Minimum system specifications:

Additionally, ensure you have adequate disk space for storing data and backups, and a stable internet connection for downloading dependencies during installation.


Installation

To install MginDB, follow these simple steps:

1. Create a directory mgindb:

2. Download the latest version of MginDB. You will find both a .whl file and a .tar.gz file.

.whl file: wget https://mgindb.com/downloads/mgindb-0.1.5-py3-none-any.whl
.tar.gz file: wget https://mgindb.com/downloads/mgindb-0.1.5.tar.gz

3. Install the one that suits your needs:

4. If you downloaded the .whl file, you can install it directly using pip:

pip install mgindb-0.1.5-py3-none-any.whl

If you downloaded the .tar.gz file, follow these steps:

5. Ensure that port 6446 is open or authorized on your server or network/security group.

6. Once the installation is complete, and the network configurations are set, start MginDB by running:

mgindb start

7. Verify that MginDB is running with the command:

mgindb client

8. Congratulations! You have successfully installed MginDB on your system.

9. Start with your first commands! Refer to the CLI section for instructions on using MginDB.

Auto-update

MginDB supports automatic updates. Each time you start the server, it checks for a new version. AUTO_UPDATE is set to 1 by default in conf.json.

Use the command CONFIG SET AUTO_UPDATE 0/1 to activate/deactivate automatic updates

Check updates with the command: CHECKUPDATE. If there is a new version available restart your server.


Domain Access

To access MginDB with a custom domain name, you can set up Apache or Nginx as a reverse proxy.

Apache Configuration

If you're using Apache, you can configure it to proxy requests to MginDB running on localhost:6446 with the following steps:

# Enable required modules
a2enmod proxy
a2enmod proxy_http

# Create a virtual host configuration file
sudo nano /etc/apache2/sites-available/mgindb.conf

Then, add the following configuration to the file:

<VirtualHost *:80>
ServerName yourdomain.com
ProxyPreserveHost On
ProxyPass / ws://localhost:6446/
ProxyPassReverse / ws://localhost:6446/
</VirtualHost>

Save the file and enable the virtual host:

a2ensite mgindb.conf
service apache2 restart

Nginx Configuration

If you prefer Nginx, you can configure it to proxy requests to MginDB using the following steps:

# Create a new server block configuration file
sudo nano /etc/nginx/sites-available/mgindb

Then, add the following configuration to the file:

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        proxy_pass ws://localhost:6446/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Save the file and enable the server block:

ln -s /etc/nginx/sites-available/mgindb /etc/nginx/sites-enabled/
service nginx restart

After configuring Apache or Nginx, your MginDB instance should be accessible via your custom domain name.


Running as a Service

To run MginDB as a service on your system, you can follow these steps:

  1. Create a systemd service file for MginDB. Open a terminal and run:
  2. sudo nano /etc/systemd/system/mgindb.service

  3. In the editor, add the following content to the file:
  4. [Unit]
    Description=MginDB Service
    After=network.target
    
    [Service]
    User=www-data
    Group=www-data
    # Ensure the working directory is set to where MginDB is installed or accessible
    WorkingDirectory=/path/to/mgindb
    # Use the CLI command to start MginDB
    ExecStart=/path/to/mgindb/venv/bin/mgindb start
    Restart=always
    
    [Install]
    WantedBy=multi-user.target

  5. Replace your_username with your actual system username and /path/to/mgindb with the directory where MginDB can be accessed, if necessary.

  6. Save and close the file (press Ctrl + X, followed by Y, then Enter).

  7. Reload systemd to recognize the new service file:
  8. sudo systemctl daemon-reload

  9. Start the MginDB service:
  10. sudo systemctl start mgindb.service

  11. Enable the MginDB service to start on boot:
  12. sudo systemctl enable mgindb.service

  13. You can check the status of the MginDB service to ensure it is running properly:
  14. sudo systemctl status mgindb.service

MginDB is now set to run as a service on your system and will automatically start on system boot.


Server CLI / Web CLI / GUI DB Admin

The Server CLI / Web CLI / GUI DB Admin provide convenient ways to interact with the server-side script.
Choose the method that best suits your preferences and requirements.

Server CLI: The Server CLI allows you to interact directly with your server through a command-line interface. To access it:

  1. Log in to the server where MginDB is installed.
  2. Open a terminal and execute the command mgindb client.
With the CLI active, enter commands into the terminal and press Enter to execute them.

Web CLI: This interface is accessible through any standard web browser and provides a user-friendly environment for command execution.

Screenshots:
Server CLI Server CLI Web CLI Web CLI Web CLI

GUI DB Admin: Offers a comprehensive visual interface for managing your MginDB instances. This graphical user interface allows you to monitor data visually, execute queries interactively, and explore the relationships between data through deep graph visualizations.

Features of the GUI DB Admin include:

The GUI DB Admin is an essential tool for both developers and administrators, providing a centralized platform for database management with an emphasis on usability and visualization.

Screenshots:
GUI DB Admin GUI DB Admin GUI DB Admin GUI DB Admin

To use the CLI / GUI DB Admin, follow these steps:
  1. Download the TOOLS PACKAGE using your preferred web browser.
  2. Extract the downloaded tools.zip file into your chosen directory.
  3. Edit const uri = 'ws://127.0.0.1:6446'; for js/cli.js and js/gui.js in a text editor to configure the WebSocket IP or URL and your credentials.
  4. Open client.html and gui.html, it will automatically connect to your MginDB server.
  5. If client.html and gui.html is hosted on your server, ensure that access to it is securely configured.
× Enlarged Image

Using MginDB with the Python Client

The mgindb.py provides a robust Python interface to interact programmatically with MginDB via WebSockets.
This client handles connection management, authentication, and command execution transparently, allowing you to focus on interacting with your data.

Setup and Installation

Ensure you have the websockets library installed to use the Python client:

pip install websockets

Import the MginDBClient from mgindb.py into your Python script to start:

from mgindb import MginDBClient

Authentication and Connection

Initialize the client with your server details and credentials. The client will handle the WebSocket connection and authenticate automatically when you send the first command:

client = MginDBClient(protocol='ws/wss', host='127.0.0.1', port=6446, username='your_username', password='your_password')

Example Usage

Below is an example demonstrating how to perform various operations with the MginDB client:

import asyncio
from mgindb import MginDBClient

async def manage_data():
    # Initialize MginDBClient
    client = MginDBClient(protocol='ws/wss', host='127.0.0.1', port=6446, username='admin', password='password')

    # Set a value
    response = await client.set('key:subkey', 'value1')
    print(f"Response: {response}")

    # Query a value
    response = await client.query('key:subkey')
    print(f"Response: {response}")

    # Query with criteria
    response = await client.query('key:subkey', 'criteria > int AND criteria = "string"')
    print(f"Response: {response}")

    # Query with exclusions
    response = await client.query('key', '', 'EXCLUDE(password)')
    print(f"Response: {response}")

    # Query with ordering and grouping
    response = await client.query('key:subkey', 'criteria > int AND criteria = "string"', 'ORDERBY(key,DESC) GROUPBY(key)')
    print(f"Response: {response}")

    # Increment a counter
    response = await client.incr('key', 1)
    print(f"Response: {response}")

    # Decrement a counter
    response = await client.decr('key', 1)
    print(f"Response: {response}")

    # Delete a key
    response = await client.delete('key:subkey')
    print(f"Response: {response}")

    # Manage indices
    response = await client.indices('LIST')
    print(f"Response: {response}")
    response = await client.indices('GET', 'ALL')
    print(f"Response: {response}")
    response = await client.indices('GET', 'key:subkey')
    print(f"Response: {response}")
    response = response = await client.indices('CREATE', 'key:subkey', 'type')
    print(f"Response: {response}")
    response = await client.indices('DEL', 'key:subkey', 'value')
    print(f"Response: {response}")
    response = await client.indices('FLUSH', 'key:subkey')
    print(f"Response: {response}")

    # Manage schedules
    response = await client.schedule('SHOW ALL')
    print(f"Response: {response}")
    response = await client.schedule('SHOW', '* * * * *')
    print(f"Response: {response}")
    response = await client.schedule('SHOW', 'key/key:subkey')
    print(f"Response: {response}")
    response = await client.schedule('ADD', '* * * * *', 'COMMAND(INCR key:subkey value)')
    print(f"Response: {response}")
    response = await client.schedule('DEL', 'key/key:subkey')
    print(f"Response: {response}")
    response = await client.schedule('FLUSH ALL')
    print(f"Response: {response}")
    response = await client.schedule('FLUSH', '* * * * *')
    print(f"Response: {response}")

    # Subscribe / Unsubscribe to a key
    response = await client.sub('SUB', 'key:*/key:subkey:*')
    print(f"Response: {response}")

    response = await client.unsub('UNSUB', 'key:*/key:subkey:*')
    print(f"Response: {response}")

    await client.close()

asyncio.run(manage_data())

Asynchronous Handling

All client methods are asynchronous and should be used within an async function or alongside other asyncio tasks. This is ideal for non-blocking data operations and handling real-time data updates.

Security Note

Ensure your network connections are secure, especially when transmitting sensitive data. Use TLS to encrypt your WebSocket connections if operating over public networks.

With these guidelines, you can efficiently use the MginDB Python client to interact with your MginDB database instance through a clean and powerful API.


Using MginDB with the JavaScript Client

The mgindb.js file provides a robust JavaScript interface to interact programmatically with MginDB via WebSockets.
This client handles connection management, authentication, and command execution transparently, allowing you to focus on interacting with your data.

Setup and Installation

Ensure you have the ws library installed to use the JavaScript client:

npm install ws

Import the MginDBClient from mgindb.js into your JavaScript module to start:

import { MginDBClient } from './mgindb.js';

Authentication and Connection

Initialize the client with your server details and credentials. The client will handle the WebSocket connection and authenticate automatically when you send the first command:

const client = new MginDBClient('ws/wss', '127.0.0.1', 6446, 'your_username', 'your_password');

Example Usage

Below is an example demonstrating how to perform various operations with the MginDB client:

import { MginDBClient } from './client.js';

async function manageData() {
    // Initialize MginDBClient
    const client = new MginDBClient('ws/wss', '127.0.0.1', 6446, 'admin', 'password');

    // Set a value
    const response = await client.set('key:subkey', 'value1');
    console.log(`Response: ${response}`);

    // Query a value
    response = await client.query('key:subkey');
    console.log(`Response: ${response}`);

    // Query with criteria
    response = await client.query('key:subkey', 'criteria > int AND criteria = "string"');
    console.log(`Response: ${response}`);

    // Query with exclusions
    response = await client.query('key', '', 'EXCLUDE(password)');
    console.log(`Response: ${response}`);

    // Query with ordering and grouping
    response = await client.query('key:subkey', 'criteria > int AND criteria = "string"', 'ORDERBY(key,DESC) GROUPBY(key)');
    console.log(`Response: ${response}`);

    // Increment a counter
    response = await client.incr('key', 1);
    console.log(`Response: ${response}`);

    // Decrement a counter
    response = await client.decr('key', 1);
    console.log(`Response: ${response}`);

    // Delete a key
    response = await client.delete('key:subkey');
    console.log(`Response: ${response}`);

    // Manage indices
    response = await client.indices('LIST');
    console.log(`Response: ${response}`);
    response = await client.indices('GET', 'ALL');
    console.log(`Response: ${response}`);
    response = await client.indices('GET', 'key:subkey');
    console.log(`Response: ${response}`);
    response = await client.indices('CREATE', 'key:subkey', 'type');
    console.log(`Response: ${response}`);
    response = await client.indices('DEL', 'key:subkey', 'value');
    console.log(`Response: ${response}`);
    response = await client.indices('FLUSH', 'key:subkey');
    console.log(`Response: ${response}`);

    // Manage schedules
    response = await client.schedule('SHOW ALL');
    console.log(`Response: ${response}`);
    response = await client.schedule('SHOW', '* * * * *');
    console.log(`Response: ${response}`);
    response = await client.schedule('SHOW', 'key/key:subkey');
    console.log(`Response: ${response}`);
    response = await client.schedule('ADD', '* * * * *', 'COMMAND(INCR key:subkey value)');
    console.log(`Response: ${response}`);
    response = await client.schedule('DEL', 'key/key:subkey');
    console.log(`Response: ${response}`);
    response = await client.schedule('FLUSH ALL');
    console.log(`Response: ${response}`);
    response = await client.schedule('FLUSH', '* * * * *');
    console.log(`Response: ${response}`);

    // Subscribe / Unsubscribe to a key
    response = await client.sub('SUB', 'key:*/key:subkey:*');
    console.log(`Response: ${response}`);

    response = await client.unsub('UNSUB', 'key:*/key:subkey:*');
    console.log(`Response: ${response}`);

    await client.close();
}

manageData();

Asynchronous Handling

All client methods are asynchronous and should be used within an async function or alongside other async tasks. This is ideal for non-blocking data operations and handling real-time data updates.

Security Note

Ensure your network connections are secure, especially when transmitting sensitive data. Use TLS to encrypt your WebSocket connections if operating over public networks.

With these guidelines, you can efficiently use the MginDB JavaScript client to interact with your MginDB database instance through a clean and powerful API.


Using MginDB with the C# Client

The mgindb.cs provides a robust C# interface to interact programmatically with MginDB via WebSockets.
This client handles connection management, authentication, and command execution transparently, allowing you to focus on interacting with your data.

Setup and Installation

Ensure you have the necessary libraries installed to use the C# client:

Install-Package WebSocketSharp
Install-Package Newtonsoft.Json

Import the MginDBClient class into your C# project to start:

using YourNamespace;

Authentication and Connection

Initialize the client with your server details and credentials. The client will handle the WebSocket connection and authenticate automatically when you send the first command:

var client = new MginDBClient("ws/wss", "127.0.0.1", 6446, "your_username", "your_password");

Example Usage

Below is an example demonstrating how to perform various operations with the MginDB client:

using System;
using System.Threading.Tasks;

public class Program
{
    public static async Task Main(string[] args)
    {
        var client = new MginDBClient("ws/wss", "127.0.0.1", 6446, "your_username", "your_password");

        await client.ConnectAsync();

        // Set a value
        Console.WriteLine(await client.SetAsync("key:subkey", "value1"));

        // Query a value
        Console.WriteLine(await client.QueryAsync("key:subkey"));

        // Query with criteria
        Console.WriteLine(await client.QueryAsync("key:subkey", "criteria > int AND criteria = \"string\""));

        // Query with exclusions
        Console.WriteLine(await client.QueryAsync("key", "", "EXCLUDE(password)"));

        // Query with ordering and grouping
        Console.WriteLine(await client.QueryAsync("key:subkey", "criteria > int AND criteria = \"string\"", "ORDERBY(key,DESC) GROUPBY(key)"));

        // Increment a counter
        Console.WriteLine(await client.IncrAsync("key", "1"));

        // Decrement a counter
        Console.WriteLine(await client.DecrAsync("key", "1"));

        // Delete a key
        Console.WriteLine(await client.DeleteAsync("key:subkey"));

        // Manage indices
        Console.WriteLine(await client.IndicesAsync("LIST"));
        Console.WriteLine(await client.IndicesAsync("GET", "ALL"));
        Console.WriteLine(await client.IndicesAsync("GET", "key:subkey"));
        Console.WriteLine(await client.IndicesAsync("CREATE", "key:subkey", "type"));
        Console.WriteLine(await client.IndicesAsync("DEL", "key:subkey", "value"));
        Console.WriteLine(await client.IndicesAsync("FLUSH", "key:subkey"));

        // Manage schedules
        Console.WriteLine(await client.ScheduleAsync("SHOW ALL"));
        Console.WriteLine(await client.ScheduleAsync("SHOW", "* * * * *"));
        Console.WriteLine(await client.ScheduleAsync("SHOW", "key/key:subkey"));
        Console.WriteLine(await client.ScheduleAsync("ADD", "* * * * *", "COMMAND(INCR key:subkey value)"));
        Console.WriteLine(await client.ScheduleAsync("DEL", "key/key:subkey"));
        Console.WriteLine(await client.ScheduleAsync("FLUSH ALL"));
        Console.WriteLine(await client.ScheduleAsync("FLUSH", "* * * * *"));

        // Subscribe / Unsubscribe to a key
        Console.WriteLine(await client.SubAsync("key:*/key:subkey:*"));
        Console.WriteLine(await client.UnsubAsync("key:*/key:subkey:*"));

        client.Close();
    }
}

Asynchronous Handling

All client methods are asynchronous and should be used within an async function or alongside other async tasks. This is ideal for non-blocking data operations and handling real-time data updates.

Security Note

Ensure your network connections are secure, especially when transmitting sensitive data. Use TLS to encrypt your WebSocket connections if operating over public networks.

With these guidelines, you can efficiently use the MginDB C# client to interact with your MginDB database instance through a clean and powerful API.


Using MginDB with the Go Client

The mgindb.go provides a robust Go interface to interact programmatically with MginDB via WebSockets.
This client handles connection management, authentication, and command execution transparently, allowing you to focus on interacting with your data.

Setup and Installation

Ensure you have the necessary library installed to use the Go client:

go get github.com/gorilla/websocket

Import the MginDBClient from mgindb.go into your Go project to start:

import "path/to/your/package"

Authentication and Connection

Initialize the client with your server details and credentials. The client will handle the WebSocket connection and authenticate automatically when you send the first command:

client := NewMginDBClient("ws/wss", "127.0.0.1", 6446, "your_username", "your_password")

Example Usage

Below is an example demonstrating how to perform various operations with the MginDB client:

package main

import (
    "fmt"
    "log"
)

func main() {
    client := NewMginDBClient("ws/wss", "127.0.0.1", 6446, "your_username", "your_password")
    err := client.Connect()
    if err != nil {
        log.Fatalf("Failed to connect: %v", err)
    }

    // Set a value
    response, err := client.Set("key:subkey", "value1")
        if err != nil {
        log.Fatalf("Set command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    // Query a value
    response, err = client.Query("key:subkey", "", "")
    if err != nil {
        log.Fatalf("Query command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    // Query with criteria
    response, err = client.Query("key:subkey", "criteria > int AND criteria = \"string\"", "")
    if err != nil {
        log.Fatalf("Query command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    // Query with exclusions
    response, err = client.Query("key", "", "EXCLUDE(password)")
    if err != nil {
        log.Fatalf("Query command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    // Query with ordering and grouping
    response, err = client.Query("key:subkey", "criteria > int AND criteria = \"string\"", "ORDERBY(key,DESC) GROUPBY(key)")
    if err != nil {
        log.Fatalf("Query command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    // Increment a counter
    response, err = client.Incr("key", "1")
    if err != nil {
        log.Fatalf("Increment command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    // Decrement a counter
    response, err = client.Decr("key", "1")
    if err != nil {
        log.Fatalf("Decrement command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    // Delete a key
    response, err = client.Delete("key:subkey")
    if err != nil {
        log.Fatalf("Delete command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    // Manage indices
    response, err = client.Indices("LIST", "", "")
    if err != nil {
        log.Fatalf("Indices command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Indices("GET", "ALL", "")
    if err != nil {
        log.Fatalf("Indices command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Indices("GET", "key:subkey", "")
    if err != nil {
        log.Fatalf("Indices command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Indices("CREATE", "key:subkey", "type")
    if err != nil {
        log.Fatalf("Indices command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Indices("DEL", "key:subkey", "value")
    if err != nil {
        log.Fatalf("Indices command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Indices("FLUSH", "key:subkey", "")
    if err != nil {
        log.Fatalf("Indices command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    // Manage schedules
    response, err = client.Schedule("SHOW ALL", "", "")
    if err != nil {
        log.Fatalf("Schedule command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Schedule("SHOW", "* * * * *", "")
    if err != nil {
        log.Fatalf("Schedule command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Schedule("SHOW", "key/key:subkey", "")
    if err != nil {
        log.Fatalf("Schedule command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Schedule("ADD", "* * * * *", "COMMAND(INCR key:subkey value)")
    if err != nil {
        log.Fatalf("Schedule command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Schedule("DEL", "key/key:subkey", "")
    if err != nil {
        log.Fatalf("Schedule command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Schedule("FLUSH ALL", "", "")
    if err != nil {
        log.Fatalf("Schedule command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Schedule("FLUSH", "* * * * *", "")
    if err != nil {
        log.Fatalf("Schedule command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    // Subscribe / Unsubscribe to a key
    response, err = client.Sub("key:*/key:subkey:*")
    if err != nil {
        log.Fatalf("Subscribe command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    response, err = client.Unsub("key:*/key:subkey:*")
    if err != nil {
        log.Fatalf("Unsubscribe command failed: %v", err)
    }
    fmt.Printf("Response: %s\n", response)

    client.Close()
}

Asynchronous Handling

All client methods are asynchronous and should be used within an async function or alongside other async tasks. This is ideal for non-blocking data operations and handling real-time data updates.

Security Note

Ensure your network connections are secure, especially when transmitting sensitive data. Use TLS to encrypt your WebSocket connections if operating over public networks.

With these guidelines, you can efficiently use the MginDB Go client to interact with your MginDB database instance through a clean and powerful API.


Using MginDB with the Swift Client

The mgindb.swift provides a robust Swift interface to interact programmatically with MginDB via WebSockets.
This client handles connection management, authentication, and command execution transparently, allowing you to focus on interacting with your data.

Setup and Installation

Ensure you have the necessary libraries installed to use the Swift client:

pod 'Starscream', '~> 4.0'
pod 'SwiftyJSON', '~> 5.0'

Import the MginDBClient from mgindb.swift into your Swift project to start:

import Starscream
import SwiftyJSON

Authentication and Connection

Initialize the client with your server details and credentials. The client will handle the WebSocket connection and authenticate automatically when you send the first command:

let client = MginDBClient(protocol: "ws/wss", host: "127.0.0.1", port: 6446, username: "your_username", password: "your_password")
client.connect()

Example Usage

Below is an example demonstrating how to perform various operations with the MginDB client:

import Foundation

let client = MginDBClient(protocol: "ws/wss", host: "127.0.0.1", port: 6446, username: "your_username", password: "your_password")
client.connect()

// Set a value
client.set(key: "myKey", value: "myValue") { response in
    print("Set Response: \(response)")
}

// Query a value
client.query(key: "myKey") { response in
    print("Query Response: \(response)")
}

// Query with criteria
client.query(key: "myKey", queryString: "criteria > int AND criteria = \"string\"") { response in
    print("Query with Criteria Response: \(response)")
}

// Query with exclusions
client.query(key: "key", options: "EXCLUDE(password)") { response in
    print("Query with Exclusions Response: \(response)")
}

// Query with ordering and grouping
client.query(key: "key:subkey", queryString: "criteria > int AND criteria = \"string\"", options: "ORDERBY(key,DESC) GROUPBY(key)") { response in
    print("Query with Ordering and Grouping Response: \(response)")
}

// Increment a counter
client.incr(key: "myKey", value: "1") { response in
    print("Incr Response: \(response)")
}

// Decrement a counter
client.decr(key: "myKey", value: "1") { response in
    print("Decr Response: \(response)")
}

// Delete a key
client.delete(key: "myKey") { response in
    print("Delete Response: \(response)")
}

// Manage indices
client.indices(action: "LIST") { response in
    print("Indices LIST Response: \(response)")
}
client.indices(action: "GET", key: "ALL") { response in
    print("Indices GET ALL Response: \(response)")
}
client.indices(action: "GET", key: "key:subkey") { response in
    print("Indices GET Response: \(response)")
}
client.indices(action: "CREATE", key: "key:subkey", value: "type") { response in
    print("Indices CREATE Response: \(response)")
}
client.indices(action: "DEL", key: "key:subkey", value: "value") { response in
    print("Indices DEL Response: \(response)")
}
client.indices(action: "FLUSH", key: "key:subkey") { response in
    print("Indices FLUSH Response: \(response)")
}

// Manage schedules
client.schedule(action: "SHOW ALL") { response in
    print("Schedule SHOW ALL Response: \(response)")
}
client.schedule(action: "SHOW", cronOrKey: "* * * * *") { response in
    print("Schedule SHOW cron Response: \(response)")
}
client.schedule(action: "SHOW", cronOrKey: "key/key:subkey") { response in
    print("Schedule SHOW key Response: \(response)")
}
client.schedule(action: "ADD", cronOrKey: "* * * * *", command: "COMMAND(INCR key:subkey value)") { response in
    print("Schedule ADD Response: \(response)")
}
client.schedule(action: "DEL", cronOrKey: "key/key:subkey") { response in
    print("Schedule DEL Response: \(response)")
}
client.schedule(action: "FLUSH ALL") { response in
    print("Schedule FLUSH ALL Response: \(response)")
}
client.schedule(action: "FLUSH", cronOrKey: "* * * * *") { response in
    print("Schedule FLUSH cron Response: \(response)")
}

// Subscribe / Unsubscribe to a key
client.sub(key: "key:*/key:subkey:*") { response in
    print("Subscribe Response: \(response)")
}
client.unsub(key: "key:*/key:subkey:*") { response in
    print("Unsubscribe Response: \(response)")
}

client.disconnect()

Asynchronous Handling

All client methods use completion handlers for asynchronous operations. This is ideal for non-blocking data operations and handling real-time data updates.

Security Note

Ensure your network connections are secure, especially when transmitting sensitive data. Use TLS to encrypt your WebSocket connections if operating over public networks.

With these guidelines, you can efficiently use the MginDB Swift client to interact with your MginDB database instance through a clean and powerful API.


Using MginDB with the Rust Client

The mgindb.rs provides a robust Rust interface to interact programmatically with MginDB via WebSockets.
This client handles connection management, authentication, and command execution transparently, allowing you to focus on interacting with your data.

Setup and Installation

Ensure you have the necessary libraries installed to use the Rust client:

[dependencies]
tokio = { version = "1", features = ["full"] }
tokio-tungstenite = "0.15"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

Import the MginDBClient from mgindb.rs into your Rust project to start:

use crate::MginDBClient;

Authentication and Connection

Initialize the client with your server details and credentials. The client will handle the WebSocket connection and authenticate automatically when you send the first command:

let client = MginDBClient::new("ws/wss", "127.0.0.1", 6446, "your_username", "your_password");
let mut rx = client.connect().await?;

Example Usage

Below is an example demonstrating how to perform various operations with the MginDB client:

use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box> {
    let client = MginDBClient::new("ws/wss", "127.0.0.1", 6446, "your_username", "your_password");
    let mut rx = client.connect().await?;

    // Set a value
    let response = client.set("key:subkey", "value1", &mut rx).await?;
    println!("Set Response: {}", response);

    // Query a value
    let response = client.query("key:subkey", None, None, &mut rx).await?;
    println!("Query Response: {}", response);

    // Query with criteria
    let response = client.query("key:subkey", Some("criteria > int AND criteria = \"string\""), None, &mut rx).await?;
    println!("Query with Criteria Response: {}", response);

    // Query with exclusions
    let response = client.query("key", None, Some("EXCLUDE(password)"), &mut rx).await?;
    println!("Query with Exclusions Response: {}", response);

    // Query with ordering and grouping
    let response = client.query("key:subkey", Some("criteria > int AND criteria = \"string\""), Some("ORDERBY(key,DESC) GROUPBY(key)"), &mut rx).await?;
    println!("Query with Ordering and Grouping Response: {}", response);

    // Increment a counter
    let response = client.incr("key", "1", &mut rx).await?;
    println!("Incr Response: {}", response);

    // Decrement a counter
    let response = client.decr("key", "1", &mut rx).await?;
    println!("Decr Response: {}", response);

    // Delete a key
    let response = client.delete("key:subkey", &mut rx).await?;
    println!("Delete Response: {}", response);

    // Manage indices
    let response = client.indices("LIST", None, None, &mut rx).await?;
    println!("Indices LIST Response: {}", response);

    let response = client.indices("GET", Some("ALL"), None, &mut rx).await?;
    println!("Indices GET ALL Response: {}", response);

    let response = client.indices("GET", Some("key:subkey"), None, &mut rx).await?;
    println!("Indices GET Response: {}", response);

    let response = client.indices("CREATE", Some("key:subkey"), Some("type"), &mut rx).await?;
    println!("Indices CREATE Response: {}", response);

    let response = client.indices("DEL", Some("key:subkey"), Some("value"), &mut rx).await?;
    println!("Indices DEL Response: {}", response);

    let response = client.indices("FLUSH", Some("key:subkey"), None, &mut rx).await?;
    println!("Indices FLUSH Response: {}", response);

    // Manage schedules
    let response = client.schedule("SHOW ALL", None, None, &mut rx).await?;
    println!("Schedule SHOW ALL Response: {}", response);

    let response = client.schedule("SHOW", Some("* * * * *"), None, &mut rx).await?;
    println!("Schedule SHOW cron Response: {}", response);

    let response = client.schedule("SHOW", Some("key/key:subkey"), None, &mut rx).await?;
    println!("Schedule SHOW key Response: {}", response);

    let response = client.schedule("ADD", Some("* * * * *"), Some("COMMAND(INCR key:subkey value)"), &mut rx).await?;
    println!("Schedule ADD Response: {}", response);

    let response = client.schedule("DEL", Some("key/key:subkey"), None, &mut rx).await?;
    println!("Schedule DEL Response: {}", response);

    let response = client.schedule("FLUSH ALL", None, None, &mut rx).await?;
    println!("Schedule FLUSH ALL Response: {}", response);

    let response = client.schedule("FLUSH", Some("* * * * *"), None, &mut rx).await?;
    println!("Schedule FLUSH cron Response: {}", response);

    // Subscribe / Unsubscribe to a key
    let response = client.sub("key:*/key:subkey:*", &mut rx).await?;
    println!("Subscribe Response: {}", response);

    let response = client.unsub("key:*/key:subkey:*", &mut rx).await?;
    println!("Unsubscribe Response: {}", response);

    Ok(())
}

Asynchronous Handling

All client methods are asynchronous and should be used within an async function or alongside other async tasks. This is ideal for non-blocking data operations and handling real-time data updates.

Security Note

Ensure your network connections are secure, especially when transmitting sensitive data. Use TLS to encrypt your WebSocket connections if operating over public networks.

With these guidelines, you can efficiently use the MginDB Rust client to interact with your MginDB database instance through a clean and powerful API.


Using MginDB with the Ruby Client

The mgindb.rb provides a robust Ruby interface to interact programmatically with MginDB via WebSockets.
This client handles connection management, authentication, and command execution transparently, allowing you to focus on interacting with your data.

Setup and Installation

Ensure you have the necessary gems installed to use the Ruby client:

gem install websocket-client-simple
gem install json

Import the MginDBClient class into your Ruby script to start:

require './MginDBClient'

Authentication and Connection

Initialize the client with your server details and credentials. The client will handle the WebSocket connection and authenticate automatically when you send the first command:

client = mgindb.new('ws/wss', '127.0.0.1', 6446, 'your_username', 'your_password')
client.connect

Example Usage

Below is an example demonstrating how to perform various operations with the MginDB client:

require './MginDBClient'

client = mgindb.new('ws/wss', '127.0.0.1', 6446, 'your_username', 'your_password')
client.connect

# Set a value
puts client.set('key:subkey', 'value1')

# Query a value
puts client.query('key:subkey')

# Query with criteria
puts client.query('key:subkey', 'criteria > int AND criteria = "string"')

# Query with exclusions
puts client.query('key', nil, 'EXCLUDE(password)')

# Query with ordering and grouping
puts client.query('key:subkey', 'criteria > int AND criteria = "string"', 'ORDERBY(key,DESC) GROUPBY(key)')

# Increment a counter
puts client.incr('key', '1')

# Decrement a counter
puts client.decr('key', '1')

# Delete a key
puts client.delete('key:subkey')

# Manage indices
puts client.indices('LIST')
puts client.indices('GET', 'ALL')
puts client.indices('GET', 'key:subkey')
puts client.indices('CREATE', 'key:subkey', 'type')
puts client.indices('DEL', 'key:subkey', 'value')
puts client.indices('FLUSH', 'key:subkey')

# Manage schedules
puts client.schedule('SHOW ALL')
puts client.schedule('SHOW', '* * * * *')
puts client.schedule('SHOW', 'key/key:subkey')
puts client.schedule('ADD', '* * * * *', 'COMMAND(INCR key:subkey value)')
puts client.schedule('DEL', 'key/key:subkey')
puts client.schedule('FLUSH ALL')
puts client.schedule('FLUSH', '* * * * *')

# Subscribe / Unsubscribe to a key
puts client.sub('key:*/key:subkey:*')
puts client.unsub('key:*/key:subkey:*')

client.close

Synchronous Handling

The Ruby client is synchronous by default. Ensure that commands are sent and responses are handled appropriately for your application's needs.

Security Note

Ensure your network connections are secure, especially when transmitting sensitive data. Use TLS to encrypt your WebSocket connections if operating over public networks.

With these guidelines, you can efficiently use the MginDB Ruby client to interact with your MginDB database instance through a clean and powerful API.


Using MginDB with the PHP Client

The mgindb.php file provides a robust PHP interface to interact programmatically with MginDB via WebSockets.
This client handles connection management, authentication, and command execution synchronously, allowing you to focus on interacting with your data.

Setup and Installation

Ensure you have a suitable WebSocket client library installed to use the PHP client. For example, if using TextWebSocketClient, you might need to install it via Composer:

composer require your-vendor/text-websocket-client

Include the MginDBClient from mgindb.php in your PHP script to start:

require 'path/to/mgindb.php';
Use namespaces appropriately if they are defined within your library.

Authentication and Connection

Initialize the client with your server details and credentials. The client will handle the WebSocket connection and authenticate automatically when you send the first command:

$client = new MginDBClient('ws/wss', '127.0.0.1', 6446, 'your_username', 'your_password');

Example Usage

Below is an example demonstrating how to perform various operations with the MginDB client:

<?php
require 'path/to/mgindb.php';

$client = new MginDBClient('ws/wss', '127.0.0.1', 6446, 'admin', 'password');

// Set a value
$response = $client->set('key:subkey', 'value1');
echo "Response: $response\n";

// Query a value
$response = $client->query('key:subkey');
echo "Response: $response\n";

// Query with criteria
$response = $client->query('key:subkey', 'criteria > int AND criteria = "string"');
echo "Response: $response\n";

// Query with exclusions
$response = $client->query('key', '', 'EXCLUDE(password)');
echo "Response: $response\n";

// Query with ordering and grouping
$response = $client->query('key:subkey', 'criteria > int AND criteria = "string"', 'ORDERBY(key,DESC) GROUPBY(key)');
echo "Response: $response\n";

// Increment a counter
$response = $client->incr('key', 1);
echo "Response: $response\n";

// Decrement a counter
$response = $client->decr('key', 1);
echo "Response: $response\n";

// Delete a key
$response = $client->delete('key:subkey');
echo "Response: $response\n";

// Manage indices
$response = $client->indices('LIST');
echo "Response: $response\n";
$response = $client->indices('GET', 'ALL');
echo "Response: $response\n";
$response = $client->indices('GET', 'key:subkey');
echo "Response: $response\n";
$response = $client->indices('CREATE', 'key:subkey', 'type');
echo "Response: $response\n";
$response = $client->indices('DEL', 'key:subkey', 'value');
echo "Response: $response\n";
$response = $client->indices('COUNT', 'key:subkey');
echo "Count: $response\n";
$response = $client->indices('FLUSH', 'key:subkey');
echo "Response: $response\n";

// Manage schedules
$response = $client->schedule('SHOW ALL');
echo "Response: $response\n";
$response = $client->schedule('SHOW', '* * * * *');
echo "Response: $response\n";
$response = $client->schedule('SHOW', 'key/key:subkey');
echo "Response: $response\n";
$response = $client->schedule('ADD', '* * * * *', 'COMMAND(INCR key:subkey value)');
echo "Response: $response\n";
$response = $client->schedule('DEL', 'key/key:subkey');
echo "Response: $response\n";
$response = $client->schedule('FLUSH ALL');
echo "Response: $response\n";
$response = $client'schedule('FLUSH', '* * * * *');
echo "Response: $response\n";

// Subscribe / Unsubscribe to a key
$response = $client->sub('key:*/key:subkey:*');
echo "Response: $response\n";

$response = $client->unsub('key:*/key:subkey:*');
echo "Response: $response\n";

$client->close();
?>

Synchronous Handling

All client methods are synchronous and should be executed within standard PHP scripts or command-line interfaces. This ensures straightforward integration into existing PHP applications.

Security Note

Ensure your network connections are secure, especially when transmitting sensitive data. Consider using encrypted WebSocket connections (wss://) if operating over public networks.

With these guidelines, you can efficiently use the MginDB PHP client to interact with your MginDB database instance through a clean and powerful API.


Using WebSockets with MginDB

MginDB supports WebSocket connections for to send commands, real-time data updates and notifications. WebSocket provides a persistent, full-duplex communication channel over a single TCP connection, enabling efficient, bidirectional communication between the client and the server.

Connecting to MginDB via WebSocket

To initiate a WebSocket connection, connect to the server using the WebSocket URL: wss://your-mgindb-server.com or wss://your-mgindb-domain.com.

Once connected, you can send commands, subscribe to specific keys or patterns using the SUB command to receive real-time updates whenever the data changes. Similarly, you can unsubscribe using the UNSUB command.

Additionally, MginDB provides a SUB LIST command to list all active subscriptions, allowing you to manage and monitor your WebSocket connections effectively.

Python Example

Here's how you can use Python to connect and interact with MginDB via WebSockets:

import asyncio
import websockets

async def mgindb_client():
    uri = "wss://your-mgindb-server.com"
    async with websockets.connect(uri) as websocket:

    # Authenticate
    auth = {"username": "", "password": ""}
    await websocket.send(auth)
    auth_response = await websocket.recv()
    print(f"Auth Response: {auth_response}")

    # Send a command
    await websocket.send("SET key1 value1")
    response = await websocket.recv()
    print(f"Response: {response}")

    # Send a command
    await websocket.send("QUERY key LIMIT(5)")
    response = await websocket.recv()
    print(f"Response: {response}")

    # Send a command
    await websocket.send("QUERY key:subkey WHERE criteria = 'value'")
    response = await websocket.recv()
    print(f"Response: {response}")

    # Subscribe to a key
    await websocket.send("SUB key1")
    update = await websocket.recv()
    print(f"Update: {update}")

asyncio.run(mgindb_client())

JavaScript Example

Use the following JavaScript snippet to establish a WebSocket connection:

const socket = new WebSocket("wss://your-mgindb-server.com");

socket.onopen = function() {
    console.log("WebSocket connection established.");

    // Authenticate
    const auth = {"username": "", "password": ""}
    socket.send(auth);

    socket.onmessage = function(event) {
        console.log("Message from server", event.data);
    };
};

function sendCommand(command) {
    socket.send(command);
}

sendCommand("SET key1 value1");
sendCommand("QUERY key LIMIT(5)");
sendCommand("QUERY key:subkey WHERE criteria = 'value'");
sendCommand("SUB key1");

C# Example

Here's how you can use C# to connect and interact with MginDB via WebSockets:

using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        using (var client = new ClientWebSocket())
        {
            await client.ConnectAsync(new Uri("wss://your-mgindb-server.com"), CancellationToken.None);

            var auth = Encoding.UTF8.GetBytes("{\"username\": \"\", \"password\": \"\"}");
            await client.SendAsync(new ArraySegment(auth), WebSocketMessageType.Text, true, CancellationToken.None);
            var authResponse = await ReceiveMessage(client);
            Console.WriteLine($"Auth Response: {authResponse}");

            await SendMessage(client, "SET key1 value1");
            var response = await ReceiveMessage(client);
            Console.WriteLine($"Response: {response}");

            await SendMessage(client, "QUERY key LIMIT(5)");
            response = await ReceiveMessage(client);
            Console.WriteLine($"Response: {response}");

            await SendMessage(client, "QUERY key:subkey WHERE criteria = 'value'");
            response = await ReceiveMessage(client);
            Console.WriteLine($"Response: {response}");

            await SendMessage(client, "SUB key1");
            var update = await ReceiveMessage(client);
            Console.WriteLine($"Update: {update}");
        }
    }

    static async Task SendMessage(ClientWebSocket client, string message)
    {
        var bytes = Encoding.UTF8.GetBytes(message);
        await client.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Text, true, CancellationToken.None);
    }

    static async Task ReceiveMessage(ClientWebSocket client)
    {
        var buffer = new byte[1024];
        var result = await client.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None);
        return Encoding.UTF8.GetString(buffer, 0, result.Count);
    }
}

Go Example

Here's how you can use Go to connect and interact with MginDB via WebSockets:

package main

import (
    "fmt"
    "log"
    "github.com/gorilla/websocket"
)

func main() {
    conn, _, err := websocket.DefaultDialer.Dial("wss://your-mgindb-server.com", nil)
    if err != nil {
        log.Fatal("Dial error:", err)
    }
    defer conn.Close()

    auth := `{"username": "", "password": ""}`
    err = conn.WriteMessage(websocket.TextMessage, []byte(auth))
    if err != nil {
        log.Fatal("Auth send error:", err)
    }
    _, authResponse, err := conn.ReadMessage()
    if err != nil {
        log.Fatal("Auth receive error:", err)
    }
    fmt.Printf("Auth Response: %s\n", authResponse)

    sendAndReceive(conn, "SET key1 value1")
    sendAndReceive(conn, "QUERY key LIMIT(5)")
    sendAndReceive(conn, "QUERY key:subkey WHERE criteria = 'value'")
    sendAndReceive(conn, "SUB key1")
}

func sendAndReceive(conn *websocket.Conn, message string) {
    err := conn.WriteMessage(websocket.TextMessage, []byte(message))
    if err != nil {
        log.Fatal("Send error:", err)
    }
    _, response, err := conn.ReadMessage()
    if err != nil {
        log.Fatal("Receive error:", err)
    }
    fmt.Printf("Response: %s\n", response)
}

Swift Example

Here's how you can use Swift to connect and interact with MginDB via WebSockets:

import Foundation
import Starscream

class MginDBClient: WebSocketDelegate {
    var socket: WebSocket!

    init() {
        var request = URLRequest(url: URL(string: "wss://your-mgindb-server.com")!)
        socket = WebSocket(request: request)
        socket.delegate = self
        socket.connect()
    }

    func didReceive(event: WebSocketEvent, client: WebSocket) {
        switch event {
            case .connected(_):
            authenticate()
            case .text(let string):
            print("Response: \(string)")
            default:
            break
        }
    }

    func authenticate() {
        let auth = "{\"username\": \"\", \"password\": \"\"}"
        socket.write(string: auth)
    }

    func sendCommand(command: String) {
        socket.write(string: command)
    }
}

let client = MginDBClient()
RunLoop.main.run()

Rust Example

Here's how you can use Rust to connect and interact with MginDB via WebSockets:

use tokio_tungstenite::connect_async;
use tungstenite::protocol::Message;
use futures_util::{SinkExt, StreamExt};

#[tokio::main]
async fn main() {
    let url = url::Url::parse("wss://your-mgindb-server.com").unwrap();
    let (mut ws_stream, _) = connect_async(url).await.expect("Failed to connect");

    let auth = r#"{"username": "", "password": ""}"#;
    ws_stream.send(Message::Text(auth.into())).await.unwrap();

    if let Some(Ok(Message::Text(auth_response))) = ws_stream.next().await {
        println!("Auth Response: {}", auth_response);
    }

    send_and_receive(&mut ws_stream, "SET key1 value1").await;
    send_and_receive(&mut ws_stream, "QUERY key LIMIT(5)").await;
    send_and_receive(&mut ws_stream, "QUERY key:subkey WHERE criteria = 'value'").await;
    send_and_receive(&mut ws_stream, "SUB key1").await;
}

async fn send_and_receive(ws_stream: &mut (impl StreamExt + SinkExt + Unpin), message: &str) {
    ws_stream.send(Message::Text(message.into())).await.unwrap();
    if let Some(Ok(Message::Text(response))) = ws_stream.next().await {
        println!("Response: {}", response);
    }
}

Ruby Example

Here's how you can use Ruby to connect and interact with MginDB via WebSockets:

require 'faye/websocket'
require 'eventmachine'
require 'json'

EM.run do
ws = Faye::WebSocket::Client.new('wss://your-mgindb-server.com')

ws.on :open do |event|
auth = {username: '', password: ''}.to_json
ws.send(auth)
end

ws.on :message do |event|
puts "Response: #{event.data}"
end

ws.on :open do |event|
commands = ["SET key1 value1", "QUERY key LIMIT(5)", "QUERY key:subkey WHERE criteria = 'value'", "SUB key1"]
commands.each { |cmd| ws.send(cmd) }
end
end

PHP Example

Here's how you can use PHP to connect and interact with MginDB via WebSockets:

<?php
require 'vendor/autoload.php';

use Ratchet\Client\WebSocket;
use Ratchet\Client\connect;

$loop = \React\EventLoop\Factory::create();

connect('wss://your-mgindb-server.com', [], [], $loop)->then(function(WebSocket $conn) {
$auth = json_encode(['username' => '', 'password' => '']);
$conn->send($auth);

$conn->on('message', function($msg) use ($conn) {
echo "Response: {$msg}\n";
});

$commands = ["SET key1 value1", "QUERY key LIMIT(5)", "QUERY key:subkey WHERE criteria = 'value'", "SUB key1"];
foreach ($commands as $command) {
$conn->send($command);
}

}, function(\Exception $e) use ($loop) {
echo "Could not connect: {$e->getMessage()}\n";
$loop->stop();
});

$loop->run();
?>

Authentication

Authentication for accessing the MginDB server or WebSocket is optional but recommended for securing your data and resources.
You can set up a username and password to authenticate your connections.

To authenticate with MginDB WebSocket, provide your credentials in the first message sent after connecting:
{"username": "your_username", "password": "your_password"}

If authentication is enabled, MginDB will verify the provided credentials before establishing the connection. Ensure that you use secure and strong passwords to protect your data.

Note: Setting a username and password is not mandatory but highly recommended for enhanced security and access control.

To set your username and password in the MginDB configuration, use the following commands:
CONFIG SET USERNAME your_username
CONFIG SET PASSWORD your_password
Make sure to replace your_username and your_password with your desired credentials.

When just installed, you can edit the configuration file config.json to set up your initial authentication credentials.


Caching

Caching is an essential feature for improving the performance and efficiency of your database by storing frequently accessed data in memory.
Below are the commands to manage caching in the system:

Flushing the Cache: To clear all entries in the cache, use the following command:
FLUSHCACHE
This command removes all cached queries, ensuring that subsequent queries fetch fresh data from the database.

Managing Cache Entries:
Cache entries are automatically managed based on their time-to-live (TTL) setting. Expired entries are removed to ensure that the cache stays up-to-date and efficient.

Caching helps in reducing the load on the database by serving frequently accessed data from memory, thereby improving the overall performance and responsiveness of the system.


Replication

Replication is a crucial feature in database management, enabling the creation of redundant copies of data across multiple servers. This redundancy enhances data availability, fault tolerance, and load distribution. Below are the commands to manage replication in the system:

Adding a Replication Slave: To add a new server as a replication slave, use the following command:
CONFIG SET REPLICATION_SLAVES ADD serverip/domain
This command designates serverip/domain as a replication slave, ensuring it receives replicated data from the master server.

Removing a Replication Slave: To remove an existing replication slave, execute the command:
CONFIG SET REPLICATION_SLAVES DEL serverip/domain
This removes serverip/domain from the list of replication slaves, halting data replication to that server.

Starting Replication: Once configured, replication starts automatically. The replication server connects to the master to synchronize existing data, ensuring an up-to-date copy before commencing replication commands.

Replication Operation: With replication active, any write operations (inserts, updates, deletes) performed on the master are automatically propagated to all replication slaves, keeping the data consistent across all servers.

Deactivating Replication: To halt replication temporarily or permanently, set REPLICATION to 0 in the configuration. This stops the replication process, and servers revert to operating independently.

Replication is fundamental for maintaining data integrity, scalability, and disaster recovery readiness. By distributing data across multiple servers, it ensures resilience and reliability, even in the face of hardware failures or network issues.


Sharding

Sharding is a database architecture pattern that partitions data across multiple servers, enhancing the system's scalability and performance.
Below are the commands to manage shards in the system:

Adding a Shard: To add a new server to the shard list, use the following command:
CONFIG SET SHARDS ADD serverip/domain
This command registers serverip/domain as a new shard where data can be distributed.

Removing a Shard: To remove an existing server from the shard list, use the command:
CONFIG SET SHARDS DEL serverip/domain
This removes serverip/domain from the list of shards, redistributing any data it held to remaining shards.

Activating Sharding: To activate sharding and start distributing data across the configured shards, execute:
CONFIG SET SHARDING 1
Ensure you add the necessary shards before activating sharding to distribute data evenly.

Deactivating Sharding: To deactivate sharding and consolidate all data back to the master server, use:
CONFIG SET SHARDING 0
This command centralizes the data, ceasing its distribution among shards.

Backup and Rollback: When sharding is activated or deactivated, data is always backed up before resharding.
If an error occurs during the sharding process, it automatically rolls back to the last backup before the operation, ensuring data integrity and minimizing risks.

Sharding Batch Size: It's the size of commands sent to shards per batch (default: 100).
CONFIG SET SHARDING_BATCH_SIZE value
This command sets the size of commands sent to shards per batch, influencing the efficiency of data distribution.

Each of those commands need to be executed for each server where MginDB is installed using the Web CLI client.html or Server CLI mgindb client

These settings plays a crucial role in managing the distribution of data and the operational scale of your system, allowing for flexibility in handling workload and data management strategies.


CONFIG Command

CONFIG SET key value - Sets a configuration key to a value
CONFIG DEL key - Deletes a configuration key
CONFIG SHOW - Displays the current configuration
CONFIG SET REPLICATION_AUTHORIZED_SLAVES ADD slave1 - Adds slave1 to the list of authorized replication slaves.
CONFIG SET REPLICATION_AUTHORIZED_SLAVES DEL slave2 - Removes slave2 from the list of authorized replication slaves.
CONFIG SET SHARDS ADD server1 - Adds server1 to the list of shards.
CONFIG SET SHARDS DEL server2 - Removes server2 from the list of shards.
CONFIG SET SHARDING 1 - Activates sharding and dispatches data across shards (add shards first before activating).
CONFIG SET SHARDING 0 - Deactivates sharding and centralizes data on the master server.

BACKUP Commands

BACKUP - Backs up data
BACKUP LIST - Lists available backups
BACKUP DEL filename - Deletes a backup file
BACKUP DEL ALL - Deletes all backup files
BACKUP RESTORE filename - Restores data from a backup file

SET Commands

Basic Commands

SET key value - Sets a key to a value
SET key:subkey value - Sets a subkey to a value
SET key json - Sets a key to a JSON string
SET key:subkey json - Sets a subkey to a JSON string
SET key:*:subkey value - Sets all subkeys matching the wildcard to a value

Encryption and Hashing

SET key BASE64('value') - Sets a key to a Base64 encoded value
SET key HASH('value') - Sets a key to a hashed value
SET key MD5('value') - Sets a key to an MD5 hashed value
SET key CHECKSUM(algo,value) - Sets a key to a checksum value (Algo: CRC32, SHA1, SHA256)
Replace value by %key to use dynamic keys in your dataset. SET key BASE64(%password)
Combine functions: SET key BASE64(RANDOM(16))

Other Functionalities

SET key RANDOM(length) - Sets a key to a random string with length
SET key TIMESTAMP(option) - Sets a key to a timestamp (Options: full, unix, date, time)
SET key UPPER('value') - Sets a key to the uppercase value of input
SET key UPPER(%key) - Sets a key to the uppercase value of an existing key
SET key LOWER('value') - Sets a key to the lowercase value of input
SET key LOWER(%key) - Sets a key to the lowercase value of of an existing key
SET key ROUND(value,precision) - Sets a key to a rounded float value
SET key ROUND(%key,precision) - Sets a key to a rounded float value
SET key DECIMAL(value,decimal_places) - Sets a key to a decimal float value
SET key DECIMAL(%key,decimal_places) - Sets a key to a decimal float value
SET key UUID() - Sets a key to a UUID value
SET key value EXPIRE(seconds) - Sets a key to a value with an expiration in seconds

RENAME Commands

RENAME old_key TO new_key - Renames an existing key to a new key name
RENAME old_key:*:subkey TO new_key - Renames all subkeys matching the wildcard under an old key to a new key

DEL Commands

DEL key - Deletes a key
DEL key:subkey - Deletes a subkey for a key
DEL key:subkey:subkey - Deletes a nested subkey under a subkey for a key
DEL key:*:subkey - Deletes all subkeys matching the wildcard for a sub key

INCR/DECR Commands

INCR/DECR key int/float - Increments or decrements a key by an integer or float value
INCR/DECR key:subkey int/float - Increments or decrements a subkey by an integer or float value

COUNT Command

COUNT key - Returns the number of entries for a key
COUNT key:subkey - Returns the number of entries for a sub key
COUNT key WHERE criteria = 'value' - Returns the number of entries for a key with conditions
COUNT key:subkey WHERE criteria >= int/float - Returns the number of entries for a key with conditions

INDICES Commands

Structure example

{
  "users": {
    "user_id": {
      "type": "string",
      "values": {
        "1": "users:1",
        "2": "users:2",
        "3": "users:3",
        "4": "users:4",
        "5": "users:5",
        "6": "users:6",
        "7": "users:7"
      }
    },
    "age": {
      "type": "set",
      "values": {
        "18": [
          "users:7"
        ],
        "25": [
          "users:2",
          "users:3"
        ],
        "28": [
          "users:4"
        ],
        "30": [
          "users:1"
        ],
        "35": [
          "users:5"
        ],
        "59": [
          "users:6"
        ]
      }
    },
    "email": {
      "type": "string",
      "values": {
        "john.doe@example.com": "users:1",
        "jane.smith@example.com": "users:2",
        "marco.bianchi@example.it": "users:3",
        "lisa.muller@example.de": "users:4",
        "carlos.garcia@example.es": "users:5",
        "pablo.escobar@example.co": "users:6",
        "tom.felton@example.uk": "users:7"
      }
    },
    "country": {
      "type": "set",
      "values": {
        "USA": [
          "users:1"
        ],
        "FR": [
          "users:2"
        ],
        "IT": [
          "users:3"
        ],
        "DE": [
          "users:4"
        ],
        "ES": [
          "users:5"
        ],
        "CO": [
          "users:6"
        ],
        "UK": [
          "users:7"
        ]
      }
    }
  },
  "orders": {
    "order_id": {
      "type": "string",
      "values": {
        "O-001": "orders:O-001",
        "O-002": "orders:O-002",
        "O-003": "orders:O-003",
        "O-004": "orders:O-004",
        "O-005": "orders:O-005",
        "O-006": "orders:O-006",
        "O-007": "orders:O-007",
        "O-008": "orders:O-008",
        "O-009": "orders:O-009"
      }
    },
    "product_id": {
      "type": "set",
      "values": {
        "101": [
          "orders:O-001",
          "orders:O-005"
        ],
        "102": [
          "orders:O-001",
          "orders:O-006"
        ],
        "103": [
          "orders:O-002",
          "orders:O-006"
        ],
        "104": [
          "orders:O-003"
        ],
        "105": [
          "orders:O-004",
          "orders:O-005",
          "orders:O-006",
          "orders:O-007",
          "orders:O-008",
          "orders:O-009"
        ]
      }
    },
    "user_id": {
      "type": "set",
      "values": {
        "1": [
          "orders:O-001",
          "orders:O-002"
        ],
        "2": [
          "orders:O-003"
        ],
        "3": [
          "orders:O-007"
        ],
        "4": [
          "orders:O-004"
        ],
        "5": [
          "orders:O-005",
          "orders:O-006"
        ],
        "6": [
          "orders:O-008",
          "orders:O-009"
        ]
      }
    }
  },
  "products": {
    "product_id": {
      "type": "string",
      "values": {
        "101": "products:101",
        "102": "products:102",
        "103": "products:103",
        "104": "products:104",
        "105": "products:105",
        "106": "products:106"
      }
    }
  }
}

LIST

INDICES LIST - Returns a list of all index keys

CREATE

To leverage the indexing capabilities of MginDB, it is essential to explicitly define indices for keys or subkeys. Once an index is created, MginDB automatically manages the association, updating, and deletion of indexed data in response to SET, DEL, INCR/DECR, RENAME, and other data-modifying commands. This ensures that your queries can execute efficiently using these indices.

Usage

The INDICES CREATE command is used to define an index for a specific key or subkey within the database. This command supports two types of indices: string and set. A string type index is suitable for unique identifiers or values where each entry is unique. A set type index is used where the key might have multiple values (non-unique).

Create a String Index

INDICES CREATE key string - Creates an index for a key where each key holds a unique string value.

Create a Set Index

INDICES CREATE key set - Creates an index for a key where each key can hold multiple values.

Create a String Index for a Subkey

INDICES CREATE key:subkey string - Creates an index for a subkey under a main key where each subkey holds a unique string value.

Create a Set Index for a Subkey

INDICES CREATE key:subkey set - Creates an index for a subkey under a main key where each subkey can hold multiple values.

Example

Let's say that you have a table users and you want to index user_id, email and status for faster retrieval and joined operations.
You will create an index users where you will have user_id as a string, email as a string and status as a set. If status is 0 or 1 or 2 it will put users in the appropriate set based on their value.

INDICES CREATE users:user_id string
INDICES CREATE users:email string
INDICES CREATE users:status set

GET

INDICES GET ALL - Get all indexes
INDICES GET key - Get an index for a specific key
INDICES GET key:subkey - Get an index for a subkey under a key
INDICES GET key:subkey:subkey - Get an index for a nested subkey under a key

DEL

INDICES DEL key value - Deletes the specified value from the index associated with a key
INDICES DEL key:subkey value - Deletes the specified value from the index associated with a subkey under a key

FLUSH

INDICES FLUSH key - Flushes data associated with the key
INDICES FLUSH key:subkey - Flushes data associated with a subkey under a key

QUERY Commands

Basic Queries

QUERY key WHERE criteria = 'value' - Retrieves data based on criteria
QUERY key:subkey WHERE criteria = 'value' - Retrieves data based on criteria for a subkey

Advanced Queries

QUERY key WHERE criteria LIKE 'value' - Retrieves data where criteria contains value
QUERY key WHERE criteria = 'value' OR criteria = 'value' - Retrieves data where criteria matches any of the provided values
QUERY key WHERE criteria >= value AND criteria < value - Retrieves data where criteria is between two values
QUERY key WHERE criteria BETWEEN value1,value2 - Retrieves data where criteria is between two values
QUERY key WHERE criteria BETWEEN value1,value2 AND criteria = 'value' - Retrieves data where criteria is between two values and matches additional criteria
QUERY key WHERE criteria >= value GROUPBY(country) - Retrieves data where criteria is greater than or equal to value and groups by country
QUERY key WHERE criteria >= value AND age < value ORDERBY(criteria,DESC) - Retrieves data where criteria is between two values, ordered by criteria in descending order
QUERY key WHERE criteria >= value AND age < value ORDERBY(criteria,ASC) LIMIT(1,3) - Retrieves data where criteria is between two values, ordered by criteria in ascending order, with limit and offset
QUERY key WHERE criteria >= value JOIN(key,relational_key) - Retrieves data where criteria is greater than or equal to value and joins with another key using a relational key

Join Queries (with indices)

QUERY key join(key,relational_key) - Retrieves all data for a key and joins with another key using a relational key
QUERY key WHERE criteria >= value JOIN(key,relational_key) - Retrieves data where criteria is greater than or equal to value and joins with another key using a relational key

Deep Nested Queries (with indices)

QUERY key WHERE details:country = 'USA' - Retrieves all data for a key using deep nested criteria
QUERY key WHERE details:orders:amount >= value - Retrieves all data for a key using deep nested criteria using sub key of a key

SCHEDULE Commands

Use Cron Guru for cron schedule expressions.

SHOW

SCHEDULE SHOW ALL - Displays all scheduled commands.
SCHEDULE SHOW * * * * * - Displays all scheduled commands for the specified time.
SCHEDULE SHOW key - Displays all scheduled commands for the specified key.
SCHEDULE SHOW key:subkey - Displays all scheduled commands for the specified subkey within a key.
SCHEDULE SHOW key:subkey:subkey - Displays all scheduled commands for the specified subkey within a subkey of a key.

ADD

SCHEDULE ADD * * * * * COMMAND(SET key value) - Adds a scheduling command to set the specified key to the given value.
SCHEDULE ADD * * * * * COMMAND(SET key:subkey value) - Adds a scheduling command to set the specified subkey within a key to the given value.
SCHEDULE ADD * * * * * COMMAND(SET key:subkey:subkey value) - Adds a scheduling command to set the specified subkey within a subkey of a key to the given value.
SCHEDULE ADD * * * * * COMMAND(INCR key value) - Adds a scheduling command to increment the specified key by the given value.
SCHEDULE ADD * * * * * COMMAND(DECR key:subkey value) - Adds a scheduling command to decrement the specified subkey within a key by the given value.
SCHEDULE ADD * * * * * COMMAND(INCR key:subkey:subkey value) - Adds a scheduling command to increment the specified subkey within a subkey of a key by the given value.

DEL

SCHEDULE DEL key - Deletes a scheduled command for a specific key.
SCHEDULE DEL key:subkey - Deletes a scheduled command for a specific subkey within a key.
SCHEDULE key:subkey:subkey - Deletes a scheduled command for a specific subkey within a subkey of a key.

FLUSH

SCHEDULE FLUSH ALL - Flushes all scheduled commands.
SCHEDULE FLUSH * * * * * - Flushes all scheduled commands for the specified time.

INCLUDE/EXCLUDE Commands

QUERY key INCLUDE(last_name,first_name,age) - Includes specified fields in query results
QUERY key:subkey INCLUDE(last_name,first_name,age) - Includes specified fields in subkey query results
QUERY key:subkey INCLUDE(last_name,first_name,age,details:key:subkey) - Includes specified fields and nested fields query results
QUERY key:subkey INCLUDE(last_name,first_name,age,details:*:subkey) - Includes specified fields and wildcard nested fields query results
QUERY key EXCLUDE(password,uuid) - Excludes specified fields from query results
QUERY key:subkey EXCLUDE(password,uuid) - Excludes specified fields from subkey query results
QUERY key:subkey EXCLUDE(last_name,first_name,age,details:key:subkey) - Excludes specified fields and nested fields query results
QUERY key:subkey EXCLUDE(last_name,first_name,age,details:*:subkey) - Excludes specified fields and wildcard nested fields query results

SUB/PUB Commands

SUB MONITOR - Subscribes to all commands
SUB key:* - Subscribes to all keys matching a pattern
SUB key:subkey - Subscribes to a subkey
SUB key:subkey:* - Subscribes to all subkeys matching a pattern
UNSUB key:* - Unsubscribes from all keys matching a pattern
UNSUB key:subkey - Unsubscribes from a subkey
UNSUB key:subkey:* - Unsubscribes from all subkeys matching a pattern
SUBLIST - Lists all active subscriptions

Batching (pipe "|" as separator)

SET key value|key value|key value - Sets keys to a value for a
SET key:subkey value|key:subkey value|key:subkey value - Sets subkeys to a value in for a batch
INCR/DECR key int/float|key int/float - Increments or decrements keys by an integer or float value for a batch
INCR/DECR key:subkey int/float|key:subkey int/float - Increments or decrements subkeys by an integer or float value for a batch
DEL key|key|key - Deletes keys for a batch
DEL key:subkey|key:subkey - Deletes sub keys for a key for a batch
DEL key:subkey:subkey|key:subkey:subkey - Deletes nested subkeys under a sub key for a key for a batch

Examples

SET Examples:
SET user:1:info {"name": "Alice", "age": 25, "email": "alice@example.com"}
SET user:2:info {"name": "Bob", "age": 30, "email": "bob@example.com"}
SET products:101:product_id 101
SET products:101:details {"name": "Laptop", "price": 999.99, "category": "Electronics"}
SET orders:O-JD493SA:ref O-JD493SA LINKTO(orders:%user_id,ref) Links user_id to ref for indices to join queries
SET orders:O-JD493SA:product_id 101 LINKTO(orders:%ref,product_id) Links ref to product id for indices to joint queries

INCR/DECR Examples:
INCR user:1:age 1
INCR user:2:age 1
DECR product:101:inventory_count 5

QUERY Examples:
QUERY users WHERE age >= 25 AND age < 35
QUERY products WHERE category = 'Electronics'
QUERY users WHERE age BETWEEN 20,30 AND city = 'New York'

SCHEDULE Examples:
SCHEDULE ADD * * * * * COMMAND(INCR users:3:points 5)
SCHEDULE ADD * * * * * COMMAND(INCR users:99:balance 1)
SCHEDULE ADD 0 0 * * * COMMAND(INCR users:3:points 10)

INCLUDE/EXCLUDE Examples:
QUERY users INCLUDE(name,email)
QUERY users:1 INCLUDE(name,email)
QUERY users EXCLUDE(password,phone_number)
QUERY users:2 EXCLUDE(password,phone_number)

SUB/PUB Examples:
SUB users:*
SUB users:orders
UNSUB users:*
UNSUB users:orders