⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qsql_psql.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
QPSQLDriver::QPSQLDriver(PGconn * conn, QObject * parent)    : QSqlDriver(parent){    init();    d->connection = conn;    if (conn) {        d->pro = getPSQLVersion(d->connection);        setOpen(true);        setOpenError(false);    }}void QPSQLDriver::init(){    d = new QPSQLDriverPrivate();}QPSQLDriver::~QPSQLDriver(){    if (d->connection)        PQfinish(d->connection);    delete d;}QVariant QPSQLDriver::handle() const{    return qVariantFromValue(d->connection);}bool QPSQLDriver::hasFeature(DriverFeature f) const{    switch (f) {    case Transactions:    case QuerySize:    case LastInsertId:        return true;    case BatchOperations:    case PreparedQueries:    case NamedPlaceholders:    case PositionalPlaceholders:    case SimpleLocking:    case LowPrecisionNumbers:        return false;    case BLOB:        return d->pro >= QPSQLDriver::Version71;    case Unicode:        return d->isUtf8;    }    return false;}/*   Quote a string for inclusion into the connection string   \ -> \\   ' -> \'   surround string by single quotes */static QString qQuote(QString s){    s.replace(QLatin1Char('\\'), QLatin1String("\\\\"));    s.replace(QLatin1Char('\''), QLatin1String("\\'"));    s.append(QLatin1Char('\'')).prepend(QLatin1Char('\''));    return s;}bool QPSQLDriver::open(const QString & db,                        const QString & user,                        const QString & password,                        const QString & host,                        int port,                        const QString& connOpts){    if (isOpen())        close();    QString connectString;    if (!host.isEmpty())        connectString.append(QLatin1String("host=")).append(qQuote(host));    if (!db.isEmpty())        connectString.append(QLatin1String(" dbname=")).append(qQuote(db));    if (!user.isEmpty())        connectString.append(QLatin1String(" user=")).append(qQuote(user));    if (!password.isEmpty())        connectString.append(QLatin1String(" password=")).append(qQuote(password));    if (port != -1)        connectString.append(QLatin1String(" port=")).append(qQuote(QString::number(port)));    // add any connect options - the server will handle error detection    if (!connOpts.isEmpty()) {        QString opt = connOpts;        opt.replace(QLatin1Char(';'), QLatin1Char(' '), Qt::CaseInsensitive);        connectString.append(QLatin1Char(' ')).append(opt);    }    d->connection = PQconnectdb(connectString.toLocal8Bit().constData());    if (PQstatus(d->connection) == CONNECTION_BAD) {        PQfinish(d->connection);        d->connection = 0;        setLastError(qMakeError(tr("Unable to connect"), QSqlError::ConnectionError, d));        setOpenError(true);        return false;    }    d->pro = getPSQLVersion(d->connection);    d->isUtf8 = setEncodingUtf8(d->connection);    setDatestyle(d->connection);    setOpen(true);    setOpenError(false);    return true;}void QPSQLDriver::close(){    if (isOpen()) {        if (d->connection)            PQfinish(d->connection);        d->connection = 0;        setOpen(false);        setOpenError(false);    }}QSqlResult *QPSQLDriver::createResult() const{    return new QPSQLResult(this, d);}bool QPSQLDriver::beginTransaction(){    if (!isOpen()) {        qWarning("QPSQLDriver::beginTransaction: Database not open");        return false;    }    PGresult* res = PQexec(d->connection, "BEGIN");    if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) {        PQclear(res);        setLastError(qMakeError(tr("Could not begin transaction"),                                QSqlError::TransactionError, d));        return false;    }    PQclear(res);    return true;}bool QPSQLDriver::commitTransaction(){    if (!isOpen()) {        qWarning("QPSQLDriver::commitTransaction: Database not open");        return false;    }    PGresult* res = PQexec(d->connection, "COMMIT");    if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) {        PQclear(res);        setLastError(qMakeError(tr("Could not commit transaction"),                                QSqlError::TransactionError, d));        return false;    }    PQclear(res);    return true;}bool QPSQLDriver::rollbackTransaction(){    if (!isOpen()) {        qWarning("QPSQLDriver::rollbackTransaction: Database not open");        return false;    }    PGresult* res = PQexec(d->connection, "ROLLBACK");    if (!res || PQresultStatus(res) != PGRES_COMMAND_OK) {        setLastError(qMakeError(tr("Could not rollback transaction"),                                QSqlError::TransactionError, d));        PQclear(res);        return false;    }    PQclear(res);    return true;}QStringList QPSQLDriver::tables(QSql::TableType type) const{    QStringList tl;    if (!isOpen())        return tl;    QSqlQuery t(createResult());    t.setForwardOnly(true);    if (type & QSql::Tables)        d->appendTables(tl, t, QLatin1Char('r'));    if (type & QSql::Views)        d->appendTables(tl, t, QLatin1Char('v'));    if (type & QSql::SystemTables) {        t.exec(QLatin1String("select relname from pg_class where (relkind = 'r') "                "and (relname like 'pg_%') "));        while (t.next())            tl.append(t.value(0).toString());    }    return tl;}static void qSplitTableName(QString &tablename, QString &schema){    int dot = tablename.indexOf(QLatin1Char('.'));    if (dot == -1)        return;    schema = tablename.left(dot);    tablename = tablename.mid(dot + 1);}QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const{    QSqlIndex idx(tablename);    if (!isOpen())        return idx;    QSqlQuery i(createResult());    QString stmt;    QString tbl = tablename;    QString schema;    qSplitTableName(tbl, schema);    switch(d->pro) {    case QPSQLDriver::Version6:        stmt = QLatin1String("select pg_att1.attname, int(pg_att1.atttypid), pg_cl.relname "                "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind "                "where lower(pg_cl.relname) = '%1_pkey' "                "and pg_cl.oid = pg_ind.indexrelid "                "and pg_att2.attrelid = pg_ind.indexrelid "                "and pg_att1.attrelid = pg_ind.indrelid "                "and pg_att1.attnum = pg_ind.indkey[pg_att2.attnum-1] "                "order by pg_att2.attnum");        break;    case QPSQLDriver::Version7:    case QPSQLDriver::Version71:        stmt = QLatin1String("select pg_att1.attname, pg_att1.atttypid::int, pg_cl.relname "                "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind "                "where lower(pg_cl.relname) = '%1_pkey' "                "and pg_cl.oid = pg_ind.indexrelid "                "and pg_att2.attrelid = pg_ind.indexrelid "                "and pg_att1.attrelid = pg_ind.indrelid "                "and pg_att1.attnum = pg_ind.indkey[pg_att2.attnum-1] "                "order by pg_att2.attnum");        break;    case QPSQLDriver::Version73:        stmt = QLatin1String("SELECT pg_attribute.attname, pg_attribute.atttypid::int, "                "pg_class.relname "                "FROM pg_attribute, pg_class "                "WHERE %1 pg_class.oid = "                "(SELECT indexrelid FROM pg_index WHERE indisprimary = true AND indrelid = "                " (SELECT oid FROM pg_class WHERE lower(relname) = '%2')) "                "AND pg_attribute.attrelid = pg_class.oid "                "AND pg_attribute.attisdropped = false "                "ORDER BY pg_attribute.attnum");        if (schema.isEmpty())            stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid) AND"));        else            stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from "                   "pg_namespace where pg_namespace.nspname = '%1') AND ").arg(schema.toLower()));        break;    }    i.exec(stmt.arg(tbl.toLower()));    while (i.isActive() && i.next()) {        QSqlField f(i.value(0).toString(), qDecodePSQLType(i.value(1).toInt()));        idx.append(f);        idx.setName(i.value(2).toString());    }    return idx;}QSqlRecord QPSQLDriver::record(const QString& tablename) const{    QSqlRecord info;    if (!isOpen())        return info;    QString tbl = tablename;    QString schema;    qSplitTableName(tbl, schema);    QString stmt;    switch(d->pro) {    case QPSQLDriver::Version6:        stmt = QLatin1String("select pg_attribute.attname, int(pg_attribute.atttypid), "                "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, "                "int(pg_attribute.attrelid), pg_attribute.attnum "                "from pg_class, pg_attribute "                "where lower(pg_class.relname) = '%1' "                "and pg_attribute.attnum > 0 "                "and pg_attribute.attrelid = pg_class.oid ");        break;    case QPSQLDriver::Version7:        stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, "                "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, "                "pg_attribute.attrelid::int, pg_attribute.attnum "                "from pg_class, pg_attribute "                "where lower(pg_class.relname) = '%1' "                "and pg_attribute.attnum > 0 "                "and pg_attribute.attrelid = pg_class.oid ");        break;    case QPSQLDriver::Version71:        stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, "                "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, "                "pg_attrdef.adsrc "                "from pg_class, pg_attribute "                "left join pg_attrdef on (pg_attrdef.adrelid = "                "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) "                "where lower(pg_class.relname) = '%1' "                "and pg_attribute.attnum > 0 "                "and pg_attribute.attrelid = pg_class.oid "                "order by pg_attribute.attnum ");        break;    case QPSQLDriver::Version73:        stmt = QLatin1String("select pg_attribute.attname, pg_attribute.atttypid::int, "                "pg_attribute.attnotnull, pg_attribute.attlen, pg_attribute.atttypmod, "                "pg_attrdef.adsrc "                "from pg_class, pg_attribute "                "left join pg_attrdef on (pg_attrdef.adrelid = "                "pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) "                "where %1 "                "and lower(pg_class.relname) = '%2' "                "and pg_attribute.attnum > 0 "                "and pg_attribute.attrelid = pg_class.oid "                "and pg_attribute.attisdropped = false "                "order by pg_attribute.attnum ");        if (schema.isEmpty())            stmt = stmt.arg(QLatin1String("pg_table_is_visible(pg_class.oid)"));        else            stmt = stmt.arg(QString::fromLatin1("pg_class.relnamespace = (select oid from "                   "pg_namespace where pg_namespace.nspname = '%1')").arg(schema.toLower()));        break;    }    QSqlQuery query(createResult());    query.exec(stmt.arg(tbl.toLower()));    if (d->pro >= QPSQLDriver::Version71) {        while (query.next()) {            int len = query.value(3).toInt();            int precision = query.value(4).toInt();            // swap length and precision if length == -1            if (len == -1 && precision > -1) {                len = precision - 4;                precision = -1;            }            QString defVal = query.value(5).toString();            if (!defVal.isEmpty() && defVal.at(0) == QLatin1Char('\''))                defVal = defVal.mid(1, defVal.length() - 2);            QSqlField f(query.value(0).toString(), qDecodePSQLType(query.value(1).toInt()));            f.setRequired(query.value(2).toBool());            f.setLength(len);            f.setPrecision(precision);            f.setDefaultValue(defVal);            f.setSqlType(query.value(1).toInt());            info.append(f);        }    } else {        // Postgres < 7.1 cannot handle outer joins        while (query.next()) {            QString defVal;            QString stmt2 = QLatin1String("select pg_attrdef.adsrc from pg_attrdef where "                            "pg_attrdef.adrelid = %1 and pg_attrdef.adnum = %2 ");            QSqlQuery query2(createResult());            query2.exec(stmt2.arg(query.value(5).toInt()).arg(query.value(6).toInt()));            if (query2.isActive() && query2.next())                defVal = query2.value(0).toString();            if (!defVal.isEmpty() && defVal.at(0) == QLatin1Char('\''))                defVal = defVal.mid(1, defVal.length() - 2);            int len = query.value(3).toInt();            int precision = query.value(4).toInt();            // swap length and precision if length == -1            if (len == -1 && precision > -1) {                len = precision - 4;                precision = -1;            }            QSqlField f(query.value(0).toString(), qDecodePSQLType(query.value(1).toInt()));            f.setRequired(query.value(2).toBool());            f.setLength(len);            f.setPrecision(precision);            f.setDefaultValue(defVal);            f.setSqlType(query.value(1).toInt());            info.append(f);        }    }    return info;}QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const{    QString r;    if (field.isNull()) {        r = QLatin1String("NULL");    } else {        switch (field.type()) {        case QVariant::DateTime:#ifndef QT_NO_DATESTRING            if (field.value().toDateTime().isValid()) {                QDate dt = field.value().toDateTime().date();                QTime tm = field.value().toDateTime().time();                // msecs need to be right aligned otherwise psql                // interpretes them wrong                r = QLatin1String("'") + QString::number(dt.year()) + QLatin1String("-")                          + QString::number(dt.month()) + QLatin1String("-")                          + QString::number(dt.day()) + QLatin1String(" ")                          + tm.toString() + QLatin1String(".")                          + QString::number(tm.msec()).rightJustified(3, QLatin1Char('0'))                          + QLatin1String("'");            } else#else            {                r = QLatin1String("NULL");            }#endif // QT_NO_DATESTRING            break;        case QVariant::Time:#ifndef QT_NO_DATESTRING            if (field.value().toTime().isValid()) {                r = field.value().toTime().toString(Qt::ISODate);            } else#endif            {                r = QLatin1String("NULL");            }        case QVariant::String:        {            // Escape '\' characters            r = QSqlDriver::formatValue(field, trimStrings);            r.replace(QLatin1String("\\"), QLatin1String("\\\\"));            break;        }        case QVariant::Bool:            if (field.value().toBool())                r = QLatin1String("TRUE");            else                r = QLatin1String("FALSE");            break;        case QVariant::ByteArray: {            QByteArray ba(field.value().toByteArray());            size_t len;            unsigned char *data = PQescapeBytea((unsigned char*)ba.constData(), ba.size(), &len);            r += QLatin1Char('\'');            r += QLatin1String((const char*)data);            r += QLatin1Char('\'');            qPQfreemem(data);            break;        }        default:            r = QSqlDriver::formatValue(field, trimStrings);            break;        }    }    return r;}QString QPSQLDriver::escapeIdentifier(const QString &identifier, IdentifierType) const{    QString res = identifier;    res.replace(QLatin1Char('"'), QLatin1String("\"\""));    res.prepend(QLatin1Char('"')).append(QLatin1Char('"'));    res.replace(QLatin1Char('.'), QLatin1String("\".\""));    return res;}bool QPSQLDriver::isOpen() const{    return PQstatus(d->connection) == CONNECTION_OK;}QPSQLDriver::Protocol QPSQLDriver::protocol() const{    return d->pro;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -