You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
477 lines
22 KiB
477 lines
22 KiB
15 years ago
|
/* This file is part of the KDE project
|
||
|
Copyright (C) 2004-2007 Jaroslaw Staniek <js@iidea.pl>
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Library General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2 of the License, or (at your option) any later version.
|
||
|
|
||
|
This library is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
Library General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Library General Public License
|
||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
* Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
|
||
|
#ifndef KEXIDB_UTILS_H
|
||
|
#define KEXIDB_UTILS_H
|
||
|
|
||
|
#include <qvaluelist.h>
|
||
|
#include <qvariant.h>
|
||
|
|
||
|
#include <kexidb/connection.h>
|
||
|
#include <kexidb/driver.h>
|
||
|
|
||
|
class QDomNode;
|
||
|
class QDomElement;
|
||
|
class QDomDocument;
|
||
|
|
||
|
namespace KexiDB
|
||
|
{
|
||
|
//! for convenience
|
||
|
inline KEXI_DB_EXPORT bool deleteRow(Connection &conn, TableSchema *table,
|
||
|
const QString &keyname, const QString &keyval)
|
||
|
{
|
||
|
return table!=0 && conn.executeSQL("DELETE FROM " + table->name() + " WHERE "
|
||
|
+ keyname + "=" + conn.driver()->valueToSQL( Field::Text, QVariant(keyval) ));
|
||
|
}
|
||
|
|
||
|
inline KEXI_DB_EXPORT bool deleteRow(Connection &conn, const QString &tableName,
|
||
|
const QString &keyname, const QString &keyval)
|
||
|
{
|
||
|
return conn.executeSQL("DELETE FROM " + tableName + " WHERE "
|
||
|
+ keyname + "=" + conn.driver()->valueToSQL( Field::Text, QVariant(keyval) ));
|
||
|
}
|
||
|
|
||
|
inline KEXI_DB_EXPORT bool deleteRow(Connection &conn, TableSchema *table,
|
||
|
const QString &keyname, int keyval)
|
||
|
{
|
||
|
return table!=0 && conn.executeSQL("DELETE FROM " + table->name() + " WHERE "
|
||
|
+ keyname + "=" + conn.driver()->valueToSQL( Field::Integer, QVariant(keyval) ));
|
||
|
}
|
||
|
|
||
|
inline KEXI_DB_EXPORT bool deleteRow(Connection &conn, const QString &tableName,
|
||
|
const QString &keyname, int keyval)
|
||
|
{
|
||
|
return conn.executeSQL("DELETE FROM " + tableName + " WHERE "
|
||
|
+ keyname + "=" + conn.driver()->valueToSQL( Field::Integer, QVariant(keyval) ));
|
||
|
}
|
||
|
|
||
|
/*! Delete row with two generic criterias. */
|
||
|
inline KEXI_DB_EXPORT bool deleteRow(Connection &conn, const QString &tableName,
|
||
|
const QString &keyname1, Field::Type keytype1, const QVariant& keyval1,
|
||
|
const QString &keyname2, Field::Type keytype2, const QVariant& keyval2)
|
||
|
{
|
||
|
return conn.executeSQL("DELETE FROM " + tableName + " WHERE "
|
||
|
+ keyname1 + "=" + conn.driver()->valueToSQL( keytype1, keyval1 )
|
||
|
+ " AND " + keyname2 + "=" + conn.driver()->valueToSQL( keytype2, keyval2 ));
|
||
|
}
|
||
|
|
||
|
inline KEXI_DB_EXPORT bool replaceRow(Connection &conn, TableSchema *table,
|
||
|
const QString &keyname, const QString &keyval, const QString &valname, QVariant val, int ftype)
|
||
|
{
|
||
|
if (!table || !KexiDB::deleteRow(conn, table, keyname, keyval))
|
||
|
return false;
|
||
|
return conn.executeSQL("INSERT INTO " + table->name()
|
||
|
+ " (" + keyname + "," + valname + ") VALUES ("
|
||
|
+ conn.driver()->valueToSQL( Field::Text, QVariant(keyval) ) + ","
|
||
|
+ conn.driver()->valueToSQL( ftype, val) + ")");
|
||
|
}
|
||
|
|
||
|
typedef QValueList<uint> TypeGroupList;
|
||
|
|
||
|
/*! \return list of types for type group \a typeGroup. */
|
||
|
KEXI_DB_EXPORT const TypeGroupList typesForGroup(Field::TypeGroup typeGroup);
|
||
|
|
||
|
/*! \return list of i18n'd type names for type group \a typeGroup. */
|
||
|
KEXI_DB_EXPORT QStringList typeNamesForGroup(Field::TypeGroup typeGroup);
|
||
|
|
||
|
/*! \return list of (not-i18n'd) type names for type group \a typeGroup. */
|
||
|
KEXI_DB_EXPORT QStringList typeStringsForGroup(Field::TypeGroup typeGroup);
|
||
|
|
||
|
/*! \return default field type for type group \a typeGroup,
|
||
|
for example, Field::Integer for Field::IntegerGroup.
|
||
|
It is used e.g. in KexiAlterTableDialog, to properly fill
|
||
|
'type' property when user selects type group for a field. */
|
||
|
KEXI_DB_EXPORT Field::Type defaultTypeForGroup(Field::TypeGroup typeGroup);
|
||
|
|
||
|
/*! \return a slightly simplified type name for \a field.
|
||
|
For BLOB type it returns i18n'd "Image" string or other, depending on the mime type.
|
||
|
For numbers (either floating-point or integer) it returns i18n'd "Number: string.
|
||
|
For other types it the same string as Field::typeGroupName() is returned. */
|
||
|
//! @todo support names of other BLOB subtypes
|
||
|
KEXI_DB_EXPORT QString simplifiedTypeName(const Field& field);
|
||
|
|
||
|
/*! \return true if \a v represents an empty (but not null) value.
|
||
|
Values of some types (as for strings) can be both empty and not null. */
|
||
|
inline bool isEmptyValue(Field *f, const QVariant &v) {
|
||
|
if (f->hasEmptyProperty() && v.toString().isEmpty() && !v.toString().isNull())
|
||
|
return true;
|
||
|
return v.isNull();
|
||
|
}
|
||
|
|
||
|
/*! Sets \a msg to an error message retrieved from object \a obj, and \a details
|
||
|
to details of this error (server message and result number).
|
||
|
Does nothing if \a obj is null or no error occurred.
|
||
|
\a msg and \a details strings are not overwritten.
|
||
|
If \a msg is not empty, \a obj's error message is appended to \a details.
|
||
|
*/
|
||
|
KEXI_DB_EXPORT void getHTMLErrorMesage(Object* obj, QString& msg, QString &details);
|
||
|
|
||
|
/*! This methods works like above, but appends both a message and a description
|
||
|
to \a msg. */
|
||
|
KEXI_DB_EXPORT void getHTMLErrorMesage(Object* obj, QString& msg);
|
||
|
|
||
|
/*! This methods works like above, but works on \a result's members instead. */
|
||
|
KEXI_DB_EXPORT void getHTMLErrorMesage(Object* obj, ResultInfo *result);
|
||
|
|
||
|
/*! Function useful for building WHERE parts of sql statements.
|
||
|
Constructs an sql string like "fielname = value" for specific \a drv driver,
|
||
|
field type \a t, \a fieldName and \a value. If \a value is null, "fieldname is NULL"
|
||
|
string is returned. */
|
||
|
inline KEXI_DB_EXPORT QString sqlWhere(Driver *drv, Field::Type t,
|
||
|
const QString fieldName, const QVariant value)
|
||
|
{
|
||
|
if (value.isNull())
|
||
|
return fieldName + " is NULL";
|
||
|
return fieldName + "=" + drv->valueToSQL( t, value );
|
||
|
}
|
||
|
|
||
|
/*! \return identifier for object \a objName of type \a objType
|
||
|
or 0 if such object does not exist. */
|
||
|
KEXI_DB_EXPORT int idForObjectName( Connection &conn, const QString& objName, int objType );
|
||
|
|
||
|
/*! Variant class providing a pointer to table or query. */
|
||
|
class KEXI_DB_EXPORT TableOrQuerySchema {
|
||
|
public:
|
||
|
/*! Creates a new TableOrQuerySchema variant object, retrieving table or query schema
|
||
|
using \a conn connection and \a name. If both table and query exists for \a name,
|
||
|
table has priority over query.
|
||
|
You should check whether a query or table has been found by testing
|
||
|
(query() || table()) expression. */
|
||
|
TableOrQuerySchema(Connection *conn, const QCString& name);
|
||
|
|
||
|
/*! Creates a new TableOrQuerySchema variant object, retrieving table or query schema
|
||
|
using \a conn connection and \a name. If \a table is true, \a name is assumed
|
||
|
to be a table name, otherwise \a name is assumed to be a query name.
|
||
|
You should check whether a query or table has been found by testing
|
||
|
(query() || table()) expression. */
|
||
|
TableOrQuerySchema(Connection *conn, const QCString& name, bool table);
|
||
|
|
||
|
/*! Creates a new TableOrQuerySchema variant object. \a tableOrQuery must be of
|
||
|
class TableSchema or QuerySchema.
|
||
|
You should check whether a query or table has been found by testing
|
||
|
(query() || table()) expression. */
|
||
|
TableOrQuerySchema(FieldList &tableOrQuery);
|
||
|
|
||
|
/*! Creates a new TableOrQuerySchema variant object, retrieving table or query schema
|
||
|
using \a conn connection and \a id.
|
||
|
You should check whether a query or table has been found by testing
|
||
|
(query() || table()) expression. */
|
||
|
TableOrQuerySchema(Connection *conn, int id);
|
||
|
|
||
|
/*! Creates a new TableOrQuerySchema variant object, keeping a pointer so \a table
|
||
|
object. */
|
||
|
TableOrQuerySchema(TableSchema* table);
|
||
|
|
||
|
/*! Creates a new TableOrQuerySchema variant object, keeping a pointer so \a query
|
||
|
object. */
|
||
|
TableOrQuerySchema(QuerySchema* query);
|
||
|
|
||
|
//! \return a pointer to the query if it's provided
|
||
|
QuerySchema* query() const { return m_query; }
|
||
|
|
||
|
//! \return a pointer to the table if it's provided
|
||
|
TableSchema* table() const { return m_table; }
|
||
|
|
||
|
//! \return name of a query or table
|
||
|
QCString name() const;
|
||
|
|
||
|
//! \return caption (if present) or name of the table/query
|
||
|
QString captionOrName() const;
|
||
|
|
||
|
//! \return number of fields
|
||
|
uint fieldCount() const;
|
||
|
|
||
|
//! \return all columns for the table or the query
|
||
|
const QueryColumnInfo::Vector columns(bool unique = false);
|
||
|
|
||
|
/*! \return a field of the table or the query schema for name \a name
|
||
|
or 0 if there is no such field. */
|
||
|
Field* field(const QString& name);
|
||
|
|
||
|
/*! Like Field* field(const QString& name);
|
||
|
but returns all information associated with field/column \a name. */
|
||
|
QueryColumnInfo* columnInfo(const QString& name);
|
||
|
|
||
|
/*! \return connection object, for table or query or 0 if there's no table or query defined. */
|
||
|
Connection* connection() const;
|
||
|
|
||
|
/*! \return String for debugging purposes. */
|
||
|
QString debugString();
|
||
|
|
||
|
/*! Shows debug information about table or query. */
|
||
|
void debug();
|
||
|
|
||
|
protected:
|
||
|
QCString m_name; //!< the name is kept here because m_table and m_table can be 0
|
||
|
//! and we still want name() and acptionOrName() work.
|
||
|
TableSchema* m_table;
|
||
|
QuerySchema* m_query;
|
||
|
};
|
||
|
|
||
|
//! @todo perhaps use Q_ULLONG here?
|
||
|
/*! \return number of rows that can be retrieved after executing \a sql statement
|
||
|
within a connection \a conn. The statement should be of type SELECT.
|
||
|
For SQL data sources it does not fetch any records, only "COUNT(*)"
|
||
|
SQL aggregation is used at the backed.
|
||
|
-1 is returned if error occured. */
|
||
|
int rowCount(Connection &conn, const QString& sql);
|
||
|
|
||
|
//! @todo perhaps use Q_ULLONG here?
|
||
|
/*! \return number of rows that can be retrieved from \a tableSchema.
|
||
|
The table must be created or retrieved using a Connection object,
|
||
|
i.e. tableSchema.connection() must not return 0.
|
||
|
For SQL data sources it does not fetch any records, only "COUNT(*)"
|
||
|
SQL aggregation is used at the backed.
|
||
|
-1 is returned if error occurred. */
|
||
|
KEXI_DB_EXPORT int rowCount(const TableSchema& tableSchema);
|
||
|
|
||
|
//! @todo perhaps use Q_ULLONG here?
|
||
|
/*! Like above but operates on a query schema. */
|
||
|
KEXI_DB_EXPORT int rowCount(QuerySchema& querySchema);
|
||
|
|
||
|
//! @todo perhaps use Q_ULLONG here?
|
||
|
/*! Like above but operates on a table or query schema variant. */
|
||
|
KEXI_DB_EXPORT int rowCount(TableOrQuerySchema& tableOrQuery);
|
||
|
|
||
|
/*! \return a number of columns that can be retrieved from table or query schema.
|
||
|
In case of query, expanded fields are counted. Can return -1 if \a tableOrQuery
|
||
|
has neither table or query assigned. */
|
||
|
KEXI_DB_EXPORT int fieldCount(TableOrQuerySchema& tableOrQuery);
|
||
|
|
||
|
/*! shows connection test dialog with a progress bar indicating connection testing
|
||
|
(within a second thread).
|
||
|
\a data is used to perform a (temporary) test connection. \a msgHandler is used to display errors.
|
||
|
On successful connecting, a message is displayed. After testing, temporary connection is closed. */
|
||
|
KEXI_DB_EXPORT void connectionTestDialog(QWidget* parent, const ConnectionData& data,
|
||
|
MessageHandler& msgHandler);
|
||
|
|
||
|
/*! Saves connection data \a data into \a map. */
|
||
|
KEXI_DB_EXPORT QMap<QString,QString> toMap( const ConnectionData& data );
|
||
|
|
||
|
/*! Restores connection data \a data from \a map. */
|
||
|
KEXI_DB_EXPORT void fromMap( const QMap<QString,QString>& map, ConnectionData& data );
|
||
|
|
||
|
//! Used in splitToTableAndFieldParts().
|
||
|
enum SplitToTableAndFieldPartsOptions {
|
||
|
FailIfNoTableOrFieldName = 0, //!< default value for splitToTableAndFieldParts()
|
||
|
SetFieldNameIfNoTableName = 1 //!< see splitToTableAndFieldParts()
|
||
|
};
|
||
|
|
||
|
/*! Splits \a string like "table.field" into "table" and "field" parts.
|
||
|
On success, a table name is passed to \a tableName and a field name is passed to \a fieldName.
|
||
|
The function fails if either:
|
||
|
- \a string is empty, or
|
||
|
- \a string does not contain '.' character and \a option is FailIfNoTableOrFieldName
|
||
|
(the default), or
|
||
|
- '.' character is the first of last character of \a string (in this case table name
|
||
|
or field name could become empty what is not allowed).
|
||
|
|
||
|
If \a option is SetFieldNameIfNoTableName and \a string does not contain '.',
|
||
|
\a string is passed to \a fieldName and \a tableName is set to QString::null
|
||
|
without failure.
|
||
|
|
||
|
If function fails, \a tableName and \a fieldName remain unchanged.
|
||
|
\return true on success. */
|
||
|
KEXI_DB_EXPORT bool splitToTableAndFieldParts(const QString& string,
|
||
|
QString& tableName, QString& fieldName,
|
||
|
SplitToTableAndFieldPartsOptions option = FailIfNoTableOrFieldName);
|
||
|
|
||
|
/*! \return true if \a type supports "visibleDecimalPlaces" property. */
|
||
|
KEXI_DB_EXPORT bool supportsVisibleDecimalPlacesProperty(Field::Type type);
|
||
|
|
||
|
/*! \return string constructed by converting \a value.
|
||
|
* If \a decimalPlaces is < 0, all meaningful fractional digits are returned.
|
||
|
* If \a automatically is 0, just integer part is returned.
|
||
|
* If \a automatically is > 0, fractional part should take exactly
|
||
|
N digits: if the fractional part is shorter than N, additional zeros are appended.
|
||
|
For example, "12.345" becomes "12.345000" if N=6.
|
||
|
|
||
|
No rounding is actually performed.
|
||
|
KLocale::formatNumber() and KLocale::decimalSymbol() are used to get locale settings.
|
||
|
|
||
|
@see KexiDB::Field::visibleDecimalPlaces() */
|
||
|
KEXI_DB_EXPORT QString formatNumberForVisibleDecimalPlaces(double value, int decimalPlaces);
|
||
|
|
||
|
//! \return true if \a propertyName is a builtin field property.
|
||
|
KEXI_DB_EXPORT bool isBuiltinTableFieldProperty( const QCString& propertyName );
|
||
|
|
||
|
//! \return true if \a propertyName is an extended field property.
|
||
|
KEXI_DB_EXPORT bool isExtendedTableFieldProperty( const QCString& propertyName );
|
||
|
|
||
|
/*! \return type of field for integer value \a type.
|
||
|
If \a type cannot be casted to KexiDB::Field::Type, KexiDB::Field::InvalidType is returned.
|
||
|
This can be used when type information is deserialized from a string or QVariant. */
|
||
|
KEXI_DB_EXPORT Field::Type intToFieldType( int type );
|
||
|
|
||
|
/*! Sets property values for \a field. \return true if all the values are valid and allowed.
|
||
|
On failure contents of \a field is undefined.
|
||
|
Properties coming from extended schema are also supported.
|
||
|
This function is used e.g. by AlterTableHandler when property information comes in form of text.
|
||
|
*/
|
||
|
KEXI_DB_EXPORT bool setFieldProperties( Field& field, const QMap<QCString, QVariant>& values );
|
||
|
|
||
|
/*! Sets property value for \a field. \return true if the property has been found and
|
||
|
the value is valid for this property. On failure contents of \a field is undefined.
|
||
|
Properties coming from extended schema are also supported as well as
|
||
|
QVariant customProperty(const QString& propertyName) const;
|
||
|
|
||
|
This function is used e.g. by AlterTableHandler when property information comes in form of text.
|
||
|
*/
|
||
|
KEXI_DB_EXPORT bool setFieldProperty(Field& field, const QCString& propertyName,
|
||
|
const QVariant& value);
|
||
|
|
||
|
/*! @return property value loaded from a DOM \a node, written in a QtDesigner-like
|
||
|
notation: <number>int</number> or <bool>bool</bool>, etc. Supported types are
|
||
|
"string", "cstring", "bool", "number". For invalid values null QVariant is returned.
|
||
|
You can check the validity of the returned value using QVariant::type(). */
|
||
|
KEXI_DB_EXPORT QVariant loadPropertyValueFromDom( const QDomNode& node );
|
||
|
|
||
|
/*! Convenience version of loadPropertyValueFromDom(). \return int value. */
|
||
|
KEXI_DB_EXPORT int loadIntPropertyValueFromDom( const QDomNode& node, bool* ok );
|
||
|
|
||
|
/*! Convenience version of loadPropertyValueFromDom(). \return QString value. */
|
||
|
KEXI_DB_EXPORT QString loadStringPropertyValueFromDom( const QDomNode& node, bool* ok );
|
||
|
|
||
|
/*! Saves integer element for value \a value to \a doc document within parent element
|
||
|
\a parentEl. The value will be enclosed in "number" element and "elementName" element.
|
||
|
Example: saveNumberElementToDom(doc, parentEl, "height", 15) will create
|
||
|
\code
|
||
|
<height><number>15</number></height>
|
||
|
\endcode
|
||
|
\return the reference to element created with tag elementName. */
|
||
|
KEXI_DB_EXPORT QDomElement saveNumberElementToDom(QDomDocument& doc, QDomElement& parentEl,
|
||
|
const QString& elementName, int value);
|
||
|
|
||
|
/*! Saves boolean element for value \a value to \a doc document within parent element
|
||
|
\a parentEl. Like saveNumberElementToDom() but creates "bool" tags. True/false values will be
|
||
|
saved as "true"/"false" strings.
|
||
|
\return the reference to element created with tag elementName. */
|
||
|
KEXI_DB_EXPORT QDomElement saveBooleanElementToDom(QDomDocument& doc, QDomElement& parentEl,
|
||
|
const QString& elementName, bool value);
|
||
|
|
||
|
/*! \return an empty value that can be set for a database field of type \a type having
|
||
|
"null" property set. Empty string is returned for text type, 0 for integer
|
||
|
or floating-point types, false for boolean type, empty null byte array for BLOB type.
|
||
|
For date, time and date/time types current date, time, date+time is returned, respectively.
|
||
|
Returns null QVariant for unsupported values like KexiDB::Field::InvalidType.
|
||
|
This function is efficient (uses a cache) and is heavily used by the AlterTableHandler
|
||
|
for filling new columns. */
|
||
|
KEXI_DB_EXPORT QVariant emptyValueForType( Field::Type type );
|
||
|
|
||
|
/*! \return a value that can be set for a database field of type \a type having
|
||
|
"notEmpty" property set. It works in a similar way as
|
||
|
@ref QVariant emptyValueForType( KexiDB::Field::Type type ) with the following differences:
|
||
|
- " " string (a single space) is returned for Text and LongText types
|
||
|
- a byte array with saved "filenew" PNG image (icon) for BLOB type
|
||
|
Returns null QVariant for unsupported values like KexiDB::Field::InvalidType.
|
||
|
This function is efficient (uses a cache) and is heavily used by the AlterTableHandler
|
||
|
for filling new columns. */
|
||
|
KEXI_DB_EXPORT QVariant notEmptyValueForType( Field::Type type );
|
||
|
|
||
|
//! Escaping types used in escapeBLOB().
|
||
|
enum BLOBEscapingType {
|
||
|
BLOBEscapeXHex = 1, //!< escaping like X'1FAD', used by sqlite (hex numbers)
|
||
|
BLOBEscape0xHex, //!< escaping like 0x1FAD, used by mysql (hex numbers)
|
||
|
BLOBEscapeHex, //!< escaping like 1FAD without quotes or prefixes
|
||
|
BLOBEscapeOctal //!< escaping like 'zk\\000$x', used by pgsql
|
||
|
//!< (only non-printable characters are escaped using octal numbers)
|
||
|
//!< See http://www.postgresql.org/docs/8.1/interactive/datatype-binary.html
|
||
|
};
|
||
|
|
||
|
//! @todo reverse function for BLOBEscapeOctal is available: processBinaryData() in pqxxcursor.cpp - move it here
|
||
|
/*! \return a string containing escaped, printable representation of \a array.
|
||
|
Escaping is controlled by \a type. For empty array QString::null is returned,
|
||
|
so if you want to use this function in an SQL statement, empty arrays should be
|
||
|
detected and "NULL" string should be put instead.
|
||
|
This is helper, used in Driver::escapeBLOB() and KexiDB::variantToString(). */
|
||
|
KEXI_DB_EXPORT QString escapeBLOB(const QByteArray& array, BLOBEscapingType type);
|
||
|
|
||
|
/*! \return byte array converted from \a data of length \a length.
|
||
|
\a data is escaped in format used by PostgreSQL's bytea datatype
|
||
|
described at http://www.postgresql.org/docs/8.1/interactive/datatype-binary.html
|
||
|
This function is used by PostgreSQL KexiDB and migration drivers. */
|
||
|
KEXI_DB_EXPORT QByteArray pgsqlByteaToByteArray(const char* data, int length);
|
||
|
|
||
|
/*! \return string value serialized from a variant value \a v.
|
||
|
This functions works like QVariant::toString() except the case when \a v is of type ByteArray.
|
||
|
In this case KexiDB::escapeBLOB(v.toByteArray(), KexiDB::BLOBEscapeHex) is used.
|
||
|
This function is needed for handling values of random type, for example "defaultValue"
|
||
|
property of table fields can contain value of any type.
|
||
|
Note: the returned string is an unescaped string. */
|
||
|
KEXI_DB_EXPORT QString variantToString( const QVariant& v );
|
||
|
|
||
|
/*! \return variant value of type \a type for a string \a s that was previously serialized using
|
||
|
\ref variantToString( const QVariant& v ) function.
|
||
|
\a ok is set to the result of the operation. */
|
||
|
KEXI_DB_EXPORT QVariant stringToVariant( const QString& s, QVariant::Type type, bool &ok );
|
||
|
|
||
|
/*! \return true if setting default value for \a field field is allowed. Fields with unique
|
||
|
(and thus primary key) flags set do not accept default values.
|
||
|
False is returned aslo if \a field is 0. */
|
||
|
KEXI_DB_EXPORT bool isDefaultValueAllowed( Field* field );
|
||
|
|
||
|
/*! Gets limits for values of type \a type. The result is put into \a minValue and \a maxValue.
|
||
|
Supported types are Byte, ShortInteger, Integer and BigInteger
|
||
|
Results for BigInteger or non-integer types are the same as for Integer due
|
||
|
to limitation of int type.
|
||
|
Signed integers are assumed. */
|
||
|
//! @todo add support for unsigned flag
|
||
|
KEXI_DB_EXPORT void getLimitsForType(Field::Type type, int &minValue, int &maxValue);
|
||
|
|
||
|
/*! Shows debug information about \a rowData row data. */
|
||
|
KEXI_DB_EXPORT void debugRowData(const RowData& rowData);
|
||
|
|
||
|
/*! \return type that's maximum of two integer types \a t1 and \a t2, e.g. Integer for (Byte, Integer).
|
||
|
If one of the types is not of the integer group, Field::InvalidType is returned. */
|
||
|
KEXI_DB_EXPORT Field::Type maximumForIntegerTypes(Field::Type t1, Field::Type t2);
|
||
|
|
||
|
/*! \return QVariant value converted from null-terminated \a data string.
|
||
|
In case of BLOB type, \a data is not nul lterminated, so passing length is needed. */
|
||
|
inline QVariant cstringToVariant(const char* data, KexiDB::Field* f, int length = -1)
|
||
|
{
|
||
|
if (!data)
|
||
|
return QVariant();
|
||
|
// from mo st to least frequently used types:
|
||
|
|
||
|
if (!f || f->isTextType())
|
||
|
return QString::fromUtf8(data, length);
|
||
|
if (f->isIntegerType()) {
|
||
|
if (f->type()==KexiDB::Field::BigInteger)
|
||
|
return QVariant( QString::fromLatin1(data, length).toLongLong() );
|
||
|
return QVariant( QString::fromLatin1(data, length).toInt() );
|
||
|
}
|
||
|
if (f->isFPNumericType())
|
||
|
return QString::fromLatin1(data, length).toDouble();
|
||
|
if (f->type()==KexiDB::Field::BLOB) {
|
||
|
QByteArray ba;
|
||
|
ba.duplicate(data, length);
|
||
|
return ba;
|
||
|
}
|
||
|
// the default
|
||
|
//! @todo date/time?
|
||
|
QVariant result(QString::fromUtf8(data, length));
|
||
|
if (!result.cast( KexiDB::Field::variantType(f->type()) ))
|
||
|
return QVariant();
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|