00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <kexidb/fieldlist.h>
00021 #include <kexidb/object.h>
00022
00023 #include <kdebug.h>
00024
00025 #include <assert.h>
00026
00027 using namespace KexiDB;
00028
00029 FieldList::FieldList(bool owner)
00030
00031 : m_fields_by_name(101, false)
00032 {
00033 m_fields.setAutoDelete( owner );
00034 m_fields_by_name.setAutoDelete( false );
00035 m_autoinc_fields = 0;
00036 }
00037
00038 FieldList::FieldList(const FieldList& fl, bool deepCopyFields)
00039 : m_fields_by_name( fl.m_fields_by_name.size() )
00040 {
00041 m_fields.setAutoDelete( fl.m_fields.autoDelete() );
00042 m_fields_by_name.setAutoDelete( false );
00043 m_autoinc_fields = 0;
00044
00045 if (deepCopyFields) {
00046
00047 for (Field::ListIterator f_it(fl.m_fields); f_it.current(); ++f_it) {
00048 Field *f = f_it.current()->copy();
00049 if (f_it.current()->m_parent == &fl)
00050 f->m_parent = this;
00051 addField( f );
00052 }
00053 }
00054 }
00055
00056 FieldList::~FieldList()
00057 {
00058 delete m_autoinc_fields;
00059 }
00060
00061 void FieldList::clear()
00062 {
00063
00064 m_fields.clear();
00065 m_fields_by_name.clear();
00066 m_sqlFields = QString::null;
00067 delete m_autoinc_fields;
00068 m_autoinc_fields = 0;
00069 }
00070
00071 FieldList& FieldList::insertField(uint index, KexiDB::Field *field)
00072 {
00073 assert(field);
00074 if (!field)
00075 return *this;
00076 if (index>m_fields.count()) {
00077 KexiDBFatal << "FieldList::insertField(): index (" << index << ") out of range" << endl;
00078 return *this;
00079 }
00080 if (!m_fields.insert(index, field))
00081 return *this;
00082 if (!field->name().isEmpty())
00083 m_fields_by_name.insert(field->name().lower(),field);
00084 m_sqlFields = QString::null;
00085 return *this;
00086 }
00087
00088 void FieldList::renameField(const QString& oldName, const QString& newName)
00089 {
00090 renameField( m_fields_by_name[ oldName ], newName );
00091 }
00092
00093 void FieldList::renameField(KexiDB::Field *field, const QString& newName)
00094 {
00095 if (!field || field != m_fields_by_name[ field->name() ]) {
00096 KexiDBFatal << "FieldList::renameField() no field found "
00097 << (field ? QString("\"%1\"").arg(field->name()) : QString::null) << endl;
00098 return;
00099 }
00100 m_fields_by_name.take( field->name() );
00101 field->setName( newName );
00102 m_fields_by_name.insert( field->name(), field );
00103 }
00104
00105
00106 FieldList& FieldList::addField(KexiDB::Field *field)
00107 {
00108 return insertField(m_fields.count(), field);
00109 }
00110
00111 void FieldList::removeField(KexiDB::Field *field)
00112 {
00113 assert(field);
00114 if (!field)
00115 return;
00116 m_fields_by_name.remove(field->name());
00117 m_fields.remove(field);
00118 m_sqlFields = QString::null;
00119 }
00120
00121 Field* FieldList::field(const QString& name)
00122 {
00123 return m_fields_by_name[name];
00124 }
00125
00126 QString FieldList::debugString()
00127 {
00128 QString dbg;
00129 dbg.reserve(512);
00130 Field::ListIterator it( m_fields );
00131 Field *field;
00132 bool start = true;
00133 if (!it.current())
00134 dbg = "<NO FIELDS>";
00135 for (; (field = it.current())!=0; ++it) {
00136 if (!start)
00137 dbg += ",\n";
00138 else
00139 start = false;
00140 dbg += " ";
00141 dbg += field->debugString();
00142 }
00143 return dbg;
00144 }
00145
00146 void FieldList::debug()
00147 {
00148 KexiDBDbg << debugString() << endl;
00149 }
00150
00151 #define _ADD_FIELD(fname) \
00152 { \
00153 if (fname.isEmpty()) return fl; \
00154 f = m_fields_by_name[fname]; \
00155 if (!f) { KexiDBWarn << subListWarning1(fname) << endl; delete fl; return 0; } \
00156 fl->addField(f); \
00157 }
00158
00159 static QString subListWarning1(const QString& fname) {
00160 return QString("FieldList::subList() could not find field \"%1\"").arg(fname);
00161 }
00162
00163 FieldList* FieldList::subList(const QString& n1, const QString& n2,
00164 const QString& n3, const QString& n4,
00165 const QString& n5, const QString& n6,
00166 const QString& n7, const QString& n8,
00167 const QString& n9, const QString& n10,
00168 const QString& n11, const QString& n12,
00169 const QString& n13, const QString& n14,
00170 const QString& n15, const QString& n16,
00171 const QString& n17, const QString& n18)
00172 {
00173 if (n1.isEmpty())
00174 return 0;
00175 Field *f;
00176 FieldList *fl = new FieldList(false);
00177 _ADD_FIELD(n1);
00178 _ADD_FIELD(n2);
00179 _ADD_FIELD(n3);
00180 _ADD_FIELD(n4);
00181 _ADD_FIELD(n5);
00182 _ADD_FIELD(n6);
00183 _ADD_FIELD(n7);
00184 _ADD_FIELD(n8);
00185 _ADD_FIELD(n9);
00186 _ADD_FIELD(n10);
00187 _ADD_FIELD(n11);
00188 _ADD_FIELD(n12);
00189 _ADD_FIELD(n13);
00190 _ADD_FIELD(n14);
00191 _ADD_FIELD(n15);
00192 _ADD_FIELD(n16);
00193 _ADD_FIELD(n17);
00194 _ADD_FIELD(n18);
00195 return fl;
00196 }
00197
00198 FieldList* FieldList::subList(const QStringList& list)
00199 {
00200 Field *f;
00201 FieldList *fl = new FieldList(false);
00202 for(QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it) {
00203 _ADD_FIELD( (*it) );
00204 }
00205 return fl;
00206 }
00207
00208 FieldList* FieldList::subList(const QValueList<uint>& list)
00209 {
00210 Field *f;
00211 FieldList *fl = new FieldList(false);
00212 foreach(QValueList<uint>::ConstIterator, it, list) {
00213 f = field(*it);
00214 if (!f) {
00215 KexiDBWarn << QString("FieldList::subList() could not find field at position %1").arg(*it) << endl;
00216 delete fl;
00217 return 0;
00218 }
00219 fl->addField(f);
00220 }
00221 return fl;
00222 }
00223
00224 QStringList FieldList::names() const
00225 {
00226 QStringList r;
00227
00228
00229
00230 for (Field::ListIterator it(m_fields); it.current(); ++it) {
00231 r += it.current()->name().lower();
00232 }
00233 return r;
00234 }
00235
00236
00237 QString FieldList::sqlFieldsList(Field::List* list, Driver *driver,
00238 const QString& separator, const QString& tableAlias, int drvEscaping)
00239 {
00240 if (!list)
00241 return QString::null;
00242 QString result;
00243 result.reserve(256);
00244 bool start = true;
00245 const QString tableAliasAndDot( tableAlias.isEmpty() ? QString::null : (tableAlias + ".") );
00246 for (Field::ListIterator it( *list ); it.current(); ++it) {
00247 if (!start)
00248 result += separator;
00249 else
00250 start = false;
00251 result += (tableAliasAndDot + driver->escapeIdentifier( it.current()->name(), drvEscaping ));
00252 }
00253 return result;
00254 }
00255
00256 QString FieldList::sqlFieldsList(Driver *driver,
00257 const QString& separator, const QString& tableAlias, int drvEscaping)
00258 {
00259 if (!m_sqlFields.isEmpty())
00260 return m_sqlFields;
00261
00262 m_sqlFields = FieldList::sqlFieldsList( &m_fields, driver, separator, tableAlias, drvEscaping );
00263 return m_sqlFields;
00264 }
00265
00266 Field::List* FieldList::autoIncrementFields()
00267 {
00268 if (!m_autoinc_fields) {
00269 m_autoinc_fields = new Field::List();
00270 Field *f;
00271 for (Field::ListIterator f_it(m_fields); (f = f_it.current()); ++f_it) {
00272 if (f->isAutoIncrement()) {
00273 m_autoinc_fields->append( f_it.current() );
00274 }
00275 }
00276 }
00277 return m_autoinc_fields;
00278 }