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 };
00057 }
00058
00059
00060
00061 using namespace KexiDB;
00062
00063 TableSchema::TableSchema(const QString& name)
00064 : FieldList(true)
00065 , SchemaData(KexiDB::TableObjectType)
00066 , m_query(0)
00067 , m_isKexiDBSystem(false)
00068 {
00069 m_name = name.lower();
00070 init();
00071 }
00072
00073 TableSchema::TableSchema(const SchemaData& sdata)
00074 : FieldList(true)
00075 , SchemaData(sdata)
00076 , m_query(0)
00077 , m_isKexiDBSystem(false)
00078 {
00079 init();
00080 }
00081
00082 TableSchema::TableSchema()
00083 : FieldList(true)
00084 , SchemaData(KexiDB::TableObjectType)
00085 , m_query(0)
00086 , m_isKexiDBSystem(false)
00087 {
00088 init();
00089 }
00090
00091 TableSchema::TableSchema(const TableSchema& ts, bool copyId)
00092 : FieldList(static_cast<const FieldList&>(ts))
00093 , SchemaData(static_cast<const SchemaData&>(ts))
00094 , m_conn( ts.m_conn )
00095 , m_query(0)
00096 , m_isKexiDBSystem(false)
00097 {
00098 d = new Private();
00099 m_name = ts.m_name;
00100 m_indices.setAutoDelete( true );
00101 m_pkey = 0;
00102 if (!copyId)
00103 m_id = -1;
00104
00105
00106 IndexSchema::ListIterator idx_it(ts.m_indices);
00107 for (;idx_it.current();++idx_it) {
00108 IndexSchema *idx = new IndexSchema(
00109 *idx_it.current(), *this );
00110 if (idx->isPrimaryKey()) {
00111 m_pkey = idx;
00112 }
00113 m_indices.append(idx);
00114 }
00115 }
00116
00117
00118 TableSchema::TableSchema(Connection *conn, const QString & name)
00119 : FieldList(true)
00120 , SchemaData(KexiDB::TableObjectType)
00121 , m_conn( conn )
00122 , m_query(0)
00123 , m_isKexiDBSystem(false)
00124 {
00125 d = new Private();
00126 assert(conn);
00127 m_name = name;
00128 m_indices.setAutoDelete( true );
00129 m_pkey = new IndexSchema(this);
00130 m_indices.append(m_pkey);
00131 }
00132
00133 TableSchema::~TableSchema()
00134 {
00135 if (m_conn)
00136 m_conn->removeMe( this );
00137 delete m_query;
00138 delete d;
00139 }
00140
00141 void TableSchema::init()
00142 {
00143 d = new Private();
00144 m_indices.setAutoDelete( true );
00145 m_pkey = new IndexSchema(this);
00146 m_indices.append(m_pkey);
00147 }
00148
00149 void TableSchema::setPrimaryKey(IndexSchema *pkey)
00150 {
00151 if (m_pkey && m_pkey!=pkey) {
00152 if (m_pkey->fieldCount()==0) {
00153 m_indices.remove(m_pkey);
00154 }
00155 else {
00156 m_pkey->setPrimaryKey(false);
00157
00158 }
00159
00160 }
00161
00162 if (!pkey) {
00163 pkey = new IndexSchema(this);
00164 }
00165 m_pkey = pkey;
00166 m_pkey->setPrimaryKey(true);
00167 d->anyNonPKField = 0;
00168 }
00169
00170 FieldList& TableSchema::insertField(uint index, Field *field)
00171 {
00172 assert(field);
00173 FieldList::insertField(index, field);
00174 if (!field || index>m_fields.count())
00175 return *this;
00176 field->setTable(this);
00177 field->m_order = index;
00178
00179 Field *f = m_fields.at(index+1);
00180 for (int i=index+1; f; i++, f = m_fields.next())
00181 f->m_order = i;
00182
00183
00184 IndexSchema *idx = 0;
00185 if (field->isPrimaryKey()) {
00186 idx = new IndexSchema(this);
00187 idx->setAutoGenerated(true);
00188 idx->addField( field );
00189 setPrimaryKey(idx);
00190 }
00191 if (field->isUniqueKey()) {
00192 if (!idx) {
00193 idx = new IndexSchema(this);
00194 idx->setAutoGenerated(true);
00195 idx->addField( field );
00196 }
00197 idx->setUnique(true);
00198 }
00199 if (field->isIndexed()) {
00200 if (!idx) {
00201 idx = new IndexSchema(this);
00202 idx->setAutoGenerated(true);
00203 idx->addField( field );
00204 }
00205 }
00206 if (idx)
00207 m_indices.append(idx);
00208 return *this;
00209 }
00210
00211 void TableSchema::removeField(KexiDB::Field *field)
00212 {
00213 if (d->anyNonPKField && field == d->anyNonPKField)
00214 d->anyNonPKField = 0;
00215 delete d->lookupFields[field];
00216 d->lookupFields.remove(field);
00217 FieldList::removeField(field);
00218 }
00219
00220 #if 0 //original
00221 KexiDB::FieldList& TableSchema::addField(KexiDB::Field* field)
00222 {
00223 assert(field);
00224 FieldList::addField(field);
00225 field->setTable(this);
00226 field->m_order = m_fields.count();
00227
00228
00229 IndexSchema *idx = 0;
00230 if (field->isPrimaryKey()) {
00231 idx = new IndexSchema(this);
00232 idx->setAutoGenerated(true);
00233 idx->addField( field );
00234 setPrimaryKey(idx);
00235 }
00236 if (field->isUniqueKey()) {
00237 if (!idx) {
00238 idx = new IndexSchema(this);
00239 idx->setAutoGenerated(true);
00240 idx->addField( field );
00241 }
00242 idx->setUnique(true);
00243 }
00244 if (field->isIndexed()) {
00245 if (!idx) {
00246 idx = new IndexSchema(this);
00247 idx->setAutoGenerated(true);
00248 idx->addField( field );
00249 }
00250 }
00251 if (idx)
00252 m_indices.append(idx);
00253 return *this;
00254 }
00255 #endif
00256
00257 void TableSchema::clear()
00258 {
00259 m_indices.clear();
00260 d->clearLookupFields();
00261 FieldList::clear();
00262 SchemaData::clear();
00263 m_conn = 0;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
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 QString TableSchema::debugString()
00313 {
00314 return debugString(true);
00315 }
00316
00317 QString TableSchema::debugString(bool includeTableName)
00318 {
00319 QString s;
00320 if (includeTableName)
00321 s = QString("TABLE ") + schemaDataDebugString() + "\n";
00322 s.append( FieldList::debugString() );
00323
00324 Field *f;
00325 for (Field::ListIterator it(m_fields); (f = it.current()); ++it) {
00326 LookupFieldSchema *lookupSchema = lookupFieldSchema( *f );
00327 if (lookupSchema)
00328 s.append( QString("\n") + lookupSchema->debugString() );
00329 }
00330 return s;
00331 }
00332
00333 void TableSchema::setKexiDBSystem(bool set)
00334 {
00335 if (set)
00336 m_native=true;
00337 m_isKexiDBSystem = set;
00338 }
00339
00340 void TableSchema::setNative(bool set)
00341 {
00342 if (m_isKexiDBSystem && !set) {
00343 KexiDBWarn << "TableSchema::setNative(): cannot set native off"
00344 " when KexiDB system flag is set on!" << endl;
00345 return;
00346 }
00347 m_native=set;
00348 }
00349
00350 QuerySchema* TableSchema::query()
00351 {
00352 if (m_query)
00353 return m_query;
00354 m_query = new QuerySchema( this );
00355 return m_query;
00356 }
00357
00358 Field* TableSchema::anyNonPKField()
00359 {
00360 if (!d->anyNonPKField) {
00361 Field *f;
00362 Field::ListIterator it(m_fields);
00363 it.toLast();
00364 for (; (f = it.current()); --it) {
00365 if (!f->isPrimaryKey() && (!m_pkey || !m_pkey->hasField(f)))
00366 break;
00367 }
00368 d->anyNonPKField = f;
00369 }
00370 return d->anyNonPKField;
00371 }
00372
00373 bool TableSchema::setLookupFieldSchema( const QString& fieldName, LookupFieldSchema *lookupFieldSchema )
00374 {
00375 Field *f = field(fieldName);
00376 if (!f) {
00377 KexiDBWarn << "TableSchema::setLookupFieldSchema(): no such field '" << fieldName
00378 << "' in table " << name() << endl;
00379 return false;
00380 }
00381 if (lookupFieldSchema)
00382 d->lookupFields.replace( f, lookupFieldSchema );
00383 else {
00384 delete d->lookupFields[f];
00385 d->lookupFields.remove( f );
00386 }
00387 return true;
00388 }
00389
00390 LookupFieldSchema *TableSchema::lookupFieldSchema( const Field& field ) const
00391 {
00392 return d->lookupFields[ &field ];
00393 }
00394
00395 LookupFieldSchema *TableSchema::lookupFieldSchema( const QString& fieldName )
00396 {
00397 Field *f = TableSchema::field(fieldName);
00398 if (!f)
00399 return 0;
00400 return lookupFieldSchema( *f );
00401 }
00402
00403
00404
00405 InternalTableSchema::InternalTableSchema(const QString& name)
00406 : TableSchema(name)
00407 {
00408 }
00409
00410 InternalTableSchema::~InternalTableSchema()
00411 {
00412 }
00413
|