//================================================================================== //Return the value for a given column for the current record - Private const version QVariant pqxxSqlCursor::pValue(uint pos)const { if (m_res->size() <= 0) { KexiDBDrvWarn << "pqxxSqlCursor::value - ERROR: result size not greater than 0" << endl; return QVariant(); } if (pos>=(m_fieldCount+(m_containsROWIDInfo ? 1 : 0))) { // KexiDBDrvWarn << "pqxxSqlCursor::value - ERROR: requested position is greater than the number of fields" << endl; return QVariant(); } KexiDB::Field *f = (m_fieldsExpanded && pos<QMIN(m_fieldsExpanded->count(), m_fieldCount)) ? m_fieldsExpanded->at(pos)->field : 0; // KexiDBDrvDbg << "pqxxSqlCursor::value(" << pos << ")" << endl; //from most to least frequently used types: if (f) //We probably have a schema type query so can use kexi to determin the row type { if ((f->isIntegerType()) || (/*ROWID*/!f && m_containsROWIDInfo && pos==m_fieldCount)) { return (*m_res)[at()][pos].as(int()); } else if (f->isTextType()) { return QString::fromUtf8((*m_res)[at()][pos].c_str()); //utf8? } else if (f->isFPNumericType()) { return (*m_res)[at()][pos].as(double()); } else if (f->typeGroup() == Field::BLOBGroup) { // pqxx::result::field r = (*m_res)[at()][pos]; // kdDebug() << r.name() << ", " << r.c_str() << ", " << r.type() << ", " << r.size() << endl; return ::pgsqlByteaToByteArray((*m_res)[at()][pos]); } } else // We probably have a raw type query so use pqxx to determin the column type { return pgsqlCStrToVariant((*m_res)[at()][pos]); } return QString::fromUtf8((*m_res)[at()][pos].c_str(), (*m_res)[at()][pos].size()); //utf8? }
/* ************************************************************************** */ bool MDBMigrate::drv_readTableSchema(const QString& originalName, KexiDB::TableSchema& tableSchema) { // Get the column meta-data MdbTableDef *tableDef = getTableDef(originalName); if (!tableDef) { kDebug() << "MDBMigrate::drv_getTableDef: couldn't find table " << originalName; return false; } mdb_read_columns(tableDef); kDebug() << "MDBMigrate::drv_readTableSchema: #cols = " << tableDef->num_cols; /*! Convert column data to Kexi TableSchema Nice mix of terminology here, MDBTools has columns, Kexi has fields. */ MdbColumn *col; for (unsigned int i = 0; i < tableDef->num_cols; i++) { col = (MdbColumn*) g_ptr_array_index(tableDef->columns, i); // Field name QString fldName = QString::fromUtf8(col->name); kDebug() << "MDBMigrate::drv_readTableSchema: got column " << fldName << "\"" << col->name; QString fldID(KexiUtils::string2Identifier(fldName)); // Field type KexiDB::Field *fld = new KexiDB::Field(fldID, type(col->col_type)); kDebug() << "MDBMigrate::drv_readTableSchema: size " << col->col_size << " type " << type(col->col_type); fld->setCaption(fldName); tableSchema.addField(fld); } getPrimaryKey(&tableSchema, tableDef); // Free the column meta-data - as soon as it doesn't seg fault. //mdb_free_tabledef(tableDef); return true; }
/*! Get the types and properties for each column. */ bool MySQLMigrate::drv_readTableSchema( const QString& originalName, KexiDB::TableSchema& tableSchema) { // m_table = new KexiDB::TableSchema(table); // //TODO IDEA: ask for user input for captions // tableSchema.setCaption(table + " table"); //Perform a query on the table to get some data QString query = QString("SELECT * FROM `") + drv_escapeIdentifier(originalName) + "` LIMIT 0"; if(d->executeSQL(query)) { MYSQL_RES *res = mysql_store_result(d->mysql); if (res != NULL) { unsigned int numFlds = mysql_num_fields(res); MYSQL_FIELD *fields = mysql_fetch_fields(res); for(unsigned int i = 0; i < numFlds; i++) { QString fldName(fields[i].name); QString fldID( KexiUtils::string2Identifier(fldName) ); KexiDB::Field *fld = new KexiDB::Field(fldID, type(originalName, &fields[i])); if(fld->type() == KexiDB::Field::Enum) { QStringList values = examineEnumField(originalName, &fields[i]); } fld->setCaption(fldName); getConstraints(fields[i].flags, fld); getOptions(fields[i].flags, fld); tableSchema.addField(fld); } mysql_free_result(res); } else { kdDebug() << "MySQLMigrate::drv_tableNames: null result" << endl; } return true; } else { return false; } }
void KexiDataSourcePage::slotFieldSelected() { KexiDB::Field::Type dataType = KexiDB::Field::InvalidType; #ifdef KEXI_NO_AUTOFIELD_WIDGET KexiDB::Field *field = m_tableOrQuerySchema->field( m_widgetDataSourceCombo->fieldOrExpression()); //temp #else //! @todo this should also work for expressions KexiDB::Field *field = m_fieldListView->schema()->field( m_widgetDataSourceCombo->fieldOrExpression()); #endif if (field) dataType = field->type(); emit dataSourceFieldOrExpressionChanged( m_widgetDataSourceCombo->fieldOrExpression(), m_widgetDataSourceCombo->fieldOrExpressionCaption(), dataType ); }
bool OdbMigrate::drv_readTableSchema( const QString& originalName, KexiDB::TableSchema& tableSchema) { char* tableName=originalName.toAscii().data(); jmethodID getTableNames = env->GetMethodID(clsH,"getTableSchema","(Ljava/lang/String;)Ljava/lang/String;"); jstring returnString = (jstring) env->CallObjectMethod(java_class_object,getTableNames,tableName); const char* tablesstring = env->GetStringUTFChars(returnString, NULL); QString jsonString(tablesstring); QStringList list = jsonString.split(","); for(int i=0;i<list.size();i+=2) { QString fldID(KexiUtils::stringToIdentifier(list.at(i+1))); KexiDB::Field *fld = new KexiDB::Field(fldID, type(list.at(i+1))); fld->setCaption(list.at(i)); tableSchema.addField(fld); } return false; }
KexiTableEdit* KexiCellEditorFactory::createEditor(KexiTableViewColumn &column, QWidget* parent) { KexiDB::Field *realField; if (column.visibleLookupColumnInfo()) { realField = column.visibleLookupColumnInfo()->field; } else { realField = column.field(); } KexiCellEditorFactoryItem *item = 0; if (hasEnumType(column)) { //--we need to create combo box because of relationship: item = KexiCellEditorFactory::item(KexiDB::Field::Enum); } else { item = KexiCellEditorFactory::item(realField->type(), realField->subType()); } #if 0 //js: TODO LATER //--check if we need to create combo box because of relationship: //WARNING: it's assumed that indices are one-field long KexiDB::TableSchema *table = f.table(); if (table) { //find index that contain this field KexiDB::IndexSchema::ListIterator it = table->indicesIterator(); for (;it.current();++it) { KexiDB::IndexSchema *idx = it.current(); if (idx->fields()->contains(&f)) { //find details-side rel. for this index KexiDB::Relationship *rel = idx->detailsRelationships()->first(); if (rel) { } } } } #endif return item->createEditor(column, parent); }
void KexiTableEdit::setupContents( QPainter *p, bool focused, const QVariant& val, QString &txt, int &align, int &/*x*/, int &y_offset, int &w, int &h ) { Q_UNUSED(p); Q_UNUSED(focused); Q_UNUSED(h); KexiDB::Field *realField = displayedField(); #ifdef Q_WS_WIN // x = 1; y_offset = -1; #else // x = 1; y_offset = 0; #endif if (realField->isFPNumericType()) { //! @todo ADD OPTION to displaying NULL VALUES as e.g. "(null)" if (!val.isNull()) { txt = KexiDB::formatNumberForVisibleDecimalPlaces( val.toDouble(), realField->visibleDecimalPlaces()); } w -= 6; align |= AlignRight; } else if (realField->isIntegerType()) { Q_LLONG num = val.toLongLong(); w -= 6; align |= AlignRight; if (!val.isNull()) txt = QString::number(num); } else {//default: if (!val.isNull()) { txt = val.toString(); } align |= AlignLeft; } }
void KexiDataSourcePage::slotFieldSelected() { KexiDB::Field::Type dataType = KexiDB::Field::InvalidType; #ifdef KEXI_NO_AUTOFIELD_WIDGET KexiDB::Field *field = m_tableOrQuerySchema->field( m_widgetDataSourceCombo->fieldOrExpression()); //temp #else //! @todo this should also work for expressions KexiDB::Field *field = m_fieldListView->schema()->field( m_widgetDataSourceCombo->fieldOrExpression()); #endif if (field) dataType = field->type(); /*2.0: clear button is available in the combobox itself m_clearWidgetDSButton->setEnabled(!m_widgetDataSourceCombo->fieldOrExpression().isEmpty());*/ emit dataSourceFieldOrExpressionChanged( m_widgetDataSourceCombo->fieldOrExpression(), m_widgetDataSourceCombo->fieldOrExpressionCaption(), dataType ); }
//================================================================================== //This is probably going to be quite complex...need to get the types for all columns //any any other attributes required by kexi //helped by reading the 'tables' test program bool PqxxMigrate::drv_readTableSchema( const QString& originalName, KexiDB::TableSchema& tableSchema) { // m_table = new KexiDB::TableSchema(table); //TODO IDEA: ask for user input for captions //moved m_table->setCaption(table + " table"); //Perform a query on the table to get some data kDebug(); tableSchema.setName(originalName); if (!query("select * from " + drv_escapeIdentifier(originalName) + " limit 1")) return false; //Loop round the fields for (uint i = 0; i < (uint)m_res->columns(); i++) { QString fldName(m_res->column_name(i)); KexiDB::Field::Type fldType = type(m_res->column_type(i), fldName); QString fldID(KexiUtils::string2Identifier(fldName)); const pqxx::oid toid = tableOid(originalName); if (toid == 0) return false; KexiDB::Field *f = new KexiDB::Field(fldID, fldType); f->setCaption(fldName); f->setPrimaryKey(primaryKey(toid, i)); f->setUniqueKey(uniqueKey(toid, i)); f->setAutoIncrement(autoInc(toid, i));//This should be safe for all field types tableSchema.addField(f); // Do this for var/char types //m_f->setLength(m_res->at(0)[i].size()); // Do this for numeric type /*m_f->setScale(0); m_f->setPrecision(0);*/ kDebug() << "Added field [" << f->name() << "] type [" << f->typeName() << ']'; } return true; }
bool SQLitePreparedStatement::execute() { #ifdef SQLITE2 //! @todo #else if (!prepared_st_handle) return false; if (m_resetRequired) { res = sqlite3_reset(prepared_st_handle); if (SQLITE_OK != res) { //! @todo msg? return false; } m_resetRequired = false; } int arg=1; //arg index counted from 1 KexiDB::Field *field; Field::List _dummy; Field::ListIterator itFields(_dummy); //for INSERT, we're iterating over inserting values //for SELECT, we're iterating over WHERE conditions if (m_type == SelectStatement) itFields = *m_whereFields; else if (m_type == InsertStatement) itFields = m_fields->fieldsIterator(); else assert(0); //impl. error for (QValueListConstIterator<QVariant> it = m_args.constBegin(); (field = itFields.current()); ++it, ++itFields, arg++) { if (it==m_args.constEnd() || (*it).isNull()) {//no value to bind or the value is null: bind NULL res = sqlite3_bind_null(prepared_st_handle, arg); if (SQLITE_OK != res) { //! @todo msg? return false; } continue; } if (field->isTextType()) { //! @todo optimize: make a static copy so SQLITE_STATIC can be used QCString utf8String((*it).toString().utf8()); res = sqlite3_bind_text(prepared_st_handle, arg, (const char*)utf8String, utf8String.length(), SQLITE_TRANSIENT /*??*/); if (SQLITE_OK != res) { //! @todo msg? return false; } } else switch (field->type()) { case KexiDB::Field::Byte: case KexiDB::Field::ShortInteger: case KexiDB::Field::Integer: { //! @todo what about unsigned > INT_MAX ? bool ok; const int value = (*it).toInt(&ok); if (ok) { res = sqlite3_bind_int(prepared_st_handle, arg, value); if (SQLITE_OK != res) { //! @todo msg? return false; } } else { res = sqlite3_bind_null(prepared_st_handle, arg); if (SQLITE_OK != res) { //! @todo msg? return false; } } break; } case KexiDB::Field::Float: case KexiDB::Field::Double: res = sqlite3_bind_double(prepared_st_handle, arg, (*it).toDouble()); if (SQLITE_OK != res) { //! @todo msg? return false; } break; case KexiDB::Field::BigInteger: { //! @todo what about unsigned > LLONG_MAX ? bool ok; Q_LLONG value = (*it).toLongLong(&ok); if (ok) { res = sqlite3_bind_int64(prepared_st_handle, arg, value); if (SQLITE_OK != res) { //! @todo msg? return false; } } else { res = sqlite3_bind_null(prepared_st_handle, arg); if (SQLITE_OK != res) { //! @todo msg? return false; } } break; } case KexiDB::Field::Boolean: res = sqlite3_bind_text(prepared_st_handle, arg, QString::number((*it).toBool() ? 1 : 0).latin1(), 1, SQLITE_TRANSIENT /*??*/); if (SQLITE_OK != res) { //! @todo msg? return false; } break; case KexiDB::Field::Time: res = sqlite3_bind_text(prepared_st_handle, arg, (*it).toTime().toString(Qt::ISODate).latin1(), sizeof("HH:MM:SS"), SQLITE_TRANSIENT /*??*/); if (SQLITE_OK != res) { //! @todo msg? return false; } break; case KexiDB::Field::Date: res = sqlite3_bind_text(prepared_st_handle, arg, (*it).toDate().toString(Qt::ISODate).latin1(), sizeof("YYYY-MM-DD"), SQLITE_TRANSIENT /*??*/); if (SQLITE_OK != res) { //! @todo msg? return false; } break; case KexiDB::Field::DateTime: res = sqlite3_bind_text(prepared_st_handle, arg, (*it).toDateTime().toString(Qt::ISODate).latin1(), sizeof("YYYY-MM-DDTHH:MM:SS"), SQLITE_TRANSIENT /*??*/); if (SQLITE_OK != res) { //! @todo msg? return false; } break; case KexiDB::Field::BLOB: { const QByteArray byteArray((*it).toByteArray()); res = sqlite3_bind_blob(prepared_st_handle, arg, (const char*)byteArray, byteArray.size(), SQLITE_TRANSIENT /*??*/); if (SQLITE_OK != res) { //! @todo msg? return false; } break; } default: KexiDBWarn << "PreparedStatement::execute(): unsupported field type: " << field->type() << " - NULL value bound to column #" << arg << endl; res = sqlite3_bind_null(prepared_st_handle, arg); if (SQLITE_OK != res) { //! @todo msg? return false; } } //switch } //real execution res = sqlite3_step(prepared_st_handle); m_resetRequired = true; if (m_type == InsertStatement && res == SQLITE_DONE) { return true; } if (m_type == SelectStatement) { //fetch result //todo } #endif return false; }
bool Authenticator::loadStore() { KexiDB::TableSchema* table = KexiWebForms::Model::gConnection->tableSchema("kexi__users"); if (!table) { // the table doesn't exist, create it (programmatically) kDebug() << "kexi__users table does not exist, creating it"; KexiDB::TableSchema* kexi__users = new KexiDB::TableSchema("kexi__users"); kexi__users->setNative(true); KexiDB::Field* id = new KexiDB::Field("u_id", KexiDB::Field::Integer); id->setAutoIncrement(true); id->setPrimaryKey(true); kexi__users->insertField(0, id); KexiDB::Field* name = new KexiDB::Field("u_name", KexiDB::Field::Text); kexi__users->insertField(1, name); KexiDB::Field* password = new KexiDB::Field("u_password", KexiDB::Field::Text); kexi__users->insertField(2, password); KexiDB::Field* create = new KexiDB::Field("u_create", KexiDB::Field::Boolean); kexi__users->insertField(3, create); KexiDB::Field* read = new KexiDB::Field("u_read", KexiDB::Field::Boolean); kexi__users->insertField(4, read); KexiDB::Field* update = new KexiDB::Field("u_update", KexiDB::Field::Boolean); kexi__users->insertField(5, update); KexiDB::Field* fdelete = new KexiDB::Field("u_delete", KexiDB::Field::Boolean); kexi__users->insertField(6, fdelete); KexiDB::Field* fquery = new KexiDB::Field("u_query", KexiDB::Field::Boolean); kexi__users->insertField(7, fquery); if (!KexiWebForms::Model::gConnection->createTable(kexi__users)) { // Table was not created, fatal error kError() << "Failed to create system table kexi__users"; kError() << "Error string: " << KexiWebForms::Model::gConnection->errorMsg(); delete kexi__users; return false; } else { // Table was created, create two standard accounts KexiDB::QuerySchema query(*kexi__users); KexiDB::Cursor* cursor = KexiWebForms::Model::gConnection->prepareQuery(query); KexiDB::RecordData recordData(kexi__users->fieldCount()); KexiDB::RowEditBuffer editBuffer(true); // root QVariant vtrue(true); QVariant vfalse(false); kDebug() << "Creating user root with password root"; QVariant user_root("root"); QVariant password_root("root"); editBuffer.insert(*query.columnInfo(name->name()), user_root); editBuffer.insert(*query.columnInfo(password->name()), password_root); editBuffer.insert(*query.columnInfo(create->name()), vtrue); editBuffer.insert(*query.columnInfo(read->name()), vtrue); editBuffer.insert(*query.columnInfo(update->name()), vtrue); editBuffer.insert(*query.columnInfo(fdelete->name()), vtrue); editBuffer.insert(*query.columnInfo(fquery->name()), vtrue); kDebug() << "Registering user within database"; if (cursor->insertRow(recordData, editBuffer)) { kDebug() << "Succeeded"; User* u = new User("root", "root"); m_users.append(*u); m_auth->addUser(u->name().toUtf8().constData(), u->password().toUtf8().constData()); } else { kError() << "An error occurred"; return false; } // anonymous kDebug() << "Creating user anonymous with password guest"; QVariant user_anonymous("anonymous"); QVariant password_anonymous("guest"); editBuffer.insert(*query.columnInfo(name->name()), user_anonymous); editBuffer.insert(*query.columnInfo(password->name()), password_anonymous); editBuffer.insert(*query.columnInfo(create->name()), vfalse); editBuffer.insert(*query.columnInfo(read->name()), vfalse); editBuffer.insert(*query.columnInfo(update->name()), vfalse); editBuffer.insert(*query.columnInfo(fdelete->name()), vfalse); editBuffer.insert(*query.columnInfo(fquery->name()), vfalse); if (cursor->insertRow(recordData, editBuffer)) { kDebug() << "Succeeded"; User* u = new User("anonymous", "guest"); m_users.append(*u); m_auth->addUser(u->name().toUtf8().constData(), u->password().toUtf8().constData()); } else { kError() << "An error occurred"; return false; } KexiWebForms::Model::gConnection->deleteCursor(cursor); } } else { // load stuff from the store, create appropriated User objects, store them within // Authenticator KexiDB::QuerySchema query(*table); KexiDB::Cursor* cursor = KexiWebForms::Model::gConnection->executeQuery(query); while (cursor->moveNext()) { // Skip id QString* username = new QString(cursor->value(1).toString()); QString* password = new QString(cursor->value(2).toString()); QList<Permission>* perms = new QList<Permission>; if (cursor->value(3).toBool()) perms->append(CREATE); if (cursor->value(4).toBool()) perms->append(READ); if (cursor->value(5).toBool()) perms->append(UPDATE); if (cursor->value(6).toBool()) perms->append(DELETE); if (cursor->value(7).toBool()) perms->append(QUERY); User* u = new User(*username, *password, *perms); m_users.append(*u); m_auth->addUser(u->name().toUtf8().constData(), u->password().toUtf8().constData()); kDebug() << "Loaded user " << *username << " from store"; } } return true; }
bool MDBMigrate::getPrimaryKey(KexiDB::TableSchema* table, MdbTableDef* tableDef) { MdbIndex *idx; if (!tableDef) { return false; } mdb_read_columns(tableDef); mdb_read_indices(tableDef); // Find the PK index in the MDB file bool foundIdx = false; for (unsigned int i = 0; i < tableDef->num_idxs; i++) { idx = (MdbIndex*) g_ptr_array_index(tableDef->indices, i); // QString fldName = QString::fromUtf8(idx->name); if (!strcmp(idx->name, "PrimaryKey")) { idx = (MdbIndex*) g_ptr_array_index(tableDef->indices, i); foundIdx = true; break; } } if (!foundIdx) { mdb_free_indices(tableDef->indices); return false; } //! @todo: MDB index order (asc, desc) kDebug() << "num_keys" << idx->num_keys; //! Create the KexiDB IndexSchema ... QVector<int> key_col_num(idx->num_keys); // MDBTools counts columns from 1 - subtract 1 where necessary KexiDB::IndexSchema* p_idx = new KexiDB::IndexSchema(table); for (unsigned int i = 0; i < idx->num_keys; i++) { key_col_num[i] = idx->key_col_num[i]; kDebug() << "key" << i + 1 << " col " << key_col_num[i] << table->field(idx->key_col_num[i] - 1)->name() ; p_idx->addField(table->field(idx->key_col_num[i] - 1)); } kDebug() << p_idx->debugString(); // ... and add it to the table definition // but only if the PK has only one field, so far :o( KexiDB::Field *f; if (idx->num_keys == 1 && (f = table->field(idx->key_col_num[0] - 1))) { f->setPrimaryKey(true); } else { //! @todo: How to add a composite PK to a TableSchema? //m_table->setPrimaryKey(p_idx); } mdb_free_indices(tableDef->indices); return true; }