summaryrefslogtreecommitdiff
path: root/noncore/apps/tableviewer/db/common.cpp
Side-by-side diff
Diffstat (limited to 'noncore/apps/tableviewer/db/common.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/tableviewer/db/common.cpp28
1 files changed, 18 insertions, 10 deletions
diff --git a/noncore/apps/tableviewer/db/common.cpp b/noncore/apps/tableviewer/db/common.cpp
index dbf9370..6e544ba 100644
--- a/noncore/apps/tableviewer/db/common.cpp
+++ b/noncore/apps/tableviewer/db/common.cpp
@@ -1,124 +1,132 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
-#include <stdlib.h>
+#include "common.h"
+#include "datacache.h"
+
+/* OPIE */
+#include <opie2/odebug.h>
+#include <qpe/timestring.h>
+using namespace Opie::Core;
+
+/* QT */
#include <qstring.h>
#include <qheader.h>
#include <qvector.h>
#include <qdatetime.h>
-#include <qpe/timestring.h>
-#include "common.h"
-#include "datacache.h"
+
+/* STD */
#include <assert.h>
+#include <stdlib.h>
static const int del_flag = 0x1;
static const int new_flag = 0x2;
/* Helper function */
int parseNextNumber(QString *q) {
QChar c;
uint i;
int result = 0;
bool found_digits = FALSE;
for(i = 0; i < q->length(); i++) {
c = q->at(i);
if (c.isDigit()) {
if (found_digits)
result *= 10;
found_digits = TRUE;
result += c.digitValue();
} else {
if (found_digits)
break;
/* just skip this char */
}
}
/* now truncate q */
if (found_digits)
q->remove(0, i);
return result;
}
/*!
\class QStringVector
\brief A Vector of QStrings that can be sorted and searched
Implmented in order to allow reverse lookup on the string name
*/
/*!
This function implements the compare function in order to allow the
searching and sorting of the QStringVector to occur
\returns an int which is either
<UL>
<LI> < 0 if the first string is smaller than the second,</LI>
<LI> > 0 if the first string is bigger then the second,</LI>
<LI> == 0 if the first string is equal to the second.</LI>
</UL>
*/
int QStringVector::compareItems(Item a, Item b)
{
QString *qa = (QString *)a;
QString *qb = (QString *)b;
return QString::compare(*qa, *qb);
}
/*!
\class TVVariant
A way of abstracting void * and keeping information on
the keytypes and behaviours in one place
*/
TVVariantPrivate::TVVariantPrivate()
{
typ = TVVariant::Invalid;
}
TVVariantPrivate::TVVariantPrivate( TVVariantPrivate *d)
{
switch(d->typ)
{
case TVVariant::Invalid:
break;
case TVVariant::String:
value.ptr = new QString(*((QString *)d->value.ptr));
break;
case TVVariant::Date:
value.ptr = new QDate(*((QDate *)d->value.ptr));
break;
case TVVariant::Time:
value.ptr = new QTime(*((QTime *)d->value.ptr));
break;
case TVVariant::Int:
value.i = d->value.i;
break;
default:
ASSERT( 0 );
}
typ = d->typ;
}
TVVariantPrivate::~TVVariantPrivate()
{
@@ -219,193 +227,193 @@ void TVVariant::detach()
{
if (d->count == 1)
return;
d->deref();
d = new TVVariantPrivate(d);
}
const QString TVVariant::typeName() const
{
return typeToName(d->typ);
}
void TVVariant::clear()
{
if (d->count > 1)
{
d->deref();
d = new TVVariantPrivate;
return;
}
d->clear();
}
const QString TVVariant::typeToName(KeyType typ)
{
switch(typ) {
case String:
return QString("String");
case Date:
return QString("Date");
case Time:
return QString("Time");
case Int:
return QString("Int");
case Invalid:
default:
return QString("Invalid");
}
return QString("Invalid");
}
TVVariant::KeyType TVVariant::nameToType(const QString &name)
{
if(!qstrcmp("String", name))
return String;
if(!qstrcmp("Date", name))
return Date;
if(!qstrcmp("Time", name))
return Time;
if(!qstrcmp("Int", name))
return Int;
return Invalid;
}
void TVVariant::load(QDataStream &s )
{
KeyType t;
s >> t;
d->typ = t;
switch(t) {
case Invalid:
d->typ = t;
break;
case String:
{
QString *x = new QString;
s >> *x;
d->value.ptr = x;
}
break;
case Time:
{
QTime *x = new QTime;
s >> *x;
d->value.ptr = x;
}
break;
case Date:
{
QDate *x = new QDate;
s >> *x;
d->value.ptr = x;
}
break;
case Int:
{
int x;
s >> x;
d->value.i = x;
}
break;
default:
- qFatal("Unrecognized data type");
+ ofatal << "Unrecognized data type" << oendl;
}
}
void TVVariant::save( QDataStream &s ) const
{
s << type();
switch( d->typ ) {
case String:
s << *((QString *)d->value.ptr);
break;
case Date:
s << *((QDate *)d->value.ptr);
break;
case Time:
s << *((QTime *)d->value.ptr);
break;
case Int:
s << d->value.i;
break;
case Invalid:
break;
}
}
QDataStream& operator>>(QDataStream& s, TVVariant& p)
{
p.load( s );
return s;
}
QDataStream& operator<<(QDataStream &s, const TVVariant& p)
{
p.save( s );
return s;
}
QDataStream& operator>> (QDataStream &s, TVVariant::KeyType& p)
{
Q_UINT8 u = 0;
s >> u;
p = (TVVariant::KeyType) u;
return s;
}
QDataStream& operator<< (QDataStream& s, const TVVariant::KeyType& p)
{
s << (Q_UINT8)p;
return s;
}
const QString TVVariant::toString() const
{
switch(d->typ) {
case String:
return *((QString*)d->value.ptr);
case Date:
return ((QDate*)d->value.ptr)->toString();
case Time:
return ((QTime*)d->value.ptr)->toString();
case Int:
return QString::number(d->value.i);
case Invalid:
default:
return QString::null;
}
return QString::null;
}
// TODO DO, this properly, */
int TVVariant::toInt() const
{
if(d->typ == Int)
return d->value.i;
if(d->typ == String) {
QString tmpq(*(QString *)d->value.ptr);
return parseNextNumber(&tmpq);
}
return 0;
}
const QDate TVVariant::toDate() const
{
if(d->typ == Date)
return *((QDate *)d->value.ptr);
if(d->typ == String) {
QString q = toString();
/* date format is day mon d yyyy */
/* ignore the first three letters, read the next
three for month.. etc */
@@ -985,193 +993,193 @@ bool KeyList::validIndex(int i) const
return FALSE;
return TRUE;
}
QDataStream &operator<<( QDataStream &s, const KeyList &k)
{
s << k.getNumFields();
KeyListIterator it(k);
while(it.current()) {
s << (Q_UINT16)it.currentKey();
s << it.current()->name();
s << it.current()->example();
s << (Q_UINT16)it.current()->flags();
++it;
}
return s;
}
QDataStream &operator>>( QDataStream &s, KeyList &k)
{
int i;
int size;
int index = 0;
int flags = 0;
TVVariant type = TVVariant();
QString name;
s >> size;
for (i=0; i < size; i++) {
s >> (Q_UINT16 &)index;
s >> name;
s >> type;
s >> (Q_UINT16 &)flags;
k.replace(index, new Key(name, type, flags));
}
return s;
}
/*!
\class DataElem
\brief A class representing a single row or element of a table in a DBStore
This class holds the data of a row in a table.
*/
/*!
Constructs a DataElem. This function needs a container because the
size, types of keys and primary key are all defined by the containing
database
*/
DataElem::DataElem(DBStore *c) : values(20)
{
int size;
contained = c;
size = c->getNumFields();
values.setAutoDelete(TRUE);
}
/*!
Destroys a DataElem and frees memory used by the DataElem
*/
DataElem::~DataElem() {
}
QDataStream &operator<<( QDataStream &s, const DataElem &d)
{
int size = d.getNumFields();
s << size; /* redundent data but makes streaming easier */
KeyList k = d.getKeys();
KeyListIterator it(k);
while(it.current()) {
s << (Q_UINT16)it.currentKey();
s << d.getField(it.currentKey());
++it;
}
return s;
}
QDataStream &operator>>( QDataStream &s, DataElem &d)
{
int i;
int size;
TVVariant t;
int index = 0;
s >> size; /* redundent data but makes streaming easier */
if (size != d.getNumFields()) {
- qWarning("DataSize mis-match");
+ owarn << "DataSize mis-match" << oendl;
return s; /* sanity check failed.. don't load */
}
for(i = 0; i < size; i++) {
s >> (Q_UINT16)index;
s >> t;
d.setField(index, t);
}
return s;
}
/*! Returns the number of possible (not valid) fields in the data element */
int DataElem::getNumFields() const
{
return contained->getNumFields();
}
KeyList DataElem::getKeys() const
{
return *(contained->getKeys());
}
/*!
This function determines whether field index i of the element has been
set yet.
\return A boolean value that is TRUE if the specfied field of this
element has been set and FALSE if the field has not yet been set
*/
bool DataElem::hasValidValue(int i) const
{
if(!values.find(i))
return FALSE;
if(!contained->getKeys()->validIndex(i))
return FALSE;
return values.find(i)->isValid();
}
/*!
This function determines whether field name qs of the element has been
set yet.
\return A boolean value that is TRUE if the specfied field of this
element has been set and FALSE if the field has not yet been set
*/
bool DataElem::hasValidValue(QString qs) const
{
int i = contained->getKeyIndex(qs);
return hasValidValue(i);
}
/*! returns the type of the field specified by index i */
TVVariant::KeyType DataElem::getFieldType(int i) const
{
return contained->getKeyType(i);
}
/*! returns the type of the field specified by name qs */
TVVariant::KeyType DataElem::getFieldType(QString qs) const
{
int i = contained->getKeyIndex(qs);
return contained->getKeyType(i);
}
/*!
returns a pointer to the data stored in field index i for this
data element, (value may not be valid)
*/
TVVariant DataElem::getField(int i) const
{
if(hasValidValue(i))
return TVVariant(*values.find(i));
return TVVariant();
}
/*!
returns a pointer to the data stored in field name qs for this
data element, (value may not be valid)
*/
TVVariant DataElem::getField(QString qs) const
{
int i = contained->getKeyIndex(qs);
return getField(i);
}
/*!
Sets the value of the elements field index i to the value represented in
the QString q.
\param i index of the field to set
\param q a string that can be parsed to get the value to be set
*/
void DataElem::setField(int i, QString q)
{
/* from the type of the field, parse q and store */
TVVariant::KeyType kt = contained->getKeyType(i);
@@ -1284,187 +1292,187 @@ QString DataElem::toQString() const
/*! formats individual fields to strings so can be displayed */
QString DataElem::toQString(int i) const
{
if(hasValidValue(i)) {
return getField(i).toString();
}
return "";
}
/*! formats individual fields to strings so can be sorted by QListView */
QString DataElem::toSortableQString(int i) const
{
QString scratch = "";
if(hasValidValue(i)) {
switch (contained->getKeyType(i)) {
case TVVariant::String: {
scratch += getField(i).toString();
break;
}
case TVVariant::Int: {
scratch.sprintf("%08d", getField(i).toInt());
break;
}
case TVVariant::Date: {
static QDate epochD(1800, 1, 1);
scratch.sprintf("%08d",
epochD.daysTo(getField(i).toDate()));
break;
}
case TVVariant::Time: {
static QTime epochT(0, 0, 0);
scratch.sprintf("%08d",
epochT.msecsTo(getField(i).toTime()));
break;
}
default:
scratch += "Unknown type";
break;
}
}
return scratch;
}
/* compare functions */
bool DataElem::lessThan(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
return (getField(i) < v);
}
bool DataElem::moreThan(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
return (getField(i) > v);
}
bool DataElem::equalTo(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
return (getField(i) == v);
}
bool DataElem::contains(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
switch(getField(i).type()) {
case TVVariant::String: {
QString qs1 = getField(i).toString().lower();
QString qs2 = v.toString().lower();
if (qs1.contains(qs2) > 0) return TRUE;
break;
}
/* meaningless for ints */
/* meaningless for time */
/* meaningless for dates */
case TVVariant::Int:
case TVVariant::Time:
case TVVariant::Date:
break;
default:
- qWarning("Tried to compare unknown data type");
+ owarn << "Tried to compare unknown data type" << oendl;
}
return FALSE;
}
bool DataElem::startsWith(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
switch(getField(i).type()) {
case TVVariant::String: {
QString qs1 = getField(i).toString().lower();
QString qs2 = v.toString().lower();
return qs1.startsWith(qs2);
}
/* meaningless for ints */
/* meaningless for time */
/* meaningless for dates */
case TVVariant::Int:
case TVVariant::Time:
case TVVariant::Date:
return FALSE;
default:
- qWarning("Tried to compare unknown data type");
+ owarn << "Tried to compare unknown data type" << oendl;
}
return FALSE;
}
bool DataElem::endsWith(int i, TVVariant v) const
{
if (!hasValidValue(i)) return FALSE;
if (getField(i).type() != v.type())
return FALSE;
switch(getField(i).type()) {
case TVVariant::String: {
QString qs1 = getField(i).toString().lower();
QString qs2 = v.toString().lower();
return qs1.startsWith(qs2);
}
/* meaningless for ints */
/* meaningless for time */
/* meaningless for dates */
case TVVariant::Int:
case TVVariant::Time:
case TVVariant::Date:
return FALSE;
default:
- qWarning("Tried to compare unknown data type");
+ owarn << "Tried to compare unknown data type" << oendl;
}
return FALSE;
}
/*!
Determins which of the first to parameters are closer to the third, target
parameter.
\return
<UL>
<LI>TRUE if the first element is a closer match to the target than the
second element</LI>
<LI>FALSE if the first element is not a closer match to the target than
the second element</LI>
</UL>
*/
bool DataElem::closer(DataElem*d1, DataElem *d2, TVVariant target, int column)
{
int type;
if(!d1) return FALSE;
if (!d1->hasValidValue(column)) return FALSE;
if(!target.isValid()) return FALSE;
type = d1->getField(column).type();
if(d2) {
if (type != d2->getField(column).type()) {
/* can't do compare */
- qWarning("Tried to compare two incompatable types");
+ owarn << "Tried to compare two incompatable types" << oendl;
return FALSE;
}
return target.closer(d1->getField(column), d2->getField(column));
}
return target.close(d1->getField(column));
}