?? qsql_psql.cpp
字號:
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: 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) { 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) 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); 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); 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 + -