kexi
tableschema.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "tableschema.h"
00022 #include "driver.h"
00023 #include "connection.h"
00024 #include "lookupfieldschema.h"
00025
00026 #include <assert.h>
00027 #include <kdebug.h>
00028
00029 namespace KexiDB {
00031 class TableSchema::Private
00032 {
00033 public:
00034 Private()
00035 : anyNonPKField(0)
00036 {
00037 }
00038
00039 ~Private()
00040 {
00041 clearLookupFields();
00042 }
00043
00044 void clearLookupFields()
00045 {
00046 for (QMap<const Field*, LookupFieldSchema*>::ConstIterator it = lookupFields.constBegin();
00047 it!=lookupFields.constEnd(); ++it)
00048 {
00049 delete it.data();
00050 }
00051 lookupFields.clear();
00052 }
00053
00054 Field *anyNonPKField;
00055 QMap<const Field*, LookupFieldSchema*> lookupFields;
00056 QPtrVector<LookupFieldSchema> lookupFieldsList;
00057 };
00058 }
00059
00060
00061
00062 using namespace KexiDB;
00063
00064 TableSchema::TableSchema(const QString& name)
00065 : FieldList(true)
00066 , SchemaData(KexiDB::TableObjectType)
00067 , m_query(0)
00068 , m_isKexiDBSystem(false)
00069 {
00070 m_name = name.lower();
00071 init();
00072 }
00073
00074 TableSchema::TableSchema(const SchemaData& sdata)
00075 : FieldList(true)
00076 , SchemaData(sdata)
00077 , m_query(0)
00078 , m_isKexiDBSystem(false)
00079 {
00080 init();
00081 }
00082
00083 TableSchema::TableSchema()
00084 : FieldList(true)
00085 , SchemaData(KexiDB::TableObjectType)
00086 , m_query(0)
00087 , m_isKexiDBSystem(false)
00088 {
00089 init();
00090 }
00091
00092 TableSchema::TableSchema(const TableSchema& ts, bool copyId)
00093 : FieldList(static_cast<const FieldList&>(ts))
00094 , SchemaData(static_cast<const SchemaData&>(ts))
00095 {
00096 init(ts, copyId);
00097 }
00098
00099 TableSchema::TableSchema(const TableSchema& ts, int setId)
00100 : FieldList(static_cast<const FieldList&>(ts))
00101 , SchemaData(static_cast<const SchemaData&>(ts))
00102 {
00103 init(ts, false);
00104 m_id = setId;
00105 }
00106
00107
00108 TableSchema::TableSchema(Connection *conn, const QString & name)
00109 : FieldList(true)
00110 , SchemaData(KexiDB::TableObjectType)
00111 , m_conn( conn )
00112 , m_query(0)
00113 , m_isKexiDBSystem(false)
00114 {
00115 d = new Private();
00116 assert(conn);
00117 m_name = name;
00118 m_indices.setAutoDelete( true );
00119 m_pkey = new IndexSchema(this);
00120 m_indices.append(m_pkey);
00121 }
00122
00123 TableSchema::~TableSchema()
00124 {
00125 if (m_conn)
00126 m_conn->removeMe( this );
00127 delete m_query;
00128 delete d;
00129 }
00130
00131 void TableSchema::init()
00132 {
00133 d = new Private();
00134 m_indices.setAutoDelete( true );
00135 m_pkey = new IndexSchema(this);
00136 m_indices.append(m_pkey);
00137 }
00138
00139 void TableSchema::init(const TableSchema& ts, bool copyId)
00140 {
00141 m_conn = ts.m_conn;
00142 m_query = 0;
00143 m_isKexiDBSystem = false;
00144 d = new Private();
00145 m_name = ts.m_name;
00146 m_indices.setAutoDelete( true );
00147 m_pkey = 0;
00148 if (!copyId)
00149 m_id = -1;
00150
00151
00152 IndexSchema::ListIterator idx_it(ts.m_indices);
00153 for (;idx_it.current();++idx_it) {
00154 IndexSchema *idx = new IndexSchema(
00155 *idx_it.current(), *this );
00156 if (idx->isPrimaryKey()) {
00157 m_pkey = idx;
00158 }
00159 m_indices.append(idx);
00160 }
00161 }
00162
00163 void TableSchema::setPrimaryKey(IndexSchema *pkey)
00164 {
00165 if (m_pkey && m_pkey!=pkey) {
00166 if (m_pkey->fieldCount()==0) {
00167 m_indices.remove(m_pkey);
00168 }
00169 else {
00170 m_pkey->setPrimaryKey(false);
00171
00172 }
00173
00174 }
00175
00176 if (!pkey) {
00177 pkey = new IndexSchema(this);
00178 }
00179 m_pkey = pkey;
00180 m_pkey->setPrimaryKey(true);
00181 d->anyNonPKField = 0;
00182 }
00183
00184 FieldList& TableSchema::insertField(uint index, Field *field)
00185 {
00186 assert(field);
00187 FieldList::insertField(index, field);
00188 if (!field || index>m_fields.count())
00189 return *this;
00190 field->setTable(this);
00191 field->m_order = index;
00192
00193 Field *f = m_fields.at(index+1);
00194 for (int i=index+1; f; i++, f = m_fields.next())
00195 f->m_order = i;
00196
00197
00198 IndexSchema *idx = 0;
00199 if (field->isPrimaryKey()) {
00200 idx = new IndexSchema(this);
00201 idx->setAutoGenerated(true);
00202 idx->addField( field );
00203 setPrimaryKey(idx);
00204 }
00205 if (field->isUniqueKey()) {
00206 if (!idx) {
00207 idx = new IndexSchema(this);
00208 idx->setAutoGenerated(true);
00209 idx->addField( field );
00210 }
00211 idx->setUnique(true);
00212 }
00213 if (field->isIndexed()) {
00214 if (!idx) {
00215 idx = new IndexSchema(this);
00216 idx->setAutoGenerated(true);
00217 idx->addField( field );
00218 }
00219 }
00220 if (idx)
00221 m_indices.append(idx);
00222 return *this;
00223 }
00224
00225 void TableSchema::removeField(KexiDB::Field *field)
00226 {
00227 if (d->anyNonPKField && field == d->anyNonPKField)
00228 d->anyNonPKField = 0;
00229 delete d->lookupFields[field];
00230 d->lookupFields.remove(field);
00231 FieldList::removeField(field);
00232 }
00233
00234 #if 0 //original
00235 KexiDB::FieldList& TableSchema::addField(KexiDB::Field* field)
00236 {
00237 assert(field);
00238 FieldList::addField(field);
00239 field->setTable(this);
00240 field->m_order = m_fields.count();
00241
00242
00243 IndexSchema *idx = 0;
00244 if (field->isPrimaryKey()) {
00245 idx = new IndexSchema(this);
00246 idx->setAutoGenerated(true);
00247 idx->addField( field );
00248 setPrimaryKey(idx);
00249 }
00250 if (field->isUniqueKey()) {
00251 if (!idx) {
00252 idx = new IndexSchema(this);
00253 idx->setAutoGenerated(true);
00254 idx->addField( field );
00255 }
00256 idx->setUnique(true);
00257 }
00258 if (field->isIndexed()) {
00259 if (!idx) {
00260 idx = new IndexSchema(this);
00261 idx->setAutoGenerated(true);
00262 idx->addField( field );
00263 }
00264 }
00265 if (idx)
00266 m_indices.append(idx);
00267 return *this;
00268 }
00269 #endif
00270
00271 void TableSchema::clear()
00272 {
00273 m_indices.clear();
00274 d->clearLookupFields();
00275 FieldList::clear();
00276 SchemaData::clear();
00277 m_conn = 0;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 QString TableSchema::debugString()
00327 {
00328 return debugString(true);
00329 }
00330
00331 QString TableSchema::debugString(bool includeTableName)
00332 {
00333 QString s;
00334 if (includeTableName)
00335 s = QString("TABLE ") + schemaDataDebugString() + "\n";
00336 s.append( FieldList::debugString() );
00337
00338 Field *f;
00339 for (Field::ListIterator it(m_fields); (f = it.current()); ++it) {
00340 LookupFieldSchema *lookupSchema = lookupFieldSchema( *f );
00341 if (lookupSchema)
00342 s.append( QString("\n") + lookupSchema->debugString() );
00343 }
00344 return s;
00345 }
00346
00347 void TableSchema::setKexiDBSystem(bool set)
00348 {
00349 if (set)
00350 m_native=true;
00351 m_isKexiDBSystem = set;
00352 }
00353
00354 void TableSchema::setNative(bool set)
00355 {
00356 if (m_isKexiDBSystem && !set) {
00357 KexiDBWarn << "TableSchema::setNative(): cannot set native off"
00358 " when KexiDB system flag is set on!" << endl;
00359 return;
00360 }
00361 m_native=set;
00362 }
00363
00364 QuerySchema* TableSchema::query()
00365 {
00366 if (m_query)
00367 return m_query;
00368 m_query = new QuerySchema( *this );
00369 return m_query;
00370 }
00371
00372 Field* TableSchema::anyNonPKField()
00373 {
00374 if (!d->anyNonPKField) {
00375 Field *f;
00376 Field::ListIterator it(m_fields);
00377 it.toLast();
00378 for (; (f = it.current()); --it) {
00379 if (!f->isPrimaryKey() && (!m_pkey || !m_pkey->hasField(f)))
00380 break;
00381 }
00382 d->anyNonPKField = f;
00383 }
00384 return d->anyNonPKField;
00385 }
00386
00387 bool TableSchema::setLookupFieldSchema( const QString& fieldName, LookupFieldSchema *lookupFieldSchema )
00388 {
00389 Field *f = field(fieldName);
00390 if (!f) {
00391 KexiDBWarn << "TableSchema::setLookupFieldSchema(): no such field '" << fieldName
00392 << "' in table " << name() << endl;
00393 return false;
00394 }
00395 if (lookupFieldSchema)
00396 d->lookupFields.replace( f, lookupFieldSchema );
00397 else {
00398 delete d->lookupFields[f];
00399 d->lookupFields.remove( f );
00400 }
00401 d->lookupFieldsList.clear();
00402 return true;
00403 }
00404
00405 LookupFieldSchema *TableSchema::lookupFieldSchema( const Field& field ) const
00406 {
00407 return d->lookupFields[ &field ];
00408 }
00409
00410 LookupFieldSchema *TableSchema::lookupFieldSchema( const QString& fieldName )
00411 {
00412 Field *f = TableSchema::field(fieldName);
00413 if (!f)
00414 return 0;
00415 return lookupFieldSchema( *f );
00416 }
00417
00418 const QPtrVector<LookupFieldSchema>& TableSchema::lookupFieldsList()
00419 {
00420 if (d->lookupFields.isEmpty())
00421 return d->lookupFieldsList;
00422 if (!d->lookupFields.isEmpty() && !d->lookupFieldsList.isEmpty())
00423 return d->lookupFieldsList;
00424
00425 d->lookupFieldsList.clear();
00426 d->lookupFieldsList.resize( d->lookupFields.count() );
00427 uint i = 0;
00428 for (Field::ListIterator it(m_fields); it.current(); ++it) {
00429 QMap<const Field*, LookupFieldSchema*>::ConstIterator itMap = d->lookupFields.find( it.current() );
00430 if (itMap != d->lookupFields.constEnd()) {
00431 d->lookupFieldsList.insert( i, itMap.data() );
00432 i++;
00433 }
00434 }
00435 return d->lookupFieldsList;
00436 }
00437
00438
00439
00440 InternalTableSchema::InternalTableSchema(const QString& name)
00441 : TableSchema(name)
00442 {
00443 }
00444
00445 InternalTableSchema::InternalTableSchema(const TableSchema& ts)
00446 : TableSchema(ts, false)
00447 {
00448 }
00449
00450 InternalTableSchema::~InternalTableSchema()
00451 {
00452 }
00453
|