Programming language access

This document describes how to connect to YMatrix and query using the programming language. Two ways of high availability and non-high availability connection will be given.

High availability refers to YMatrix's [automatic fault transfer mechanism] (/doc/5.2/maintain/crash_recover). After the master node (Master) fails, the master node standby node (Standby) provides services to the outside.

High Availability Connection refer to the program automatically connecting to the node after the failover after YMatrix fails.

High Available Connection Strings (Connection URLs/DSN) provides a standardized format that can be used in different applications without re-entering the complete connection information. It usually consists of multiple fields, each representing different connection information, for example: postgres://username:password@master_ip:master_port,standby_ip:standby_port/database?sslmode=disable

in:

  • username and password are the username and password for logging in to the database, respectively.
  • master_ip:master_port and standby_ip:standby_port are the connection information for Master and Standby.
  • database represents the name of the database to be connected.
  • sslmode indicates whether SSL connection is enabled.

Notes!
YMatrix supports high-speed writing of data through the MatrixGate API interface. For details, see Programming Language Write MatrixGate.


Create sample user ymatrix with password 1234.

=# CREATE USER ymatrix PASSWORD '1234';
  • Master IP: 172.16.100.81; Port: 5432
  • Standby IP: 172.16.100.82; Port: 5432
  • Database: ymatrixdb


1 JAVA (High Availability)

It is recommended to use the official driver PostgreSQL JDBC Driver as the database connection driver.

package com.postgresqltutorial;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class App{
    private final String url = "jdbc:postgres://ymatrix:[email protected]:5432,172.16.100.82:5432/ymatrixdb?sslmode=disable";
    private final String user = "ymatrix";
    private final String password = "1234";
    /**
     * Connect to the YMatrix database
     *
     * @return a Connection object
     */
    public Connection connect() {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, user, password);
            System.out.println("Connected to the YMatrix server successfully.");
        } catch (SQLException e) {
            System.out.println(e.getMessage());
        }
        return conn;
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        App app = new App();
        app.connect();
    }
}


2 Python (high availability)

It is recommended to use psycopg 2/3 as the database connection driver.

# -*- coding: utf-8 -*-
import psycopg2

class YMatrix(object):
    def __init__(self):
        self.dsn = "postgres://ymatrix:[email protected]:5432,172.16.100.82:5432/ymatrixdb?sslmode=disable"

    def get_conn(self):
        conn = psycopg2.connect(dsn=self.dsn)
        return conn

    def create_table(self):
        conn = self.get_conn()
        cursor = conn.cursor()
        sql = "CREATE TABLE data(" \
              "time timestamp," \
              "tag_id int," \
              "metrics1 float8," \
              "metrics2 float8," \
              "metrics3 float8" \
              ")USING MARS3" \
              "DISTRIBUTED BY (tag_id)" \
              "ORDER BY (tag_id)"
        cursor.execute(sql)
        conn.commit()
        conn.close()

    def insert(self):
        conn = self.get_conn()
        cursor = conn.cursor()
        sql = "INSERT INTO data VALUES(now(), 1, 1.1, 1.2, 1.3)"
        cursor.execute(sql)
        conn.commit()
        conn.close()

    def select(self):
        conn = self.get_conn()
        cursor = conn.cursor()
        sql = "SELECT * FROM data"
        cursor.execute(sql)
        data = cursor.fetchone()
        conn.commit()
        conn.close()
        return data

if __name__ == '__main__':
    mxdb = YMatrix()
    mxdb.create_table()
    mxdb.insert()
    print(mxdb.select())


3 Golang (high availability)

It is recommended to use pgx as the database connection driver.

package main

import (
    "context"
    "fmt"
    "github.com/jackc/pgx/v4"
)

func main() {
    // Build connection configuration
    dsn := "postgres://ymatrix:<password>@172.16.100.81:5432,172.16.100.82:5432/ymatrixdb?sslmode=disable"
    config, err := pgx.ParseConfig(dsn)
    if err != nil {
        fmt.Println("Unable to parse config:", err)
        return
    }
    // Connect to the database
    conn, err := pgx.ConnectConfig(context.Background(), config)
    if err != nil {
        fmt.Println("Unable to connect to database:", err)
        return
    }
    defer conn.Close(context.Background())
}


4 Ruby (High Availability)

Ruby 3.3.3 or above is recommended.

4.1 Driver Installation

It is recommended to use ruby-pg as the database connection driver.

gem install pg -v 1.3.5 -- --with-pg-config=/opt/ymatrix/matrixdb5/bin/pg_config
Fetching pg-1.3.5.gem
Building native extensions with: '--with-pg-config=/opt/ymatrix/matrixdb5/bin/pg_config'
This could take a while...
Successfully installed pg-1.3.5
Parsing documentation for pg-1.3.5
Installing ri documentation for pg-1.3.5
Done installing documentation for pg after 1 seconds
1 gem installed

4.2 Programming

require 'pg'
# Build connection configuration
dsn = "postgres://ymatrix:[email protected]:5432,172.16.100.82:5432/ymatrixdb?sslmode=disable"
conn = PG.connect(dsn)
# Perform database operations
begin
  conn.exec('SELECT * FROM table_name') do |result|
    result.each do |row|
      # Process each row of data
      puts row.inspect
    end
  end
rescue PG::Error => e
  puts "执行数据库操作时发生错误:#{e.message}"
ensure
  # Close the database connection
  conn.close if conn
end


5 Rust (high availability)

It is recommended to use rust-postgres as the database connection driver.

use postgres::{Client, Error, NoTls};
fn main() -> Result<(), Error> {
    let mut client = Client::connect(
        "postgresql://ymatrix:[email protected]:5432,172.16.100.82:5432/ymatrixdb",
        NoTls,
    )?;
    for row in client.query("SELECT * FROM table_name", &[])? {
        let id: i32 = row.get(0);
        let name: String = row.get(1);
        println!("ID: {}, Name: {}", id, name);
        // Here you can perform the data processing operations you need
    }
    Ok(())
}


6 C# (High Availability)

It is recommended to use npgsql as the database connection driver.

C#
using System;
using Npgsql;
class Program
{
    static void Main()
    {
        // Configure high availability DSN
        var connectionString = "Host=sdw1, sdw2;Port=5432;Database=mydatabase;Username=myuser;Password=mypassword;Load Balance Hosts=true";
        // Create a database connection
        using var connection = new NpgsqlConnection(connectionString);
        try
        {
            // Open a database connection
            connection.Open();
            // Perform database operations
            using var command = new NpgsqlCommand("SELECT * FROM table_name", connection);
            using var reader = command.ExecuteReader();
            // Process query results
            while (reader.Read())
            {
                // Process each row of data
                var column1Value = reader.GetString(0);
                var column2Value = reader.GetInt32(1);
                Console.WriteLine($"{column1Value}, {column2Value}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An error occurred: {ex.Message}");
        }
    }
}


7 C/C++ (High Availability)

It is recommended to use ODBC as the database connection driver.

Notes!
All of the following commands need to be executed using the root user or through the sudo permissions.

Download and install ODBC.

# yum install -y unixODBC.x86_64
# yum install -y postgresql-odbc.x86_64

Edit ODBC related files.

# cat /usr/local/etc/odbcinst.ini
[PostgreSQL]
Description = ODBC for PostgreSQL
Driver      = /usr/lib/psqlodbcw.so
Setup       = /usr/lib/libodbcpsqlS.so
Driver64    = /usr/lib64/psqlodbcw.so
Setup64     = /usr/lib64/libodbcpsqlS.so
FileUsage = 1

# cat /usr/local/etc/odbc.ini
[pg]
Description = Test to pg
Driver = PostgreSQL
Database = test
// The content of "<>" needs to be replaced with the actual cluster information, and the "<>" symbol is removed
Servername = <Master,Standby>
UserName = mxadmin
Password = mxadmin
Port = <Master Port,Standby Port>
ReadOnly = 0

Edit C/C++ related files.

# cat test.c

#include <stdio.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>
#include <sqltypes.h>

int main()
{
    SQLHENV henv;
    SQLHDBC hdbc;
    SQLHSTMT hstmt;
    SQLRETURN ret;

    // Assign environment handles
    ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
    // Set environment properties
    ret = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
    // Assign a connection handle
    ret = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
    // Connect to the database
    ret = SQLConnect(hdbc, "pg", SQL_NTS, "mxadmin", SQL_NTS, "mxadmin", SQL_NTS);
    if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
    {
        printf("Connected to PostgreSQL database successfully.\n");

        // Create a table and replace <tablename> with actual information
        ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
        ret = SQLExecDirect(hstmt, "CREATE TABLE <tablename> (id int) USING MARS3 DISTRIBUTED BY (id) ORDER BY (id)", SQL_NTS);
        if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
        {
                printf("成功创建表<tablename>.\n");
        }
        // Disconnect the database
        SQLDisconnect(hdbc);
    }
    else
    {
        printf("Failed to connect to PostgreSQL database.\n");
    }
    // Release the handle
    SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
    SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
    SQLFreeHandle(SQL_HANDLE_ENV, henv);

    return 0;
}

Compile.

# gcc -lodbc -o test test.c

run.

# ./test
Connected to PostgreSQL database successfully.

Confirm that the table has been successfully created.

=#  \d <tablename>
              Table "public.test2"
 Column |  Type   | Collation | Nullable | Default
-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 id     | integer |           |          |
Distributed by: (id)


8 NodeJS (High Availability)

It is recommended to use the postgres module as the database connection driver.

const postgres = require('postgres')

async function query() {
  // Create a highly available database connection
  const conn = postgres(`postgres://username:password@master,stanby:port/database?sslmode=disable`)
  try {
    // Execute query SQL
    const rows = await conn`SELECT id, name FROM users`
    rows.forEach(row => {
      console.log(`id: ${row.id}, name: ${row.name}`)
    })
  } catch (err) {
    console.error(err)
  } finally {
    // Close the connection
    await conn.end()
  }
}

query()


9 PHP (High Availability)

PHP 7.4 or higher is recommended.

9.1 Driver Installation

It is recommended to use php-pgsql as the database connection driver.

# 1. Generate a configure file
[root@ymatrix] cd /root/php-7.4.9/ext/pgsql
[root@ymatrix] /usr/local/php74/bin/phpize

Configuring for:
PHP Api Version:         20190902
Zend Module Api No:      20190902
Zend Extension Api No:   320190902

# 2. Add environment variables, execute config, the configuration path must be the path of the target php version, and fill in the pgsql path to the software path of YMatrix
[root@ymatrix] ./configure --with-php-config=/usr/local/php74/bin/php-config --with-pgsql=/opt/ymatrix/matrixdb5/

# 3. Compile and install
[root@ymatrix] make & make install

Installing shared extensions:     /usr/local/php74/lib/php/extensions/no-debug-non-zts-20190902/

# 4. Check the installation results
[root@ymatrix] ls /usr/local/php74/lib/php/extensions/no-debug-non-zts-20190902/

pgsql.so

9.2 Install pdo_pgsql

# 1. Generate a configure file
[root@ymatrix] cd /root/php-7.4.9/ext/pdo_pgsql
[root@ymatrix] /usr/local/php74/bin/phpize

Configuring for:
PHP Api Version:         20190902
Zend Module Api No:      20190902
Zend Extension Api No:   320190902

# 2. Add environment variables, execute config, the configuration path must be the path of the target php version, and fill in the pgsql path to the software path of YMatrix
[root@ymatrix] ./configure --with-php-config=/usr/local/php74/bin/php-config --with-pgsql=/opt/ymatrix/matrixdb5/

# 3. Compile and install
[root@ymatrix] make & make install

Installing shared extensions:     /usr/local/php74/lib/php/extensions/no-debug-non-zts-20190902/

# 4. Check the installation results
[root@ymatrix] ls /usr/local/php74/lib/php/extensions/no-debug-non-zts-20190902/

pdo_pgsql.so  pgsql.so

9.3 Configure and restart php-fpm

[root@ymatrix] echo "extension=pgsql.so" >> /usr/local/php74/etc/php.ini
[root@ymatrix] echo "extension=pdo_pgsql.so" >> /usr/local/php74/etc/php.ini
[root@ymatrix] systemctl restart php-fpm

9.4 Programming

<?php
  $host    = "host=172.16.100.81,172.16.100.82";
  $port    = "port=5432";
  $dbname   = "dbname=postgres";
  $credentials = "user=mxadmin password=mxadmin";
  $db = pg_connect( "$host $port $dbname $credentials" );
  if(!$db){
   echo "Error : Unable to open database\n";
  } else {
   echo "Opened database successfully\n";
  }
  $sql =<<<EOF
   CREATE TABLE COMPANY
   (ID INT PRIMARY KEY   NOT NULL,
   NAME      TEXT  NOT NULL,
   AGE      INT   NOT NULL,
   ADDRESS    CHAR(50),
   SALARY     REAL);
EOF;
  $ret = pg_query($db, $sql);
  if(!$ret){
   echo pg_last_error($db);
  } else {
   echo "Table created successfully\n";
  }
  pg_close($db);
?>


10 Perl (high availability)

It is recommended to use Perl 5 version 5.40.0 or later.

10.1 Installing the Perl DBI module

# 1. Prepare the installation package
[root@ymatrix] wget http://search.cpan.org/CPAN/authors/id/T/TI/TIMB/DBI-1.625.tar.gz
[root@ymatrix] tar xvfz DBI-1.625.tar.gz
[root@ymatrix] cd DBI-1.625


# 2. Compile and install
[root@ymatrix] perl Makefile.PL
[root@ymatrix] make
[root@ymatrix] make install

10.2 Installing the DBD-Pg module

# 1. Prepare the installation package
[root@ymatrix] wget http://search.cpan.org/CPAN/authors/id/T/TU/TURNSTEP/DBD-Pg-2.19.3.tar.gz
[root@ymatrix] tar xvfz DBD-Pg-2.19.3.tar.gz
[root@ymatrix] cd DBD-Pg-2.19.3

# 2. Compile and install
# When prompted to enter major version number, type 12 and press Enter to continue
# When prompted to enter minor version number, type 0 and press Enter to continue
# When prompted to enter patch version number, type 0 and press Enter to continue
[root@ymatrix] export POSTGRES_HOME="/opt/ymatrix/matrixdb5/"
[root@ymatrix] perl Makefile.PL
[root@ymatrix] make
[root@ymatrix] make install

10.3 Programming

#!/usr/bin/perl

use DBI;
use strict;

my $driver   = "Pg";
my $database = "postgres";
my $dsn = "DBI:$driver:dbname=$database;host=172.16.100.107,172.16.100.108;port=5432";
my $userid = "mxadmin";
my $password = "mxadmin";
my $dbh = DBI->connect($dsn, $userid, $password, { RaiseError => 1 })
   or die $DBI::errstr;
print "Opened database successfully\n";

my $stmt = qq(CREATE TABLE COMPANY
      (ID INT PRIMARY KEY     NOT NULL,
      NAME           TEXT    NOT NULL,
      AGE            INT     NOT NULL,
      ADDRESS        CHAR(50),
      SALARY         REAL););
my $rv = $dbh->do($stmt);
if($rv < 0) {
   print $DBI::errstr;
} else {
   print "Table created successfully\n";
}
$dbh->disconnect();