0


linux系统下PostgreSQL的使用

文章目录


前言

最近工作中使用到了pgsql,主要是使用其c++驱动完成数据库创建及增删改查等操作…

一、安装pgsql数据库

使用命令如下:

sudo apt-get install postgresql

安装完成,使用如下命令,确认数据库版本:

psql --version

二、安装c和c++驱动

使用如下命令安装c驱动:

sudo apt-get install libpq-dev

使用如下命令安装c++驱动:

sudo tar -zxvf libpqxx-6.4.8.tar.gz
cd libpqxx-6.4.8/
sudo ./configure --disable-documentation
sudo make
sudo make install

三、使用

1、头文件

头文件如下:

#ifndefPOSTGREOPERATOR_H#definePOSTGREOPERATOR_H#include<iostream>#include<string>#include<map>#include<thread>#include"pqxx/pqxx"usingnamespace std;usingnamespace pqxx;structTableField{
    string name;
    string type;};classPostgreOperator{private:PostgreOperator(){}PostgreOperator(const PostgreOperator&)=delete;
    PostgreOperator&operator=(const PostgreOperator&)=delete;~PostgreOperator();public:static PostgreOperator&getInstance();boolconnect();voiddisConnect();boolinsertOneRow(const string& tableName,const vector<string>& rowData);boolupdateOneRow(const string& tableName,const string& conditionColumnName,const string& conditionValue,const vector<string>& columnNames,const vector<string>& newValues);voidselectRows(const string& tableName, vector<vector<string>>& resultRows,const vector<string>& selectedColumns,const string& conditionColumnName ="",const string& conditionValue ="");booldeleteRows(const string& tableName,const string& conditionColumnName ="",const string& conditionValue ="");private:staticvoidinitTable();staticboolcreatedb(const string& dbname,const string& user,const string& password);staticboolcreateInitTable();staticbooladdTable(const string& tableName,const vector<TableField>& fields);staticbooldeleteTable(const string& tableName);staticbooladdFieldToTable(const string& tableName,const vector<TableField>& fields);staticboolremoveFieldFromTable(const string& tableName,const vector<string>& fieldNames);private:static string m_user;static string m_passwd;static string m_dbName;staticbool m_initTable;static PostgreOperator *m_instance;static map<string, vector<TableField>> m_tables;static connection* m_pConnection;staticthread_local unique_ptr<connection> thread_local_connection_;};#endif// POSTGREOPERATOR_H

2、源文件

源文件如下:

#include"postgreoperator.h"

string      PostgreOperator::m_dbName;
string      PostgreOperator::m_user;
string      PostgreOperator::m_passwd;bool        PostgreOperator::m_initTable =false;
connection* PostgreOperator::m_pConnection =nullptr;

map<string, vector<TableField>> PostgreOperator::m_tables;
PostgreOperator* PostgreOperator::m_instance =nullptr;thread_local unique_ptr<connection> PostgreOperator::thread_local_connection_ =nullptr;

PostgreOperator&PostgreOperator::getInstance(){if(!m_instance){
        m_instance =new PostgreOperator;if(!m_initTable){initTable();createdb("disposaldb","tami","tami");createInitTable();}}return*m_instance;}PostgreOperator::~PostgreOperator(){if(m_pConnection){
        m_pConnection->disconnect();delete m_pConnection;
        m_pConnection =nullptr;}}boolPostgreOperator::createdb(const string& dbname,const string& user,const string& password){
    m_dbName = dbname;
    m_user = user;
    m_passwd = password;
    string connectStr ="dbname=postgres user=postgres password=postgres ""hostaddr=127.0.0.1 port=5432";bool ret =false;try{
        connection *connection =new pqxx::connection(connectStr);if(connection->is_open()){
            nontransaction txn(*connection);
            string quotedDb ="'"+ dbname +"'";if(user.compare("postgres")==0&& password.compare("postgres")==0){//cout<<"hello111 "<<"user ="<<user<<"password ="<<password<<endl;
                string checkDb ="SELECT 1 FROM pg_database WHERE datname = "+ quotedDb;
                pqxx::result result_check = txn.exec(checkDb);if(result_check.empty()){
                    string sql ="CREATE DATABASE "+ dbname +" WITH OWNER= postgres"+" ENCODING='UTF-8' ;";
                    txn.exec(sql);
                    cout <<"create database "+ dbname +" with user=postgres successed!"<< endl;}else{
                    cout <<"database "+ dbname +" already exists!"<<endl;}}else{//cout<<"hello222 "<<"user ="<<user<<" password ="<<password<<endl;
                string quotedUser ="'"+ user +"'";
                string checkUser ="SELECT 1 FROM pg_user WHERE usename = "+ quotedUser;
                pqxx::result result_checkUser = txn.exec(checkUser);if(result_checkUser.empty()){
                    string sql ="CREATE USER "+ user +" WITH PASSWORD '"+ password +"'";
                    txn.exec(sql);}else{
                    cout <<"user "+ user +" already exists!"<<endl;}
                std::string checkDb ="SELECT 1 FROM pg_database WHERE datname = "+ quotedDb;
                pqxx::result result_check = txn.exec(checkDb);if(result_check.empty()){
                    string dbSql ="CREATE DATABASE "+ dbname +" WITH OWNER="+user+" ENCODING='UTF-8';";
                    txn.exec(dbSql);
                    cout <<"create database "+ dbname +" with user="+user+" successed!"<< endl;}else{
                    cout <<"database "+ dbname +" already exists!"<<endl;}}

            ret =true;}else{
            cout<<"open database "+ dbname +" with user=postgres failed!"<<endl;
            connection->disconnect();return ret;}delete connection;
        connection =nullptr;}catch(const std::exception &e){
        cerr<<e.what()<<endl;}return ret;}voidPostgreOperator::initTable(){
    m_tables.clear();
    m_tables ={{"p_frequency",{{"msgId","bigint"},{"sn","bigint"},{"startFrequency","bigint"},{"endFrequency","bigint"},{"rbw","double precision"},{"dataType","smallint"},{"number","integer"},}},{"d_frequency",{{"msgId","bigint"},{"sn","bigint"},{"times","timestamp without time zone"},{"timems","timestamp without time zone"},{"data","smallint[]"},}},{"p_timedomain",{{"msgId","bigint"},{"sn","bigint"},{"centerFrequency","bigint"},{"gain","smallint"},{"timestamp","timestamp without time zone"},{"frameTotal","integer"},{"frameNumber","integer"},{"number","integer"},}},{"d_timedomain",{{"msgId","bigint"},{"sn","bigint"},{"times","timestamp without time zone"},{"timems","timestamp without time zone"},{"data","integer[]"},}},};}boolPostgreOperator::createInitTable(){
    string connectStr ="dbname="+m_dbName+" user="+m_user+" password="+m_passwd+" hostaddr=127.0.0.1 port=5432";bool ret =false;try{
        m_pConnection =new pqxx::connection(connectStr);if(m_pConnection->is_open()){
            nontransaction txn(*m_pConnection);for(constauto& table : m_tables){const std::string tableName = table.first;const std::vector<TableField>& fields = table.second;

                string quotedtable ="'"+ tableName +"'";
                string checktable ="SELECT 1 FROM information_schema.tables WHERE table_name = "+ quotedtable;//cout<<"checktable ="<<checktable<<endl;
                pqxx::result result_check = txn.exec(checktable);if(result_check.empty()){
                    string quotedTableName ="\""+ tableName +"\"";
                    string createTableQuery ="CREATE TABLE "+ quotedTableName +" (";
                    string idStr ="id";
                    string msgIdStr ="msgId";
                    string snStr ="sn";

                    createTableQuery +="\""+ idStr +"\" ";
                    createTableQuery +=" BIGSERIAL, ";for(size_t i =0; i < fields.size(); i++){if(fields[i].name == msgIdStr || fields[i].name == snStr){
                            createTableQuery +="\""+ fields[i].name +"\" "+" "+ fields[i].type;
                            createTableQuery +=" NOT NULL";}else{
                            createTableQuery +="\""+ fields[i].name +"\" "+" "+ fields[i].type;}if(i < fields.size()-1){
                            createTableQuery +=", ";}}

                    createTableQuery +=", PRIMARY KEY (\""+ idStr +"\")";
                    createTableQuery +=")";//cout<<"createTableQuery ="<<createTableQuery<<endl;
                    txn.exec(createTableQuery);
                    cout <<"create table "+ tableName +" succeeded!"<< endl;}else{
                    cout <<"table "+ tableName +" already exists!"<< endl;}}

            ret =true;}}catch(const std::exception& e){
        cerr << e.what()<< endl;}return ret;}boolPostgreOperator::connect(){if(!thread_local_connection_){
        std::string connectStr ="dbname="+ m_dbName +" user="+ m_user +" password="+ m_passwd
                                +" hostaddr=127.0.0.1 port=5432";try{
            thread_local_connection_.reset(new pqxx::connection(connectStr));if(thread_local_connection_->is_open()){
                cout <<"Connected to dbname="<< m_dbName <<" with user="<< m_user <<" succeeded!"<< endl;returntrue;}else{
                cout <<"Failed to connect to dbname="<< m_dbName <<" with user="<< m_user << endl;returnfalse;}}catch(const std::exception& e){
            std::cerr <<"Connection failed: "<< e.what()<< std::endl;returnfalse;}}returntrue;}voidPostgreOperator::disConnect(){if(thread_local_connection_){
        thread_local_connection_->disconnect();
        thread_local_connection_.reset();}}boolPostgreOperator::addFieldToTable(const string& tableName,const vector<TableField>& fields){bool ret =false;try{
        work txn(*m_pConnection);
        string quotedtable ="'"+ tableName +"'";
        string checktable ="SELECT 1 FROM information_schema.tables WHERE table_name = "+ quotedtable;
        pqxx::result result_check = txn.exec(checktable);if(!result_check.empty()){for(constauto& field : fields){
                string columnName ="'"+ field.name +"'";
                string sql ="SELECT column_name FROM information_schema.columns WHERE table_name = '"+ tableName +"' AND column_name = "+columnName;//cout<<"select sql ="<<sql<<endl;
                pqxx::result result = txn.exec(sql);if(result.empty()){
                    string sql ="ALTER TABLE "+ tableName+" ADD COLUMN ";
                    sql +="\""+ field.name +"\" "+" "+ field.type;//cout<<"alter add sql ="<<sql<<endl;
                    txn.exec(sql);
                    cout <<"addFieldToTable successfully."<< endl;
                    ret =true;}else{
                    cout<<"column "+field.name+" of "+tableName+" already exists!"<<endl;}}}else{
           cout <<"table "+ tableName +" does not exist!"<< endl;}
        txn.commit();}catch(const std::exception& e){
        cerr << e.what()<< endl;}return ret;}boolPostgreOperator::removeFieldFromTable(const string& tableName,const vector<string>& fieldNames){bool ret =false;try{
        work txn(*m_pConnection);
        string quotedtable ="'"+ tableName +"'";
        string checktable ="SELECT 1 FROM information_schema.tables WHERE table_name = "+ quotedtable;
        pqxx::result result_check = txn.exec(checktable);if(!result_check.empty()){for(constauto& field : fieldNames){
                string columnName ="'"+ field +"'";
                string sql ="SELECT column_name FROM information_schema.columns WHERE table_name = '"+ tableName +"' AND column_name = "+columnName;//cout<<"select sql ="<<sql<<endl;
                pqxx::result result = txn.exec(sql);if(!result.empty()){
                    string sql ="ALTER TABLE "+ tableName+" DROP COLUMN ";
                    sql +="\""+ field +"\" "+" ";//cout<<"alter drop sql ="<<sql<<endl;
                    txn.exec(sql);
                    cout <<"removeFieldFromTable successfully."<< endl;
                    ret =true;}else{
                    cout<<"column "+field+" of "+tableName+" does not exists!"<<endl;}}}else{
           cout <<"table "+ tableName +" does not exist!"<< endl;}
        txn.commit();}catch(const std::exception& e){
        cerr << e.what()<< endl;}return ret;}boolPostgreOperator::addTable(const string& tableName,const vector<TableField>& fields){bool ret =false;
    work txn(*m_pConnection);

    string quotedtable ="'"+ tableName +"'";
    string checktable ="SELECT 1 FROM information_schema.tables WHERE table_name = "+ quotedtable;//cout<<"checktable ="<<checktable<<endl;
    pqxx::result result_check = txn.exec(checktable);if(result_check.empty()){
        string quotedTableName ="\""+ tableName +"\"";
        string createTableQuery ="CREATE TABLE "+ quotedTableName +" (";
        string idStr ="id";
        string msgIdStr ="msgId";
        string snStr ="sn";

        createTableQuery +="\""+ idStr +"\" ";
        createTableQuery +=" BIGSERIAL, ";
        createTableQuery +="\""+ msgIdStr +"\" ";
        createTableQuery +=" bigint NOT NULL, ";
        createTableQuery +="\""+ snStr +"\" ";
        createTableQuery +=" bigint NOT NULL, ";if(!fields.empty()){for(size_t i =0; i < fields.size(); i++){
                createTableQuery +="\""+ fields[i].name +"\" "+" "+ fields[i].type;if(i < fields.size()-1){
                    createTableQuery +=", ";}}
            createTableQuery +=", PRIMARY KEY (\""+ idStr +"\")";}else{
            createTableQuery +=" PRIMARY KEY (\""+ idStr +"\")";}
        createTableQuery +=")";
        txn.exec(createTableQuery);
        txn.commit();//cout<<"createTableQuery ="<<createTableQuery<<endl;
        cout <<"create table "+ tableName +" succeeded!"<< endl;

        m_tables[tableName]= fields;//        for (const auto& table : m_tables) {//            const string tableName = table.first;//            cout<<"tablename ="<<tableName<<endl;//            const vector<TableField>& fields = table.second;//            for(const auto& field : fields){//                cout<<"name="<<field.name<<"type ="<<field.type;//            }//            cout<<endl;//        }

        ret =true;}else{
        cout <<"table "+ tableName +" already exists!"<< endl;}return ret;}boolPostgreOperator::deleteTable(const string& tableName){bool ret =false;try{
        string sql ="DROP TABLE IF EXISTS "+ tableName;
        pqxx::work txn(*m_pConnection);
        txn.exec(sql);if(!m_tables.empty()){auto it = m_tables.find(tableName);if(it != m_tables.end()){
                m_tables.erase(it);//cout << "Table '" << tableName << "' deleted from m_tables successfully." << endl;
                ret =true;}else{
                cout <<"Table '"<< tableName <<"' not found from m_tables."<< endl;}}
        txn.commit();}catch(const std::exception& e){
        cerr << e.what()<< endl;}return ret;}boolPostgreOperator::insertOneRow(const string& tableName,const vector<string>& rowData){bool ret =false;
    pqxx::work txn(*thread_local_connection_);try{
        std::string sql ="INSERT INTO "+ tableName +" (";for(constauto& table : m_tables){const std::string tableNameStr = table.first;const std::vector<TableField>& fields = table.second;if(tableNameStr == tableName){for(size_t i =0; i < fields.size(); i++){
                    sql +="\""+ fields[i].name +"\" ";if(i != fields.size()-1){
                        sql +=",";}}}}
        sql +=") VALUES (";for(size_t i =0; i < rowData.size(); i++){
            sql +="'"+ rowData[i]+"'";if(i != rowData.size()-1){
                sql +=",";}}

        sql +=")";//cout<<"insert sql ="<<sql<<endl;

        txn.exec(sql);
        txn.commit();

        ret =true;}catch(const std::exception &e){
        cerr<<e.what()<<endl;
        txn.abort();}return ret;}boolPostgreOperator::updateOneRow(const string& tableName,const string& conditionColumnName,const string& conditionValue,const vector<string>& columnNames,const vector<string>& newValues){bool ret =false;try{
        pqxx::work txn(*thread_local_connection_);

        std::string sql ="UPDATE "+ tableName +" SET ";for(size_t i =0; i < columnNames.size(); i++){
            string columnName ="\""+ columnNames[i]+"\" ";
            sql += columnName +" = '"+ newValues[i]+"'";if(i != columnNames.size()-1){
                sql +=",";}}

        string conditionName ="\""+ conditionColumnName +"\" ";
        sql +=" WHERE "+ conditionName +" = '"+ conditionValue +"'";
        txn.exec(sql);
        txn.commit();

        cout <<"Data updated successfully."<< endl;
        ret =true;}catch(const std::exception &e){
        cerr << e.what()<< endl;}return ret;}voidPostgreOperator::selectRows(const string& tableName, vector<vector<string>>& resultRows,const vector<string>& selectedColumns,const string& conditionColumnName,const string& conditionValue){try{
        pqxx::work txn(*thread_local_connection_);

        string sql;// = "SELECT * FROM " + tableName;if(!selectedColumns.empty()){
            sql ="SELECT ";for(size_t i =0; i < selectedColumns.size();++i){
                sql +="\""+ selectedColumns[i]+"\"";if(i < selectedColumns.size()-1)
                    sql +=",";}
            sql +=" FROM "+ tableName;}else{
            sql ="SELECT * FROM "+ tableName;}if(!conditionColumnName.empty()&&!conditionValue.empty()){
            string conditionName ="\""+ conditionColumnName +"\" ";
            sql +=" WHERE "+ conditionName +" = '"+ conditionValue +"'";}

        pqxx::result result = txn.exec(sql);for(constauto& row : result){
            vector<string> record;for(constauto& field : row){//cout << field.name() << ": " << field.c_str() << "     ";
                record.push_back(field.c_str());}
            resultRows.push_back(record);//cout << endl;}

        txn.commit();

        cout <<"Data select successfully."<< endl;}catch(const std::exception &e){
        cerr << e.what()<< endl;}}boolPostgreOperator::deleteRows(const string& tableName,const string& conditionColumnName,const string& conditionValue){bool ret =false;
    pqxx::work txn(*thread_local_connection_);try{
        string sql ="DELETE FROM "+ tableName;if(!conditionColumnName.empty()&&!conditionValue.empty()){
            string conditionName ="\""+ conditionColumnName +"\" ";
            sql +=" WHERE "+ conditionName +" = '"+ conditionValue +"'";}
        cout<<"deleterows sql = "<<sql<<endl;
        txn.exec(sql);
        txn.commit();

        cout <<"Data delete successfully."<< endl;

        ret =true;}catch(const std::exception &e){
        cerr << e.what()<< endl;

        txn.abort();}return ret;}

3、main文件

#include<chrono>#include<iostream>#include<thread>#include"postgreoperator.h"voidinsertfun(int id,PostgreOperator &operatorInstance){if(!operatorInstance.connect()){
        std::cerr <<"Thread "<< id <<" failed to connect to the database."<< std::endl;return;}
    string tableName ="p_frequency";for(int i =0;i<500;i++){
        vector<string> data ={"12345","10086","0","2000000","0.1","1","10"};
        operatorInstance.insertOneRow(tableName, data);}for(int i =500;i<1000;i++){
        vector<string> data ={"67890","10086","0","2000000","0.1","1","10"};
        operatorInstance.insertOneRow(tableName, data);}}voiddeletefun(int id,PostgreOperator &operatorInstance){if(!operatorInstance.connect()){
        std::cerr <<"Thread "<< id <<" failed to connect to the database."<< std::endl;return;}
    string tableName ="p_frequency";
    string conditionColumnName ="msgId";
    string conditionValue ="12345";

    operatorInstance.deleteRows(tableName, conditionColumnName, conditionValue);}intmain(int argc,char*argv[]){
    PostgreOperator& operatorInstance =PostgreOperator::getInstance();// 创建并启动多个线程
    std::vector<std::thread> threads;for(int i =0; i <5;++i){
        threads.emplace_back(insertfun, i,std::ref(operatorInstance));}// 等待所有线程完成for(auto& thread : threads){
        thread.join();}#if0
    std::thread t1(deletefun,5, std::ref(operatorInstance));
    t1.join();#endifreturn1;}

4、编译

命令如下:

g++-pthread --std=c++11-o demo.out main.cpp postgreoperator.cpp -lpqxx -lpq
标签: linux postgresql 运维

本文转载自: https://blog.csdn.net/u011832219/article/details/142049692
版权归原作者 敲代码的雪糕 所有, 如有侵权,请联系我们删除。

“linux系统下PostgreSQL的使用”的评论:

还没有评论