当前位置:   article > 正文

征文连载丨MogDB企业应用之七种武器

mogdb软件架构

78730515c048a8e864c295dad2241eac.png

2022年8月4日至9月9日,墨天轮社区联合云和恩墨发起了首届「MogDB 主题征文活动」,邀请各位技术从业者学习、使用 MogDB 数据库,分享使用心得与实战案例,一起探索这款融合了众多创新特性的商业版企业级数据库。活动期间共有93篇稿件通过评审,主题涵盖数据库安装部署、主从搭建、工具测试、源码解析、新特性解读,以及备份恢复、迁移实践等,并由专家评选出一等奖1名、二等奖3名、三等奖5名。即日起,我们为大家连载获奖征文,本篇是一等奖获得者夏克的文章。

如今江湖上最卷的门派,非国产数据库莫属。各位大侠们往往把精力放在拼内功(内核/架构)、拼身法(性能)、拼拳脚(功能/兼容性)、拼江湖地位(生态/社区)。然而好像并不怎么重视兵(武)器(接口/驱动/API),当然,可能我是搞 C/C++ 出身,也许搞 JAVA 的兄弟并不会遇到这样的困惑,因为一套 JDBC 可以打遍天下。虽然市场占有率的头把交椅 JAVA 已经做了很多年,但随着各种开发语言的大行其道,现代企业的信息化系统中不太可能只使用单一的开发语言。因此闯荡江湖还是需要几把趁手的兵器!

本文以古龙先生的《七种武器》和武器的寓意作为类比,简单分析MogDB各种驱动的优势应用场景

f14b58e9cbdee8ea9eb8a6a7e571fead.png

七种武器分别是:长生剑——寓意“笑”;孔雀翎——寓意“自信”;碧玉刀——寓意“诚实”;多情环——寓意“仇恨”;霸王枪——寓意“勇气”;离别钩——寓意“团聚”;箱子——寓意“道”。

当然,《七种武器》与MogDB驱动的类比并非那么贴切,甚至有些牵强。如果各位大侠有不同见解欢迎留言评论,一起切磋MogDB的“道”。

长生剑/ psycopg

“天上白玉京,五楼十二城。仙人抚我顶,结发授长生。”

长生剑!江湖中最可怕的一把剑。他只有杀人,从没有人能杀死他!长生剑的讲的是“笑”——“无论多锋利的剑,也比不上那动人的一笑。一个人只要懂得利用自己的长处,根本不必用武功也一样能够将人击倒”。

“笑”对于每个人来说再简单不过了,是每个人都能利用的一件武器。和笑一样简单的开发语言那当属 Python 了。Python 是一种代表简单主义思想的语言,它编写的程序读起来就感觉像是在读英语段落一样流畅。它懂得利用自己的长处——化繁为简,可以玩 AI、大数据、做运维甚至非专业开发人员也可以熟练使用它,包括小朋友也可以拿它来进行逻辑思维的扩展。psycopg 这把“长生剑”用最简单的方式杀敌于无形。

功法

江湖上有一篇入门心法供各位参考使用《Python-psycopg访问postgres、openGauss、MogDB》(浏览器访问https://www.modb.pro/db/337465即可查阅)。

  • 安装

获取安装介质(浏览器访问https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/x86_openEuler/openGauss-3.0.0-openEuler-x86_64-Python.tar.gz下载)。

  1. $ tar -zxvf openGauss-3.0.0-openEuler-x86_64-Python.tar.gz
  2. # cp -r /home/postgres/psycopg2/ /usr/lib/python3.7/site-packages/
  3. # chmod -R 775 psycopg2/
  • 验证

  1. $ python3
  2. Python 3.7.9 (default, Jan 25 2022, 15:12:36)
  3. [GCC 7.3.0] on linux
  4. Type "help", "copyright", "credits" or "license" for more information.
  5. >>> import psycopg2
  6. >>> conn=psycopg2.connect(database="postgres",user="frank",password="frank@123",host="localhost",port=5432)
  7. >>> cur=conn.cursor()
  8. >>> cur.execute("CREATE TABLE student(id integer,name varchar,sex varchar);")
  9. >>> cur.execute("INSERT INTO student(id,name,sex) VALUES(%s,%s,%s)",(1,'Aspirin','M'))
  10. >>> cur.execute("INSERT INTO student(id,name,sex) VALUES(%s,%s,%s)",(2,'Taxol','F'))
  11. >>> cur.execute('SELECT * FROM student')
  12. >>> results=cur.fetchall()
  13. >>> print (results)
  14. [(1, 'Aspirin', 'M'), (2, 'Taxol', 'F')]
  15. >>> conn.commit()
  16. >>> cur.close()
  17. >>> conn.close()
  18. >>>

秘籍

继续修炼请参考官方文档(浏览器访问https://www.psycopg.org/即可查阅)。

7e6b6c26ad4f3332b54ffaedfb8371a0.png

江湖

能够完美的发挥自己的特长,胜过手中锋利的剑。有了 psycopg,MogDB 可以在很多领域大展拳脚,比如爬虫系统、运维系统、AI、数据分析甚至是日常办公。也可以让 MogDB 在很多非核心的企业应用中发挥关键作用,让 MogDB 更贴近普通人的舒适工作区。

孔雀翎/node-postgres

孔雀翎是早已不存在的暗器,高立向朋友秋凤梧借来孔雀翎,信心十足地杀了强敌,这才发现孔雀翎已丢失。而秋凤梧告诉他,孔雀翎早就没有了,他借给高立的只是“信心”——“真正的胜利,并不是你用武器争取的,一定要用你的信心。无论多可怕的武器,也比不上人的信心。”

前些年有这样一个梗,PHP 是“最好编程语言”,JavaScript 将“一统天下”。不说 PHP 了,单讲 JavaScript 的信心其实并非空穴来风,从前端开发中最能打的武器,到几行代码就可以写出 HTTP 的服务“后端”,再到“全栈”、“大前端”。在江湖的各个门派中都有 JS 的一席之地。而 node-postgres 正是作为 PostgreSQL 体系数据库的那把泰山之巅的“暗器”。

功法

  • 安装

$ npm install pg
  • 范例

  1. const { Client } = require('pg')
  2. const client = new Client()
  3. client.connect()
  4. client.query('SELECT version()::text as version', (err, res) => {
  5. console.log(err ? err.stack : res.rows[0].version)
  6. client.end()
  7. })
  • 验证

  1. PGUSER=frank \
  2. PGHOST=localhost \
  3. PGPASSWORD=frank@123 \
  4. PGDATABASE=postgres \
  5. PGPORT=15432 \
  6. node test.js

秘籍

上面的例子只是简单的范例,如果各位想继续修炼可以参考官方文档(浏览器访问https://node-postgres.com/即可查阅)。

4ed8a1fb22ad8f35b25e4881b2070523.png

江湖

如果你用nodejs开发小型网站系统,爬虫系统、或者微服务架构系统要是想使用一款数据库,那么MogDB也将会出现在你的备选方案中。而node-postgres就是MogDB心中的“孔雀翎”。

碧玉刀/libpqxx

段家的碧玉刀非但价值连城,而且故老相传,都说其中还藏着一个很大的秘密。无论谁只要能解开这秘密,他立刻就可能变成富可敌国的武林高手。

段家的碧玉刀非但价值连城,而且故老相传,都说其中还藏着一个很大的秘密。无论谁只要能解开这秘密,他立刻就可能变成富可敌国的武林高手。

功法

还是先推荐一篇江湖上的典籍《libpqxx (PostgreSQL C++ API)——使用简介》(浏览器访问https://www.modb.pro/db/434187即可查阅)。

  • 安装

  1. git clone https://github.com/jtv/libpqxx
  2. git checkout 6.4
  3. ./configure --disable-documentation
  4. make -j8
  5. make check -j 8
  6. make install
  • 范例

test.sql

  1. CREATE TABLE public.employee (
  2. id int4 NULL,
  3. "name" varchar(20) NULL,
  4. gender bpchar(2) NULL,
  5. birthday date NULL,
  6. email bpchar(10) NULL,
  7. remark varchar(50) NULL,
  8. salary int8 NULL
  9. );
  10. insert into employee (id,name,gender,birthday,email,remark,salary) values(1,'frank','男','2014-02-23','f@123.com','',1000);

main.cpp

  1. #include <iostream>
  2. #include <pqxx/pqxx>
  3. int main()
  4. {
  5. try
  6. {
  7. pqxx::connection C;
  8. std::cout << "Connected to " << C.dbname() << std::endl;
  9. pqxx::work W(C);
  10. pqxx::result R = W.exec("SELECT name FROM employee");
  11. std::cout << "Found " << R.size() << "employees:" << std::endl;
  12. for (auto row: R)
  13. std::cout << row[0].c_str() << std::endl;
  14. std::cout << "Doubling all employees' salaries..." << std::endl;
  15. W.exec("UPDATE employee SET salary = salary*2");
  16. std::cout << "Making changes definite: ";
  17. W.commit();
  18. std::cout << "OK." << std::endl;
  19. }
  20. catch (const std::exception &e)
  21. {
  22. std::cerr << e.what() << std::endl;
  23. return 1;
  24. }
  25. return 0;
  26. }

run.sh

  1. rm -rf a.out
  2. g++ main.cpp -lpqxx -lpq -L/home/frank/pgsql/lib
  3. export PGDATABASE=postgres
  4. export PGHOST=localhost
  5. export PGPORT=15432
  6. export PGUSER=frank
  7. export PGPASSWORD=frank@123
  8. psql -h localhost -p 15432 -d postgres -U frank -W 'frank@123' -f test.sql
  9. ./a.out
  • 编译

g++ main.cpp -lpqxx -lpq  -L/home/frank/pgsql/lib
  • 验证

  1. frank@DESKTOP-6NF3B9K:~/test/libpqxx$ sh run.sh
  2. psql: warning: extra command-line argument "frank@123" ignored
  3. Password:
  4. DROP TABLE
  5. CREATE TABLE
  6. INSERT 0 1
  7. Connected to postgres
  8. Found 1employees:
  9. frank
  10. Doubling all employees' salaries...
  11. Making changes definite: OK.

秘籍

继续修炼请参考官方文档(浏览器访问https://pqxx.org/development/libpqxx/即可查阅)。

8f3318ac048ec71bfaf8eaa61d6ab9bb.png

江湖

libpqxx 并不是什么绝世神兵,他能做的事情 libpq 都可以做,但通过 C++ 封装后,它具备了更加友好的用户接口,同时也大大提升了开发效率,如果您使用 C++ 开发 MogDB 的应用,或者您公司使用比较高版本的 C++ 标准,例如:C++17,那么 libpqxx 会大幅减少您公司的开发成本,并且保证了代码风格的一致性。相信 MogDB 配上了 libpqxx 这把“碧玉刀”,在江湖路上必将一路坦途。

霸王枪/Golang pq

霸王枪长一丈三尺七寸三分,重七十三斤七两三钱。霸王枪象征勇气。“一个人只要有勇气去冒险,天下就绝没有不能解决的事。”

Golang 是年轻充满朝气的开发语言,它诞生于2007年,发布与2009年,自发布以来,披荆斩棘,一时间搅得江湖上不得安宁。Golang 以编译型语言的姿态挑战 C 的性能,以轻量级的携程挑战 JAVA 和C++的并发,从日志处理、运维监控,到虚拟机、容器、区块链等后端,再到代理、web 应用、API 应用,凭着这股“勇气”,在各个领域 Go 都有上佳表现。

Golang pq 对于 PostgreSQL 系的数据库有着非常重要的作用,不仅仅是在企业应用中,在 MogDB 的周边工具(如 MTK 等)开发中,这杆“霸王枪”也发发挥了重要作用,也许日后 MogDB 的监控和运维工具也会有 Golang pq 的一席之地。

对于 Golang pq,恩墨也有自己的版本:openGauss-connector-go-pq(浏览器访问https://gitee.com/enmotech/openGauss-connector-go-pq即可查阅)。

功法

  • 获取

go get gitee.com/opengauss/openGauss-connector-go-pq

注意:如果遇到golang.org/x/ 报错相关问题可以使用下面方法

  1. mkdir $GOPATH/src/golang.org/x/
  2. cd $GOPATH/src/golang.org/x/
  3. git clone https://github.com/golang/text.git text
  4. git clone https://github.com/golang/crypto.git crypto
  5. git clone https://github.com/golang/xerrors.git xerrors
  6. go install text
  7. go install crypto
  8. go install xerrors
  • 范例

  1. package main
  2. import (
  3. "fmt"
  4. "log"
  5. "database/sql"
  6. _ "gitee.com/opengauss/openGauss-connector-go-pq"
  7. )
  8. func main() {
  9. connStr := "host=127.0.0.1 port=15432 user=frank password=frank@123 dbname=postgres sslmode=disable"
  10. // db, err := sql.Open("opengauss", connStr)
  11. db, err := sql.Open("mogdb", connStr)
  12. if err != nil {
  13. log.Fatal(err)
  14. }
  15. var version string
  16. err = db.QueryRow("select version()").Scan(&version)
  17. if err != nil {
  18. log.Fatal(err)
  19. }
  20. fmt.Println(version)
  21. }
  • 验证

  1. frank@DESKTOP-6NF3B9K:~/test/go/src$ ll
  2. total 7480
  3. drwxr-xr-x 5 frank frank 4096 Aug 6 09:31 ./
  4. drwxr-xr-x 4 frank frank 4096 Aug 5 21:54 ../
  5. drwxr-xr-x 3 frank frank 4096 Aug 5 21:52 gitee.com/
  6. drwxr-xr-x 3 frank frank 4096 Aug 5 21:52 github.com/
  7. drwxr-xr-x 3 frank frank 4096 Aug 5 21:54 golang.org/
  8. -rwxr-xr-x 1 frank frank 7631349 Aug 6 09:26 main*
  9. -rw-r--r-- 1 frank frank 480 Aug 5 21:57 main.go
  10. frank@DESKTOP-6NF3B9K:~/test/go/src$ ./main
  11. (MogDB 3.0.0 build 62408a0f) compiled at 2022-06-30 14:21:11 commit 0 last mr on x86_64-unknown-linux-gnu, compiled by g++ (GCC) 7.3.0, 64-bit
  12. frank@DESKTOP-6NF3B9K:~/test/go/src$

秘籍

Golang pq 源码(浏览器访问https://github.com/lib/pq即可查阅)

9e2f537623869ea9c091143c43ae24e2.png

openGauss-connector-go-pq源码(浏览器访问https://gitee.com/enmotech/openGauss-connector-go-pq即可查阅)

335656a63eac90a25ffff60c4e660310.png

江湖

Golang 就像横空出世的霸王枪,凭借着“勇气”已经撼动了不少企业级的 JAVA 和 C/C++ 应用,一些企业的核心系统已经逐渐的开始向 Golang 转型。随着应用架构的不断演进,MogDB 想在江湖上保持竞争力,一定要紧握 Golang pq 这杆抢。

多情环/JDBC

多情自古空余恨,好梦由来最易醒。岂是拈花难解脱,可怜飞絮太飘零。

想必大家还记得 Oracle 宣布 JDK 8u202 以上版本开始商用收费的消息,“好梦由来最易醒”,从 SUN 到 Oracle 再到商用收费,也许这是必然的过程,随着商用收费的宣布,我们的梦也应该醒了。虽然可以选择继续使用低版本,或者 openJDK,但一定会对企业应用和未来的技术路线有一定的冲击。欣喜的是国内的华为、阿里也有基于 openJDK 的产品,但在我们庞大系统中分散着太多依赖 JDK 的组件,需要全面的兼容性评估——“岂是拈花难解脱,可怜飞絮太飘零。”。

JAVA 无疑是目前市场占有率做大的一门企业级开发语言,没有之一。可以说几乎没有企业的信息化系统不使用 JAVA 作为主要的技术栈,从业务系统、大数据、信息系统几乎 JAVA 应用遍及大部分核心系统。作为应用与数据库的桥梁——JDBC 来说真是又爱又恨。

功法

  • 安装

官方软件包(浏览器访问https://opengauss.org/zh/download.html即可查阅)

4e4701b3977b5f55c318ebf1747a9705.png

  • 范例

11

  1. import java.sql.*;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.Statement;
  5. public class JdbcDemo {
  6. public static void main(String[] args) throws Exception {
  7. System.out.println("System.out.println(rs.getString(1));");
  8. Class.forName("org.opengauss.Driver");
  9. Connection conn = DriverManager.getConnection("jdbc:opengauss://localhost:15432/postgres?user=frank&password=frank@123&ssl=false");
  10. String sql = "select version()";
  11. Statement stmt = conn.createStatement();
  12. ResultSet rs = stmt.executeQuery(sql);
  13. while (rs.next())
  14. {
  15. System.out.print("Version : ");
  16. System.out.println(rs.getString(1));
  17. }
  18. stmt.close();
  19. conn.close();
  20. }
  21. }
  • 验证

  1. $ export CLASSPATH=/home/frank/test/java/opengauss-jdbc-3.0.0.jar:$CLASSPATH
  2. $ javac JdbcDemo.java
  3. $ java JdbcDemo
  4. System.out.println(rs.getString(1));
  5. Aug 06, 2022 10:24:12 AM org.opengauss.core.v3.ConnectionFactoryImpl openConnectionImpl
  6. INFO: [11a01b6b-3b51-4549-b552-6f836646ef36] Try to connect. IP: localhost:15432
  7. Aug 06, 2022 10:24:12 AM org.opengauss.core.v3.ConnectionFactoryImpl openConnectionImpl
  8. INFO: [127.0.0.1:39218/ocalhost/127.0.0.1:15432] Connection is established. ID: 11a01b6b-3b51-4549-b552-6f836646ef36
  9. Aug 06, 2022 10:24:12 AM org.opengauss.core.v3.ConnectionFactoryImpl openConnectionImpl
  10. INFO: Connect complete. ID: 11a01b6b-3b51-4549-b552-6f836646ef36
  11. Version : (MogDB 3.0.0 build 62408a0f) compiled at 2022-06-30 14:21:11 commit 0 last mr   on x86_64-unknown-linux-gnu, compiled by g++ (GCC) 7.3.0, 64-bit

秘籍

PostgreSQL JDBC Driver(浏览器访问https://jdbc.postgresql.org/即可查阅)

ce67b24ffc0dbb3a7a4bb27969328452.png

openGauss Connectors(浏览器访问https://opengauss.org/zh/download.html即可查阅)

18e20eacfb3044983cb61415be7dc618.png

江湖

对 JAVA 我们有着复杂的感情,国内有着最多的 JAVA 程序员群体,甚至可以用“过剩”这个词。对于 JDK 来说,虽然国内像阿里、华为这样的大厂已经有了 JDK 的产品,但尚未成熟,需要社区继续努力和生态的支撑。MogDB 作为基于 openGauss 的企业级数据库,严格说也属于华为鲲鹏生态的一部分,华为有着完备的全栈生态体系,从 Kunpeng 处理器、openEuler 操作系统、openGauss/GaussDB 数据库到毕昇编译器,毕昇 JDK。在 IT 技术垂直领域几乎面面俱到。MogDB 是华为数据库生态领域的水平拓展,既享受着生态的红利,又是生态建设的主要力量——恩墨对 openGauss 社区的贡献仅次于华为。

离别钩/ODBC

“你为什么要用如此残酷的武器?”“因为我不愿被人强迫与我所爱的人离别。”……“你用离别钩,只不过为了要相聚。”

说起 ODBC,一些早年的程序员会比较熟悉,但现在似乎渐渐的与我们“离别”,JDBC 也是复用了 ODBC 的思想后大行其道,但由于原生的数据库 C/C++ 接口从性能到兼容性上表现的更为出色,而 C/C++ 往往追求的恰恰是性能,所以 ODBC 在企业应用的用武之地变得越来越少。

功法

  • 安装

获取unixODBC(浏览器访问https://sourceforge.net/projects/unixodbc/files/unixODBC/2.3.7/unixODBC-2.3.7pre.tar.gz/download即可查阅)

获取openGauss ODBC驱动(浏览器访问https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/x86_openEuler/openGauss-3.0.0-ODBC.tar.gz即可查阅)

  1. tar -zxvf unixODBC-2.3.7pre.tar.gz
  2. cd unixODBC-2.3.7pre
  3. ./configure
  4. make -j6
  5. sudo make install
  6. tar -zxvf openGauss-3.0.0-ODBC.tar.gz
  7. export ODBCSYSINI=/usr/local/etc
  8. export ODBCINI=/usr/local/etc/odbc.ini
  9. export LD_LIBRARY_PATH=/home/frank/test/odbc/lib:/home/frank/test/odbc/odbc/lib:$LD_LIBRARY_PATH
  • 配置

/usr/local/etc/odbcinst.ini

  1. # /usr/local/etc/odbcinst.ini
  2. [GaussMPP]
  3. Driver64=/home/frank/test/odbc/odbc/lib/psqlodbcw.so
  4. setup=/home/frank/test/odbc/odbc/lib/psqlodbcw.so

/usr/local/etc/odbc.ini

  1. # /usr/local/etc/odbc.ini
  2. [MOGODBC]
  3. Driver=GaussMPP
  4. Servername=localhost
  5. Database=postgres
  6. Username=frank
  7. Password=frank@123
  8. Port=15432
  9. Sslmode=disable
  1. frank@DESKTOP-6NF3B9K:/usr/local/etc$ isql -v MOGODBC
  2. +---------------------------------------+
  3. | Connected! |
  4. | |
  5. | sql-statement |
  6. | help [tablename] |
  7. | quit |
  8. | |
  9. +---------------------------------------+
  10. SQL> select version();
  11. +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  12. | version |
  13. +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  14. | (MogDB 3.0.0 build 62408a0f) compiled at 2022-06-30 14:21:11 commit 0 last mr on x86_64-unknown-linux-gnu, compiled by g++ (GCC) 7.3.0, 64-bit |
  15. +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
  16. SQLRowCount returns 1
  17. 1 rows fetched
  18. SQL>
  • 范例

  1. // 此示例演示如何通过ODBC方式获取MogDB中的数据。
  2. // DBtest.c (compile with: libodbc.so)
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <sqlext.h>
  6. #ifdef WIN32
  7. #include <windows.h>
  8. #endif
  9. SQLHENV V_OD_Env; // Handle ODBC environment
  10. SQLHSTMT V_OD_hstmt; // Handle statement
  11. SQLHDBC V_OD_hdbc; // Handle connection
  12. char typename[100];
  13. SQLINTEGER value = 100;
  14. SQLINTEGER V_OD_erg,V_OD_buffer,V_OD_err,V_OD_id;
  15. int main(int argc,char *argv[])
  16. {
  17. // 1. 申请环境句柄
  18. V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
  19. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
  20. {
  21. printf("Error AllocHandle\n");
  22. exit(0);
  23. }
  24. // 2. 设置环境属性(版本信息)
  25. SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
  26. // 3. 申请连接句柄
  27. V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
  28. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
  29. {
  30. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
  31. exit(0);
  32. }
  33. // 4. 设置连接属性
  34. SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
  35. // 5. 连接数据源,这里的“userName”与“password”分别表示连接数据库的用户名和用户密码,请根据实际情况修改。
  36. // 如果odbc.ini文件中已经配置了用户名密码,那么这里可以留空("");但是不建议这么做,因为一旦odbc.ini权限管理不善,将导致数据库用户密码泄露。
  37. V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "MOGODBC", SQL_NTS,
  38. (SQLCHAR*) "frank", SQL_NTS, (SQLCHAR*) "frank@123", SQL_NTS);
  39. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
  40. {
  41. printf("Error SQLConnect %d\n",V_OD_erg);
  42. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
  43. exit(0);
  44. }
  45. printf("Connected !\n");
  46. // 6. 设置语句属性
  47. SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0);
  48. // 7. 申请语句句柄
  49. SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
  50. // 8. 直接执行SQL语句。
  51. SQLExecDirect(V_OD_hstmt,"drop table IF EXISTS customer_t1",SQL_NTS);
  52. SQLExecDirect(V_OD_hstmt,"CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32));",SQL_NTS);
  53. SQLExecDirect(V_OD_hstmt,"insert into customer_t1 values(25,li)",SQL_NTS);
  54. // 9. 准备执行
  55. SQLPrepare(V_OD_hstmt,"insert into customer_t1 values(?)",SQL_NTS);
  56. // 10. 绑定参数
  57. SQLBindParameter(V_OD_hstmt,1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0,
  58. &value,0,NULL);
  59. // 11. 执行准备好的语句
  60. SQLExecute(V_OD_hstmt);
  61. SQLExecDirect(V_OD_hstmt,"select id from testtable",SQL_NTS);
  62. // 12. 获取结果集某一列的属性
  63. SQLColAttribute(V_OD_hstmt,1,SQL_DESC_TYPE,typename,100,NULL,NULL);
  64. printf("SQLColAtrribute %s\n",typename);
  65. // 13. 绑定结果集
  66. SQLBindCol(V_OD_hstmt,1,SQL_C_SLONG, (SQLPOINTER)&V_OD_buffer,150,
  67. (SQLLEN *)&V_OD_err);
  68. // 14. 通过SQLFetch取结果集中数据
  69. V_OD_erg=SQLFetch(V_OD_hstmt);
  70. // 15. 通过SQLGetData获取并返回数据。
  71. while(V_OD_erg != SQL_NO_DATA)
  72. {
  73. SQLGetData(V_OD_hstmt,1,SQL_C_SLONG,(SQLPOINTER)&V_OD_id,0,NULL);
  74. printf("SQLGetData ----ID = %d\n",V_OD_id);
  75. V_OD_erg=SQLFetch(V_OD_hstmt);
  76. };
  77. printf("Done !\n");
  78. // 16. 断开数据源连接并释放句柄资源
  79. SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
  80. SQLDisconnect(V_OD_hdbc);
  81. SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
  82. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
  83. return(0);
  84.  }
  • 验证

  1. frank@DESKTOP-6NF3B9K:~/test/odbc$ gcc main.c -lodbc -o main -w
  2. frank@DESKTOP-6NF3B9K:~/test/odbc$ ./main
  3. Connected !
  4. SQLColAtrribute
  5. Done !

秘籍

看了网上的一些文档综合比下来 ODBC 这块还是参考 MogDB 官方文档(浏览器访问https://docs.mogdb.io/zh/mogdb/v3.0/1-development-based-on-odbc-overview即可查阅),客观的讲,MogDB 的文档在对比其竞品确实做的很好。

ddecadf603d44cdb6587f78797c8cd89.png

江湖

离别意味着再次相聚,随着国产数据库迁移的步伐加快,在选型或者过度阶段可能会同时适配多种不同的数据库,诸如:mysql体系、postgres体系或者完全自研的国产数据库,如果适配每一种数据库都使用期原生的 C/C++ 驱动,那么无形中会增加很大的工作量,既是有系统有很好的架构设计(有 SQL 适配层或者使用 ORM)也避免不了要做全面的测试。但据我目前的实践经验看,几乎所有的国产关系型数据库都提供了 ODBC(就像 JDBC 一样)标准的接口,这样只要适配了 ODBC 接口就可以一劳永逸。

箱子/libpq

《英雄无泪》塑造出一个极为经典的兵器-箱子,这口箱子复杂玄妙,可任意变换成各种兵器,是武器的集大成者。箱子寓意武者的“道”。

任何武器都是身外之物,只有 libpq 是和内核代码放在一起,所以说它并非武器,而是“道”是 PostgreSQL 的“道”也是 openGauss/MogDB 的“道”。

功法

  • 安装

获取安装介质(浏览器访问https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/x86_openEuler/openGauss-3.0.0-openEuler-64bit-Libpq.tar.gz即可查阅)

  • 范例

  1. /*
  2. * testlibpq.c
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <libpq-fe.h>
  7. static void
  8. exit_nicely(PGconn *conn)
  9. {
  10. PQfinish(conn);
  11. exit(1);
  12. }
  13. int
  14. main(int argc, char **argv)
  15. {
  16. const char *conninfo;
  17. PGconn *conn;
  18. PGresult *res;
  19. int nFields;
  20. int i,j;
  21. /*
  22. * 用户在命令行上提供了conninfo字符串的值时使用该值
  23. * 否则环境变量或者所有其它连接参数
  24. * 都使用缺省值。
  25. */
  26. if (argc > 1)
  27. conninfo = argv[1];
  28. else
  29. conninfo = "dbname=postgres port=42121 host='10.44.133.171' application_name=test connect_timeout=5 sslmode=allow user='test' password='test_1234'";
  30. /* 连接数据库 */
  31. conn = PQconnectdb(conninfo);
  32. /* 检查后端连接成功建立 */
  33. if (PQstatus(conn) != CONNECTION_OK)
  34. {
  35. fprintf(stderr, "Connection to database failed: %s",
  36. PQerrorMessage(conn));
  37. exit_nicely(conn);
  38. }
  39. /*
  40. * 测试实例涉及游标的使用时候必须使用事务块
  41. *把全部放在一个 "select * from pg_database"
  42. * PQexec() 里,过于简单,不推荐使用
  43. */
  44. /* 开始一个事务块 */
  45. res = PQexec(conn, "BEGIN");
  46. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  47. {
  48. fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
  49. PQclear(res);
  50. exit_nicely(conn);
  51. }
  52. /*
  53. * 在结果不需要的时候PQclear PGresult,以避免内存泄漏
  54. */
  55. PQclear(res);
  56. /*
  57. * 从系统表 pg_database(数据库的系统目录)里抓取数据
  58. */
  59. res = PQexec(conn, "DECLARE myportal CURSOR FOR select * from pg_database");
  60. if (PQresultStatus(res) != PGRES_COMMAND_OK)
  61. {
  62. fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
  63. PQclear(res);
  64. exit_nicely(conn);
  65. }
  66. PQclear(res);
  67. res = PQexec(conn, "FETCH ALL in myportal");
  68. if (PQresultStatus(res) != PGRES_TUPLES_OK)
  69. {
  70. fprintf(stderr, "FETCH ALL failed: %s", PQerrorMessage(conn));
  71. PQclear(res);
  72. exit_nicely(conn);
  73. }
  74. /* 打印属性名称 */
  75. nFields = PQnfields(res);
  76. for (i = 0; i < nFields; i++)
  77. printf("%-15s", PQfname(res, i));
  78. printf("\n\n");
  79. /* 打印行 */
  80. for (i = 0; i < PQntuples(res); i++)
  81. {
  82. for (j = 0; j < nFields; j++)
  83. printf("%-15s", PQgetvalue(res, i, j));
  84. printf("\n");
  85. }
  86. PQclear(res);
  87. /* 关闭入口 ... 不用检查错误 ... */
  88. res = PQexec(conn, "CLOSE myportal");
  89. PQclear(res);
  90. /* 结束事务 */
  91. res = PQexec(conn, "END");
  92. PQclear(res);
  93. /* 关闭数据库连接并清理 */
  94. PQfinish(conn);
  95. return 0;
  96. }
  • 验证

  1. export LD_LIBRARY_PATH=/home/frank/test/libpq/lib/:$LD_LIBRARY_PATH
  2. gcc testlibpq.c -I include -L lib -lpq -o testlibpq

c9d9ccbf886f4ff369a838f380e58f1c.png

秘籍

PostgreSQL 官方文档(浏览器访问https://www.postgresql.org/docs/15/index.html即可查阅)

1c9796a365156d977b41608d9cd54233.png

MogDB 官方文档(浏览器访问https://docs.mogdb.io/zh/mogdb/v3.0/development-process即可查阅)

8bab580ed747b21404d96bcda2800ace.png

江湖

没有武器就是有武器,有武器就是没有武器。一口箱子可以任意变换成各种兵器,libpqxx、ODBC、node posstgres、psycopg 等等都可以找到他的影子。libpq 是 PostgreSQL 系数据库最强的武器,也是他们的道。

  • 幻化ODBC

ba936c27846eb667b72ef6ef082a753e.png

  • 幻化libpqxx

f3e6dc4a61eab1c355aa39f8ecf9521c.png

  • 幻化node-postgres

fe4417b08cf76904879cdc86633fdf84.png

番外

FanWai

洋枪/OCI、OCCI

与上面的冷兵器不同,洋枪的出现改变了人类了的战争史。而“洋枪”这个词,在国人的心中有着意味深长的寓意,可能是“落后”、“屈辱”亦或是“卧薪尝胆的意志”。

这东西用着很顺手,或许是用惯了。当然如果找一件趁手的兵器替代它也并非难事,但是需要付出一定的学习成本和时间。那么不妨在过度期间我们可以先模仿它的用法,哪怕扣响扳机后打出来的不是“子弹”,而是“袖箭”。

很多大侠已经开始这么干了,相信 MogDB 也已经在路上。

尾声

WeiSheng

MogDB 可用的武器远不止七种,这里只是列出来企业级应用最常用的几种。就像开头说的,各位大侠们并不是那么地重视驱动,而丰富的数据库驱动接口是满足企业复杂的应该系统的必要条件。对于 MogDB 来说继承了祖上(PostgreSQL、openGauss)丰富的驱动接口,这是 MogDB 的优势。可能现在缺的就是一把“洋枪”。

这里还要特别提一下除了武器之外 MogDB 的一些拳脚功夫,像 server 端的过程语言:PL/pgSQl、PL/Tcl、PL/Perl、PL/Python、PL/Java;可以扩展内部函数:C FUNCTION、Embedded SQL in C;可以热插拔的插件:contrib 下面 C 开发的插件、使用 rust pgx 开发的 rust 语言插件等等,就扩展性来说,我认为 PostgreSQL/openGauss/MogDB 是最强大的,没有之一,这也是 MogDB 吸引我的最重要原因。由于篇幅有限,后续有机会再和大家一起讨论 MogDB 的拳脚功夫 。

6aa1eb2b8c057a0f6abc60d79d49ea4e.gif

数据驱动,成就未来,云和恩墨,不负所托!


云和恩墨创立于2011年,以“数据驱动,成就未来”为使命,是智能的数据技术提供商。我们致力于将数据技术带给每个行业、每个组织、每个人,构建数据驱动的智能未来。

云和恩墨在数据承载(分布式存储、数据持续保护)、管理(数据库软件、数据库云管平台、数据技术服务)、加工(应用开发质量管控、数据模型管控、数字化转型咨询)和应用(数据服务化管理平台、数据智能、隐私计算数据联邦平台)等领域为各个组织提供可信赖的产品、服务和解决方案,围绕用户需求,持续为客户创造价值,激发数据潜能,为成就未来敏捷高效的数字世界而不懈努力。

3a19de4cbbdf10bcdd0986de60313bdb.gif

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/662656
推荐阅读
相关标签
  

闽ICP备14008679号