kexi

tableschema.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2003 Joseph Wenninger <jowenn@kde.org>
00003    Copyright (C) 2003-2004 Jaroslaw Staniek <js@iidea.pl>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include <kexidb/tableschema.h>
00022 #include <kexidb/driver.h>
00023 #include <kexidb/connection.h>
00024 
00025 #include <assert.h>
00026 
00027 #include <kdebug.h>
00028 
00029 namespace KexiDB {
00031 class TableSchema::Private
00032 {
00033 public:
00034     Private()
00035      : anyNonPKField(0)
00036     {
00037     }
00038 
00039     Field *anyNonPKField;
00040 };
00041 }
00042 //-------------------------------------
00043 
00044 
00045 using namespace KexiDB;
00046 
00047 TableSchema::TableSchema(const QString& name)
00048     : FieldList(true)
00049     , SchemaData(KexiDB::TableObjectType)
00050     , m_query(0)
00051     , m_isKexiDBSystem(false)
00052 {
00053     m_name = name.lower();
00054     init();
00055 }
00056 
00057 TableSchema::TableSchema(const SchemaData& sdata)
00058     : FieldList(true)
00059     , SchemaData(sdata)
00060     , m_query(0)
00061     , m_isKexiDBSystem(false)
00062 {
00063     init();
00064 }
00065 
00066 TableSchema::TableSchema()
00067     : FieldList(true)
00068     , SchemaData(KexiDB::TableObjectType)
00069     , m_query(0)
00070     , m_isKexiDBSystem(false)
00071 {
00072     init();
00073 }
00074 
00075 TableSchema::TableSchema(const TableSchema& ts)
00076     : FieldList(static_cast<const FieldList&>(ts))
00077     , SchemaData(static_cast<const SchemaData&>(ts))
00078     , m_conn( ts.m_conn )
00079     , m_query(0) //not cached
00080     , m_isKexiDBSystem(false)
00081 {
00082     d = new Private();
00083     m_name = ts.m_name;
00084     m_indices.setAutoDelete( true );
00085     m_pkey = 0; //will be copied
00086 
00087     //deep copy all members
00088     IndexSchema::ListIterator idx_it(ts.m_indices);
00089     for (;idx_it.current();++idx_it) {
00090         IndexSchema *idx = new IndexSchema(
00091             *idx_it.current(), *this /*fields from _this_ table will be assigned to the index*/);
00092         if (idx->isPrimaryKey()) {//assign pkey
00093             m_pkey = idx;
00094         }
00095         m_indices.append(idx);
00096     }
00097 }
00098 
00099 // used by Connection
00100 TableSchema::TableSchema(Connection *conn, const QString & name)
00101     : FieldList(true)
00102     , SchemaData(KexiDB::TableObjectType)
00103     , m_conn( conn )
00104     , m_query(0)
00105     , m_isKexiDBSystem(false)
00106 {
00107     d = new Private();
00108     assert(conn);
00109     m_name = name;
00110     m_indices.setAutoDelete( true );
00111     m_pkey = new IndexSchema(this);
00112     m_indices.append(m_pkey);
00113 }
00114 
00115 TableSchema::~TableSchema()
00116 {
00117     if (m_conn)
00118         m_conn->removeMe( this );
00119     delete m_query;
00120     delete d;
00121 }
00122 
00123 void TableSchema::init()
00124 {
00125     d = new Private();
00126     m_indices.setAutoDelete( true );
00127     m_pkey = new IndexSchema(this);
00128     m_indices.append(m_pkey);
00129 }
00130 
00131 void TableSchema::setPrimaryKey(IndexSchema *pkey)
00132 {
00133     if (m_pkey && m_pkey!=pkey) {
00134         if (m_pkey->fieldCount()==0) {//this is empty key, probably default - remove it
00135             m_indices.remove(m_pkey);
00136         }
00137         else {
00138             m_pkey->setPrimaryKey(false); //there can be only one pkey..
00139             //thats ok, the old pkey is still on indices list, if not empty
00140         }
00141 //      m_pkey=0; 
00142     }
00143     
00144     if (!pkey) {//clearing - set empty pkey
00145         pkey = new IndexSchema(this);
00146     }
00147     m_pkey = pkey; //todo
00148     m_pkey->setPrimaryKey(true);
00149     d->anyNonPKField = 0; //for safety
00150 }
00151 
00152 FieldList& TableSchema::insertField(uint index, Field *field)
00153 {
00154     assert(field);
00155     FieldList::insertField(index, field);
00156     if (!field || index>m_fields.count())
00157         return *this;
00158     field->setTable(this);
00159     field->m_order = index; //m_fields.count();
00160     //update order for next next fields
00161     Field *f = m_fields.at(index+1);
00162     for (int i=index+1; f; i++, f = m_fields.next())
00163         f->m_order = i;
00164 
00165     //Check for auto-generated indices:
00166     IndexSchema *idx = 0;
00167     if (field->isPrimaryKey()) {// this is auto-generated single-field unique index
00168         idx = new IndexSchema(this);
00169         idx->setAutoGenerated(true);
00170         idx->addField( field );
00171         setPrimaryKey(idx);
00172     }
00173     if (field->isUniqueKey()) {
00174         if (!idx) {
00175             idx = new IndexSchema(this);
00176             idx->setAutoGenerated(true);
00177             idx->addField( field );
00178         }
00179         idx->setUnique(true);
00180     }
00181     if (field->isIndexed()) {// this is auto-generated single-field
00182         if (!idx) {
00183             idx = new IndexSchema(this);
00184             idx->setAutoGenerated(true);
00185             idx->addField( field );
00186         }
00187     }
00188     if (idx)
00189         m_indices.append(idx);
00190     return *this;
00191 }
00192 
00193 void TableSchema::removeField(KexiDB::Field *field)
00194 {
00195     if (d->anyNonPKField && field == d->anyNonPKField) //d->anyNonPKField will be removed!
00196         d->anyNonPKField = 0;
00197     FieldList::removeField(field);
00198 }
00199 
00200 #if 0 //original        
00201 KexiDB::FieldList& TableSchema::addField(KexiDB::Field* field)
00202 {
00203     assert(field);
00204     FieldList::addField(field);
00205     field->setTable(this);
00206     field->m_order = m_fields.count();
00207     //Check for auto-generated indices:
00208 
00209     IndexSchema *idx = 0;
00210     if (field->isPrimaryKey()) {// this is auto-generated single-field unique index
00211         idx = new IndexSchema(this);
00212         idx->setAutoGenerated(true);
00213         idx->addField( field );
00214         setPrimaryKey(idx);
00215     }
00216     if (field->isUniqueKey()) {
00217         if (!idx) {
00218             idx = new IndexSchema(this);
00219             idx->setAutoGenerated(true);
00220             idx->addField( field );
00221         }
00222         idx->setUnique(true);
00223     }
00224     if (field->isIndexed()) {// this is auto-generated single-field
00225         if (!idx) {
00226             idx = new IndexSchema(this);
00227             idx->setAutoGenerated(true);
00228             idx->addField( field );
00229         }
00230     }
00231     if (idx)
00232         m_indices.append(idx);
00233     return *this;
00234 }
00235 #endif
00236 
00237 void TableSchema::clear()
00238 {
00239     m_indices.clear();
00240     FieldList::clear();
00241     SchemaData::clear();
00242     m_conn = 0;
00243 }
00244 
00245 /*
00246 void TableSchema::addPrimaryKey(const QString& key)
00247 {
00248     m_primaryKeys.append(key);
00249 }*/
00250 
00251 /*QStringList TableSchema::primaryKeys() const
00252 {
00253     return m_primaryKeys;
00254 }
00255 
00256 bool TableSchema::hasPrimaryKeys() const
00257 {
00258     return !m_primaryKeys.isEmpty();
00259 }
00260 */
00261 
00262 //const QString& TableSchema::name() const
00263 //{
00264 //  return m_name;
00265 //}
00266 
00267 //void TableSchema::setName(const QString& name)
00268 //{
00269 //  m_name=name;
00270 /*  ListIterator it( m_fields );
00271     Field *field;
00272     for (; (field = it.current())!=0; ++it) {
00273     
00274     int fcnt=m_fields.count();
00275     for (int i=0;i<fcnt;i++) {
00276         m_fields[i].setTable(name);
00277     }*/
00278 //}
00279 
00280 /*KexiDB::Field TableSchema::field(unsigned int id) const
00281 {
00282     if (id<m_fields.count()) return m_fields[id];
00283     return KexiDB::Field();
00284 }
00285 
00286 unsigned int TableSchema::fieldCount() const
00287 {
00288     return m_fields.count();
00289 }*/
00290 
00291 QString TableSchema::debugString()
00292 {
00293     return QString("TABLE ") + schemaDataDebugString() + "\n" + FieldList::debugString();
00294 }
00295 
00296 void TableSchema::setKexiDBSystem(bool set)
00297 {
00298     if (set)
00299         m_native=true;
00300     m_isKexiDBSystem = set;
00301 }
00302 
00303 void TableSchema::setNative(bool set)
00304 {
00305     if (m_isKexiDBSystem && !set) {
00306         KexiDBDbg << "TableSchema::setNative(): cannot set native off"
00307             " when KexiDB system flag is set on!" << endl;
00308         return;
00309     }
00310     m_native=set;
00311 }
00312 
00313 QuerySchema* TableSchema::query()
00314 {
00315     if (m_query)
00316         return m_query;
00317     m_query = new QuerySchema( this ); //it's owned by me
00318     return m_query;
00319 }
00320 
00321 Field* TableSchema::anyNonPKField()
00322 {
00323     if (!d->anyNonPKField) {
00324         Field *f;
00325         Field::ListIterator it(m_fields);
00326         it.toLast(); //from the end (higher chances to find)
00327         for (; (f = it.current()); --it) {
00328             if (!f->isPrimaryKey() && (!m_pkey || !m_pkey->hasField(f)))
00329                 break;
00330         }
00331         d->anyNonPKField = f;
00332     }
00333     return d->anyNonPKField;
00334 }
00335 
00336 //--------------------------------------
00337 
00338 InternalTableSchema::InternalTableSchema(const QString& name)
00339  : TableSchema(name)
00340 {
00341 }
00342 
00343 InternalTableSchema::~InternalTableSchema()
00344 {
00345 }
00346 
KDE Home | KDE Accessibility Home | Description of Access Keys