1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Implementation of QSqlField class
|
---|
4 | **
|
---|
5 | ** Created : 2000-11-03
|
---|
6 | **
|
---|
7 | ** Copyright (C) 2005-2007 Trolltech ASA. All rights reserved.
|
---|
8 | **
|
---|
9 | ** This file is part of the sql module of the Qt GUI Toolkit.
|
---|
10 | **
|
---|
11 | ** This file may be distributed under the terms of the Q Public License
|
---|
12 | ** as defined by Trolltech ASA of Norway and appearing in the file
|
---|
13 | ** LICENSE.QPL included in the packaging of this file.
|
---|
14 | **
|
---|
15 | ** This file may be distributed and/or modified under the terms of the
|
---|
16 | ** GNU General Public License version 2 as published by the Free Software
|
---|
17 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
18 | ** packaging of this file.
|
---|
19 | **
|
---|
20 | ** Licensees holding valid Qt Enterprise Edition licenses may use this
|
---|
21 | ** file in accordance with the Qt Commercial License Agreement provided
|
---|
22 | ** with the Software.
|
---|
23 | **
|
---|
24 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
---|
25 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
---|
26 | **
|
---|
27 | ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
|
---|
28 | ** information about Qt Commercial License Agreements.
|
---|
29 | ** See http://www.trolltech.com/qpl/ for QPL licensing information.
|
---|
30 | ** See http://www.trolltech.com/gpl/ for GPL licensing information.
|
---|
31 | **
|
---|
32 | ** Contact info@trolltech.com if any conditions of this licensing are
|
---|
33 | ** not clear to you.
|
---|
34 | **
|
---|
35 | **********************************************************************/
|
---|
36 |
|
---|
37 | #include "qsqlfield.h"
|
---|
38 |
|
---|
39 | #ifndef QT_NO_SQL
|
---|
40 |
|
---|
41 |
|
---|
42 | /*!
|
---|
43 | \class QSqlField qsqlfield.h
|
---|
44 | \brief The QSqlField class manipulates the fields in SQL database tables
|
---|
45 | and views.
|
---|
46 |
|
---|
47 | \ingroup database
|
---|
48 | \module sql
|
---|
49 |
|
---|
50 | QSqlField represents the characteristics of a single column in a
|
---|
51 | database table or view, such as the data type and column name. A
|
---|
52 | field also contains the value of the database column, which can be
|
---|
53 | viewed or changed.
|
---|
54 |
|
---|
55 | Field data values are stored as QVariants. Using an incompatible
|
---|
56 | type is not permitted. For example:
|
---|
57 |
|
---|
58 | \code
|
---|
59 | QSqlField f( "myfield", QVariant::Int );
|
---|
60 | f.setValue( QPixmap() ); // will not work
|
---|
61 | \endcode
|
---|
62 |
|
---|
63 | However, the field will attempt to cast certain data types to the
|
---|
64 | field data type where possible:
|
---|
65 |
|
---|
66 | \code
|
---|
67 | QSqlField f( "myfield", QVariant::Int );
|
---|
68 | f.setValue( QString("123") ); // casts QString to int
|
---|
69 | \endcode
|
---|
70 |
|
---|
71 | QSqlField objects are rarely created explicitly in application
|
---|
72 | code. They are usually accessed indirectly through \l QSqlRecord
|
---|
73 | or \l QSqlCursor which already contain a list of fields. For
|
---|
74 | example:
|
---|
75 |
|
---|
76 | \code
|
---|
77 | QSqlCursor cur( "Employee" ); // create cursor using the 'Employee' table
|
---|
78 | QSqlField* f = cur.field( "name" ); // use the 'name' field
|
---|
79 | f->setValue( "Dave" ); // set field value
|
---|
80 | ...
|
---|
81 | \endcode
|
---|
82 |
|
---|
83 | In practice we rarely need to extract a pointer to a field at all.
|
---|
84 | The previous example would normally be written:
|
---|
85 |
|
---|
86 | \code
|
---|
87 | QSqlCursor cur( "Employee" );
|
---|
88 | cur.setValue( "name", "Dave" );
|
---|
89 | ...
|
---|
90 | \endcode
|
---|
91 | */
|
---|
92 |
|
---|
93 | /*!
|
---|
94 | Constructs an empty field called \a fieldName of type \a type.
|
---|
95 | */
|
---|
96 |
|
---|
97 | QSqlField::QSqlField( const QString& fieldName, QVariant::Type type )
|
---|
98 | : nm(fieldName), ro(FALSE), nul(FALSE)
|
---|
99 | {
|
---|
100 | d = new QSqlFieldPrivate();
|
---|
101 | d->type = type;
|
---|
102 | val.cast( type );
|
---|
103 | }
|
---|
104 |
|
---|
105 | /*!
|
---|
106 | Constructs a copy of \a other.
|
---|
107 | */
|
---|
108 |
|
---|
109 | QSqlField::QSqlField( const QSqlField& other )
|
---|
110 | : nm( other.nm ), val( other.val ), ro( other.ro ), nul( other.nul )
|
---|
111 | {
|
---|
112 | d = new QSqlFieldPrivate();
|
---|
113 | d->type = other.d->type;
|
---|
114 | }
|
---|
115 |
|
---|
116 | /*!
|
---|
117 | Sets the field equal to \a other.
|
---|
118 | */
|
---|
119 |
|
---|
120 | QSqlField& QSqlField::operator=( const QSqlField& other )
|
---|
121 | {
|
---|
122 | nm = other.nm;
|
---|
123 | val = other.val;
|
---|
124 | ro = other.ro;
|
---|
125 | nul = other.nul;
|
---|
126 | d->type = other.d->type;
|
---|
127 | return *this;
|
---|
128 | }
|
---|
129 |
|
---|
130 | /*!
|
---|
131 | Returns TRUE if the field is equal to \a other; otherwise returns
|
---|
132 | FALSE. Fields are considered equal when the following field
|
---|
133 | properties are the same:
|
---|
134 |
|
---|
135 | \list
|
---|
136 | \i \c name()
|
---|
137 | \i \c isNull()
|
---|
138 | \i \c value()
|
---|
139 | \i \c isReadOnly()
|
---|
140 | \endlist
|
---|
141 |
|
---|
142 | */
|
---|
143 | bool QSqlField::operator==(const QSqlField& other) const
|
---|
144 | {
|
---|
145 | return ( nm == other.nm &&
|
---|
146 | val == other.val &&
|
---|
147 | ro == other.ro &&
|
---|
148 | nul == other.nul &&
|
---|
149 | d->type == other.d->type );
|
---|
150 | }
|
---|
151 |
|
---|
152 | /*!
|
---|
153 | Destroys the object and frees any allocated resources.
|
---|
154 | */
|
---|
155 |
|
---|
156 | QSqlField::~QSqlField()
|
---|
157 | {
|
---|
158 | delete d;
|
---|
159 | }
|
---|
160 |
|
---|
161 |
|
---|
162 | /*!
|
---|
163 | \fn QVariant QSqlField::value() const
|
---|
164 |
|
---|
165 | Returns the value of the field as a QVariant.
|
---|
166 | */
|
---|
167 |
|
---|
168 | /*!
|
---|
169 | Sets the value of the field to \a value. If the field is read-only
|
---|
170 | (isReadOnly() returns TRUE), nothing happens. If the data type of
|
---|
171 | \a value differs from the field's current data type, an attempt is
|
---|
172 | made to cast it to the proper type. This preserves the data type
|
---|
173 | of the field in the case of assignment, e.g. a QString to an
|
---|
174 | integer data type. For example:
|
---|
175 |
|
---|
176 | \code
|
---|
177 | QSqlCursor cur( "Employee" ); // 'Employee' table
|
---|
178 | QSqlField* f = cur.field( "student_count" ); // an integer field
|
---|
179 | ...
|
---|
180 | f->setValue( myLineEdit->text() ); // cast the line edit text to an integer
|
---|
181 | \endcode
|
---|
182 |
|
---|
183 | \sa isReadOnly()
|
---|
184 | */
|
---|
185 |
|
---|
186 | void QSqlField::setValue( const QVariant& value )
|
---|
187 | {
|
---|
188 | if ( isReadOnly() )
|
---|
189 | return;
|
---|
190 | if ( value.type() != d->type ) {
|
---|
191 | if ( !val.canCast( d->type ) )
|
---|
192 | qWarning("QSqlField::setValue: %s cannot cast from %s to %s",
|
---|
193 | nm.local8Bit().data(), value.typeName(), QVariant::typeToName( d->type ) );
|
---|
194 | }
|
---|
195 | val = value;
|
---|
196 |
|
---|
197 | if ( value.isNull() )
|
---|
198 | nul = TRUE;
|
---|
199 | else
|
---|
200 | nul = val.type() == QVariant::Invalid;
|
---|
201 | }
|
---|
202 |
|
---|
203 | /*!
|
---|
204 | Clears the value of the field. If the field is read-only, nothing
|
---|
205 | happens. If \a nullify is TRUE (the default), the field is set to
|
---|
206 | NULL.
|
---|
207 | */
|
---|
208 |
|
---|
209 | void QSqlField::clear( bool nullify )
|
---|
210 | {
|
---|
211 | if ( isReadOnly() )
|
---|
212 | return;
|
---|
213 | QVariant v;
|
---|
214 | v.cast( type() );
|
---|
215 | val = v;
|
---|
216 | if ( nullify )
|
---|
217 | nul = TRUE;
|
---|
218 | }
|
---|
219 |
|
---|
220 | /*!
|
---|
221 | \fn void QSqlField::setName( const QString& name )
|
---|
222 |
|
---|
223 | Sets the name of the field to \a name.
|
---|
224 | */
|
---|
225 |
|
---|
226 | void QSqlField::setName( const QString& name )
|
---|
227 | {
|
---|
228 | nm = name;
|
---|
229 | }
|
---|
230 |
|
---|
231 | /*!
|
---|
232 | \fn void QSqlField::setNull()
|
---|
233 |
|
---|
234 | Sets the field to NULL and clears the value using clear(). If the
|
---|
235 | field is read-only, nothing happens.
|
---|
236 |
|
---|
237 | \sa isReadOnly() clear()
|
---|
238 | */
|
---|
239 |
|
---|
240 | void QSqlField::setNull()
|
---|
241 | {
|
---|
242 | clear( TRUE );
|
---|
243 | }
|
---|
244 |
|
---|
245 | /*!
|
---|
246 | \fn void QSqlField::setReadOnly( bool readOnly )
|
---|
247 |
|
---|
248 | Sets the read only flag of the field's value to \a readOnly.
|
---|
249 |
|
---|
250 | \sa setValue()
|
---|
251 | */
|
---|
252 | void QSqlField::setReadOnly( bool readOnly )
|
---|
253 | {
|
---|
254 | ro = readOnly;
|
---|
255 | }
|
---|
256 |
|
---|
257 | /*!
|
---|
258 | \fn QString QSqlField::name() const
|
---|
259 |
|
---|
260 | Returns the name of the field.
|
---|
261 | */
|
---|
262 |
|
---|
263 | /*!
|
---|
264 | \fn QVariant::Type QSqlField::type() const
|
---|
265 |
|
---|
266 | Returns the field's type as stored in the database.
|
---|
267 | Note that the actual value might have a different type,
|
---|
268 | Numerical values that are too large to store in a long
|
---|
269 | int or double are usually stored as strings to prevent
|
---|
270 | precision loss.
|
---|
271 | */
|
---|
272 |
|
---|
273 | /*!
|
---|
274 | \fn bool QSqlField::isReadOnly() const
|
---|
275 |
|
---|
276 | Returns TRUE if the field's value is read only; otherwise returns
|
---|
277 | FALSE.
|
---|
278 | */
|
---|
279 |
|
---|
280 | /*!
|
---|
281 | \fn bool QSqlField::isNull() const
|
---|
282 |
|
---|
283 | Returns TRUE if the field is currently NULL; otherwise returns
|
---|
284 | FALSE.
|
---|
285 | */
|
---|
286 |
|
---|
287 |
|
---|
288 | /******************************************/
|
---|
289 | /******* QSqlFieldInfo Impl ******/
|
---|
290 | /******************************************/
|
---|
291 |
|
---|
292 | struct QSqlFieldInfoPrivate
|
---|
293 | {
|
---|
294 | int required, len, prec, typeID;
|
---|
295 | uint generated: 1;
|
---|
296 | uint trim: 1;
|
---|
297 | uint calculated: 1;
|
---|
298 | QString name;
|
---|
299 | QString typeName;
|
---|
300 | QVariant::Type typ;
|
---|
301 | QVariant defValue;
|
---|
302 | };
|
---|
303 |
|
---|
304 | /*!
|
---|
305 | \class QSqlFieldInfo qsqlfield.h
|
---|
306 | \brief The QSqlFieldInfo class stores meta data associated with a SQL field.
|
---|
307 |
|
---|
308 | \ingroup database
|
---|
309 | \module sql
|
---|
310 |
|
---|
311 | QSqlFieldInfo objects only store meta data; field values are
|
---|
312 | stored in QSqlField objects.
|
---|
313 |
|
---|
314 | All values must be set in the constructor, and may be retrieved
|
---|
315 | using isRequired(), type(), length(), precision(), defaultValue(),
|
---|
316 | name(), isGenerated() and typeID().
|
---|
317 | */
|
---|
318 |
|
---|
319 | /*!
|
---|
320 | Constructs a QSqlFieldInfo with the following parameters:
|
---|
321 | \table
|
---|
322 | \row \i \a name \i the name of the field.
|
---|
323 | \row \i \a typ \i the field's type in a QVariant.
|
---|
324 | \row \i \a required \i greater than 0 if the field is required, 0
|
---|
325 | if its value can be NULL and less than 0 if it cannot be
|
---|
326 | determined whether the field is required or not.
|
---|
327 | \row \i \a len \i the length of the field. Note that for
|
---|
328 | non-character types some databases return either the length in
|
---|
329 | bytes or the number of digits. -1 signifies that the length cannot
|
---|
330 | be determined.
|
---|
331 | \row \i \a prec \i the precision of the field, or -1 if the field
|
---|
332 | has no precision or it cannot be determined.
|
---|
333 | \row \i \a defValue \i the default value that is inserted into
|
---|
334 | the table if none is specified by the user. QVariant() if there is
|
---|
335 | no default value or it cannot be determined.
|
---|
336 | \row \i \a typeID \i the internal typeID of the database system
|
---|
337 | (only useful for low-level programming). 0 if unknown.
|
---|
338 | \row \i \a generated \i TRUE indicates that this field should be
|
---|
339 | included in auto-generated SQL statments, e.g. in QSqlCursor.
|
---|
340 | \row \i \a trim \i TRUE indicates that widgets should remove
|
---|
341 | trailing whitespace from character fields. This does not affect
|
---|
342 | the field value but only its representation inside widgets.
|
---|
343 | \row \i \a calculated \i TRUE indicates that the value of this
|
---|
344 | field is calculated. The value of calculated fields can by
|
---|
345 | modified by subclassing QSqlCursor and overriding
|
---|
346 | QSqlCursor::calculateField().
|
---|
347 | \endtable
|
---|
348 | */
|
---|
349 | QSqlFieldInfo::QSqlFieldInfo( const QString& name,
|
---|
350 | QVariant::Type typ,
|
---|
351 | int required,
|
---|
352 | int len,
|
---|
353 | int prec,
|
---|
354 | const QVariant& defValue,
|
---|
355 | int typeID,
|
---|
356 | bool generated,
|
---|
357 | bool trim,
|
---|
358 | bool calculated )
|
---|
359 | {
|
---|
360 | d = new QSqlFieldInfoPrivate();
|
---|
361 | d->name = name;
|
---|
362 | d->typ = typ;
|
---|
363 | d->required = required;
|
---|
364 | d->len = len;
|
---|
365 | d->prec = prec;
|
---|
366 | d->defValue = defValue;
|
---|
367 | d->typeID = typeID;
|
---|
368 | d->generated = generated;
|
---|
369 | d->trim = trim;
|
---|
370 | d->calculated = calculated;
|
---|
371 | }
|
---|
372 |
|
---|
373 | /*!
|
---|
374 | Constructs a copy of \a other.
|
---|
375 | */
|
---|
376 | QSqlFieldInfo::QSqlFieldInfo( const QSqlFieldInfo & other )
|
---|
377 | {
|
---|
378 | d = new QSqlFieldInfoPrivate( *(other.d) );
|
---|
379 | }
|
---|
380 |
|
---|
381 | /*!
|
---|
382 | Creates a QSqlFieldInfo object with the type and the name of the
|
---|
383 | QSqlField \a other. If \a generated is TRUE this field will be
|
---|
384 | included in auto-generated SQL statments, e.g. in QSqlCursor.
|
---|
385 | */
|
---|
386 | QSqlFieldInfo::QSqlFieldInfo( const QSqlField & other, bool generated )
|
---|
387 | {
|
---|
388 | d = new QSqlFieldInfoPrivate();
|
---|
389 | d->name = other.name();
|
---|
390 | d->typ = other.type();
|
---|
391 | d->required = -1;
|
---|
392 | d->len = -1;
|
---|
393 | d->prec = -1;
|
---|
394 | d->typeID = 0;
|
---|
395 | d->generated = generated;
|
---|
396 | d->trim = FALSE;
|
---|
397 | d->calculated = FALSE;
|
---|
398 | }
|
---|
399 |
|
---|
400 | /*!
|
---|
401 | Destroys the object and frees any allocated resources.
|
---|
402 | */
|
---|
403 | QSqlFieldInfo::~QSqlFieldInfo()
|
---|
404 | {
|
---|
405 | delete d;
|
---|
406 | }
|
---|
407 |
|
---|
408 | /*!
|
---|
409 | Assigns \a other to this field info and returns a reference to it.
|
---|
410 | */
|
---|
411 | QSqlFieldInfo& QSqlFieldInfo::operator=( const QSqlFieldInfo& other )
|
---|
412 | {
|
---|
413 | delete d;
|
---|
414 | d = new QSqlFieldInfoPrivate( *(other.d) );
|
---|
415 | return *this;
|
---|
416 | }
|
---|
417 |
|
---|
418 | /*!
|
---|
419 | Returns TRUE if this fieldinfo is equal to \a f; otherwise returns
|
---|
420 | FALSE.
|
---|
421 |
|
---|
422 | Two field infos are considered equal if all their attributes
|
---|
423 | match.
|
---|
424 | */
|
---|
425 | bool QSqlFieldInfo::operator==( const QSqlFieldInfo& f ) const
|
---|
426 | {
|
---|
427 | return ( d->name == f.d->name &&
|
---|
428 | d->typ == f.d->typ &&
|
---|
429 | d->required == f.d->required &&
|
---|
430 | d->len == f.d->len &&
|
---|
431 | d->prec == f.d->prec &&
|
---|
432 | d->defValue == f.d->defValue &&
|
---|
433 | d->typeID == f.d->typeID &&
|
---|
434 | d->generated == f.d->generated &&
|
---|
435 | d->trim == f.d->trim &&
|
---|
436 | d->calculated == f.d->calculated );
|
---|
437 | }
|
---|
438 |
|
---|
439 | /*!
|
---|
440 | Returns an empty QSqlField based on the information in this
|
---|
441 | QSqlFieldInfo.
|
---|
442 | */
|
---|
443 | QSqlField QSqlFieldInfo::toField() const
|
---|
444 | { return QSqlField( d->name, d->typ ); }
|
---|
445 |
|
---|
446 | /*!
|
---|
447 | Returns a value greater than 0 if the field is required (NULL
|
---|
448 | values are not allowed), 0 if it isn't required (NULL values are
|
---|
449 | allowed) or less than 0 if it cannot be determined whether the
|
---|
450 | field is required or not.
|
---|
451 | */
|
---|
452 | int QSqlFieldInfo::isRequired() const
|
---|
453 | { return d->required; }
|
---|
454 |
|
---|
455 | /*!
|
---|
456 | Returns the field's type or QVariant::Invalid if the type is
|
---|
457 | unknown.
|
---|
458 | */
|
---|
459 | QVariant::Type QSqlFieldInfo::type() const
|
---|
460 | { return d->typ; }
|
---|
461 |
|
---|
462 | /*!
|
---|
463 | Returns the field's length. For fields storing text the return
|
---|
464 | value is the maximum number of characters the field can hold. For
|
---|
465 | non-character fields some database systems return the number of
|
---|
466 | bytes needed or the number of digits allowed. If the length cannot
|
---|
467 | be determined -1 is returned.
|
---|
468 | */
|
---|
469 | int QSqlFieldInfo::length() const
|
---|
470 | { return d->len; }
|
---|
471 |
|
---|
472 | /*!
|
---|
473 | Returns the field's precision or -1 if the field has no precision
|
---|
474 | or it cannot be determined.
|
---|
475 | */
|
---|
476 | int QSqlFieldInfo::precision() const
|
---|
477 | { return d->prec; }
|
---|
478 |
|
---|
479 | /*!
|
---|
480 | Returns the field's default value or an empty QVariant if the
|
---|
481 | field has no default value or the value couldn't be determined.
|
---|
482 | The default value is the value inserted in the database when it
|
---|
483 | is not explicitly specified by the user.
|
---|
484 | */
|
---|
485 | QVariant QSqlFieldInfo::defaultValue() const
|
---|
486 | { return d->defValue; }
|
---|
487 |
|
---|
488 | /*!
|
---|
489 | Returns the name of the field in the SQL table.
|
---|
490 | */
|
---|
491 | QString QSqlFieldInfo::name() const
|
---|
492 | { return d->name; }
|
---|
493 |
|
---|
494 | /*!
|
---|
495 | Returns the internal type identifier as returned from the database
|
---|
496 | system. The return value is 0 if the type is unknown.
|
---|
497 |
|
---|
498 | \warning This information is only useful for low-level database
|
---|
499 | programming and is \e not database independent.
|
---|
500 | */
|
---|
501 | int QSqlFieldInfo::typeID() const
|
---|
502 | { return d->typeID; }
|
---|
503 |
|
---|
504 | /*!
|
---|
505 | Returns TRUE if the field should be included in auto-generated
|
---|
506 | SQL statments, e.g. in QSqlCursor; otherwise returns FALSE.
|
---|
507 |
|
---|
508 | \sa setGenerated()
|
---|
509 | */
|
---|
510 | bool QSqlFieldInfo::isGenerated() const
|
---|
511 | { return d->generated; }
|
---|
512 |
|
---|
513 | /*!
|
---|
514 | Returns TRUE if trailing whitespace should be removed from
|
---|
515 | character fields; otherwise returns FALSE.
|
---|
516 |
|
---|
517 | \sa setTrim()
|
---|
518 | */
|
---|
519 | bool QSqlFieldInfo::isTrim() const
|
---|
520 | { return d->trim; }
|
---|
521 |
|
---|
522 | /*!
|
---|
523 | Returns TRUE if the field is calculated; otherwise returns FALSE.
|
---|
524 |
|
---|
525 | \sa setCalculated()
|
---|
526 | */
|
---|
527 | bool QSqlFieldInfo::isCalculated() const
|
---|
528 | { return d->calculated; }
|
---|
529 |
|
---|
530 | /*!
|
---|
531 | If \a trim is TRUE widgets should remove trailing whitespace from
|
---|
532 | character fields. This does not affect the field value but only
|
---|
533 | its representation inside widgets.
|
---|
534 |
|
---|
535 | \sa isTrim()
|
---|
536 | */
|
---|
537 | void QSqlFieldInfo::setTrim( bool trim )
|
---|
538 | { d->trim = trim; }
|
---|
539 |
|
---|
540 | /*!
|
---|
541 | \a gen set to FALSE indicates that this field should not appear
|
---|
542 | in auto-generated SQL statements (for example in QSqlCursor).
|
---|
543 |
|
---|
544 | \sa isGenerated()
|
---|
545 | */
|
---|
546 | void QSqlFieldInfo::setGenerated( bool gen )
|
---|
547 | { d->generated = gen; }
|
---|
548 |
|
---|
549 | /*!
|
---|
550 | \a calc set to TRUE indicates that this field is a calculated
|
---|
551 | field. The value of calculated fields can by modified by subclassing
|
---|
552 | QSqlCursor and overriding QSqlCursor::calculateField().
|
---|
553 |
|
---|
554 | \sa isCalculated()
|
---|
555 | */
|
---|
556 | void QSqlFieldInfo::setCalculated( bool calc )
|
---|
557 | { d->calculated = calc; }
|
---|
558 |
|
---|
559 | #endif
|
---|