kexi

fieldlist.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2003-2007 Jaroslaw Staniek <js@iidea.pl>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#include <kexidb/fieldlist.h>
21#include <kexidb/object.h>
22
23#include <kdebug.h>
24
25#include <assert.h>
26
27using namespace KexiDB;
28
30 //reasonable sizes: TODO
31 : m_fields_by_name(1009, false)
32{
33 m_fields.setAutoDelete( owner );
34 m_fields_by_name.setAutoDelete( false );
35 m_autoinc_fields = 0;
36}
37
38FieldList::FieldList(const FieldList& fl, bool deepCopyFields)
39 : m_fields_by_name( fl.m_fields_by_name.size() )
40{
41 m_fields.setAutoDelete( fl.m_fields.autoDelete() );
42 m_fields_by_name.setAutoDelete( false );
43 m_autoinc_fields = 0;
44
45 if (deepCopyFields) {
46 //deep copy for the fields
47 for (Field::ListIterator f_it(fl.m_fields); f_it.current(); ++f_it) {
48 Field *f = f_it.current()->copy();
49 if (f_it.current()->m_parent == &fl)
50 f->m_parent = this;
51 addField( f );
52 }
53 }
54}
55
57{
58 delete m_autoinc_fields;
59}
60
62{
63// m_name = TQString();
64 m_fields.clear();
65 m_fields_by_name.clear();
66 m_sqlFields = TQString();
67 delete m_autoinc_fields;
68 m_autoinc_fields = 0;
69}
70
72{
73 assert(field);
74 if (!field)
75 return *this;
76 if (index>m_fields.count()) {
77 KexiDBFatal << "FieldList::insertField(): index (" << index << ") out of range" << endl;
78 return *this;
79 }
80 if (!m_fields.insert(index, field))
81 return *this;
82 if (!field->name().isEmpty())
83 m_fields_by_name.insert(field->name().lower(),field);
84 m_sqlFields = TQString();
85 return *this;
86}
87
88void FieldList::renameField(const TQString& oldName, const TQString& newName)
89{
90 renameField( m_fields_by_name[ oldName ], newName );
91}
92
93void FieldList::renameField(KexiDB::Field *field, const TQString& newName)
94{
95 if (!field || field != m_fields_by_name[ field->name() ]) {
96 KexiDBFatal << "FieldList::renameField() no field found "
97 << (field ? TQString("\"%1\"").arg(field->name()) : TQString()) << endl;
98 return;
99 }
100 m_fields_by_name.take( field->name() );
101 field->setName( newName );
102 m_fields_by_name.insert( field->name(), field );
103}
104
105
107{
108 return insertField(m_fields.count(), field);
109}
110
112{
113 assert(field);
114 if (!field)
115 return;
116 m_fields_by_name.remove(field->name());
117 m_fields.remove(field);
118 m_sqlFields = TQString();
119}
120
121Field* FieldList::field(const TQString& name)
122{
123 return m_fields_by_name[name];
124}
125
127{
128 TQString dbg;
129 dbg.reserve(512);
130 Field::ListIterator it( m_fields );
131 Field *field;
132 bool start = true;
133 if (!it.current())
134 dbg = "<NO FIELDS>";
135 for (; (field = it.current())!=0; ++it) {
136 if (!start)
137 dbg += ",\n";
138 else
139 start = false;
140 dbg += " ";
141 dbg += field->debugString();
142 }
143 return dbg;
144}
145
147{
148 KexiDBDbg << debugString() << endl;
149}
150
151#define _ADD_FIELD(fname) \
152{ \
153 if (fname.isEmpty()) return fl; \
154 f = m_fields_by_name[fname]; \
155 if (!f) { KexiDBWarn << subListWarning1(fname) << endl; delete fl; return 0; } \
156 fl->addField(f); \
157}
158
159static TQString subListWarning1(const TQString& fname) {
160 return TQString("FieldList::subList() could not find field \"%1\"").arg(fname);
161}
162
163FieldList* FieldList::subList(const TQString& n1, const TQString& n2,
164 const TQString& n3, const TQString& n4,
165 const TQString& n5, const TQString& n6,
166 const TQString& n7, const TQString& n8,
167 const TQString& n9, const TQString& n10,
168 const TQString& n11, const TQString& n12,
169 const TQString& n13, const TQString& n14,
170 const TQString& n15, const TQString& n16,
171 const TQString& n17, const TQString& n18)
172{
173 if (n1.isEmpty())
174 return 0;
175 Field *f;
176 FieldList *fl = new FieldList(false);
177 _ADD_FIELD(n1);
178 _ADD_FIELD(n2);
179 _ADD_FIELD(n3);
180 _ADD_FIELD(n4);
181 _ADD_FIELD(n5);
182 _ADD_FIELD(n6);
183 _ADD_FIELD(n7);
184 _ADD_FIELD(n8);
185 _ADD_FIELD(n9);
186 _ADD_FIELD(n10);
187 _ADD_FIELD(n11);
188 _ADD_FIELD(n12);
189 _ADD_FIELD(n13);
190 _ADD_FIELD(n14);
191 _ADD_FIELD(n15);
192 _ADD_FIELD(n16);
193 _ADD_FIELD(n17);
194 _ADD_FIELD(n18);
195 return fl;
196}
197
198FieldList* FieldList::subList(const TQStringList& list)
199{
200 Field *f;
201 FieldList *fl = new FieldList(false);
202 for(TQStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it) {
203 _ADD_FIELD( (*it) );
204 }
205 return fl;
206}
207
208FieldList* FieldList::subList(const TQValueList<uint>& list)
209{
210 Field *f;
211 FieldList *fl = new FieldList(false);
212 foreach(TQValueList<uint>::ConstIterator, it, list) {
213 f = field(*it);
214 if (!f) {
215 KexiDBWarn << TQString("FieldList::subList() could not find field at position %1").arg(*it) << endl;
216 delete fl;
217 return 0;
218 }
219 fl->addField(f);
220 }
221 return fl;
222}
223
224TQStringList FieldList::names() const
225{
226 TQStringList r;
227// for (TQDictIterator<Field> it(m_fields_by_name);it.current();++it) {
228// r += it.currentKey().lower();
229// }
230 for (Field::ListIterator it(m_fields); it.current(); ++it) {
231 r += it.current()->name().lower();
232 }
233 return r;
234}
235
236//static
238 const TQString& separator, const TQString& tableAlias, int drvEscaping)
239{
240 if (!list)
241 return TQString();
242 TQString result;
243 result.reserve(256);
244 bool start = true;
245 const TQString tableAliasAndDot( tableAlias.isEmpty() ? TQString() : (tableAlias + ".") );
246 for (Field::ListIterator it( *list ); it.current(); ++it) {
247 if (!start)
248 result += separator;
249 else
250 start = false;
251 result += (tableAliasAndDot + driver->escapeIdentifier( it.current()->name(), drvEscaping ));
252 }
253 return result;
254}
255
257 const TQString& separator, const TQString& tableAlias, int drvEscaping)
258{
259 if (!m_sqlFields.isEmpty())
260 return m_sqlFields;
261
262 m_sqlFields = FieldList::sqlFieldsList( &m_fields, driver, separator, tableAlias, drvEscaping );
263 return m_sqlFields;
264}
265
267{
268 if (!m_autoinc_fields) {
269 m_autoinc_fields = new Field::List();
270 Field *f;
271 for (Field::ListIterator f_it(m_fields); (f = f_it.current()); ++f_it) {
272 if (f->isAutoIncrement()) {
273 m_autoinc_fields->append( f_it.current() );
274 }
275 }
276 }
277 return m_autoinc_fields;
278}
Generic database abstraction.
Definition driver.h:67
TQString escapeIdentifier(const TQString &str, int options=EscapeDriver|EscapeAsNecessary) const
Driver-specific identifier escaping (e.g. for a table name, db name, etc.)
Definition driver.cpp:316
virtual void removeField(KexiDB::Field *field)
virtual ~FieldList()
Definition fieldlist.cpp:56
FieldList(bool owner=false)
Definition fieldlist.cpp:29
FieldList * subList(const TQString &n1, const TQString &n2=TQString(), const TQString &n3=TQString(), const TQString &n4=TQString(), const TQString &n5=TQString(), const TQString &n6=TQString(), const TQString &n7=TQString(), const TQString &n8=TQString(), const TQString &n9=TQString(), const TQString &n10=TQString(), const TQString &n11=TQString(), const TQString &n12=TQString(), const TQString &n13=TQString(), const TQString &n14=TQString(), const TQString &n15=TQString(), const TQString &n16=TQString(), const TQString &n17=TQString(), const TQString &n18=TQString())
FieldList & addField(Field *field)
Field::List * autoIncrementFields()
virtual TQString debugString()
Field * field(uint id)
Definition fieldlist.h:76
TQDict< Field > m_fields_by_name
Fields collected by name. Not used by QuerySchema.
Definition fieldlist.h:165
virtual void clear()
Definition fieldlist.cpp:61
TQString sqlFieldsList(Driver *driver, const TQString &separator=TQString::fromLatin1(","), const TQString &tableAlias=TQString(), int drvEscaping=Driver::EscapeDriver|Driver::EscapeAsNecessary)
TQStringList names() const
virtual FieldList & insertField(uint index, Field *field)
Definition fieldlist.cpp:71
Meta-data for a field.
Definition field.h:73
virtual Field * copy() const
Definition field.cpp:113
virtual TQString debugString() const
Definition field.cpp:583
void setName(const TQString &name)
Definition field.cpp:324
TQPtrList< Field > List
list of fields
Definition field.h:75
FieldList * m_parent
In most cases this points to a TableSchema object that field is assigned.
Definition field.h:576
bool isAutoIncrement() const
Definition field.h:231
TQPtrListIterator< Field > ListIterator
iterator for list of fields
Definition field.h:77
High-level database connectivity library with database backend drivers.