0

I have to copy column info from a database to a struct, the problem is that it takes over 5000 iterations and is very slow. Is there any better way?

The code used is in the .h file:

struct sFieldDef
{
CString m_strQualifier;
CString m_strOwner;
CString m_strTableName;
CString m_strColumnName;
int  m_nDataType;
CString m_strTypeName;
long m_lPrecision;
long m_lLength;
int m_nScale;
int m_nRadix;
int m_nNullable;
};

The code used in the .cpp file:

sFieldDef sTempField;
CColumns rsColumns(m_pDatabase);
rsColumns.Open(CRecordset::snapshot);

while( !rsColumns.IsEOF() )
{
sTempField.m_strQualifier=rsColumns.m_strQualifier;
sTempField.m_strOwner=rsColumns.m_strOwner;
sTempField.m_strTableName=rsColumns.m_strTableName;
sTempField.m_strColumnName=rsColumns.m_strColumnName;
sTempField.m_nDataType=rsColumns.m_nDataType;
sTempField.m_strTypeName=rsColumns.m_strTypeName;
sTempField.m_lPrecision=rsColumns.m_lPrecision;
sTempField.m_lLength=rsColumns.m_lLength;
sTempField.m_nScale=rsColumns.m_nScale;
sTempField.m_nRadix=rsColumns.m_nRadix;
sTempField.m_nNullable=rsColumns.m_nNullable;
pArrFiels->Add(sTempField);
rsColumns.MoveNext();
}
Jak
  • 471
  • 5
  • 20

1 Answers1

1

You seem to be copying and storing everything in an array of structs, where each struct has identical members with the corresponding record. Usually we use arrays through iterators. So why not provide an iterator to your record-set and avoid copying altogether? You could roughly start like this:

template <typename RS>
class rs_iterator
{
   RS& rs;
public:
   rs_iterator(RS& rs) : rs{rs} { }
   const RS& operator*() { return rs; }
   rs_iterator& operator++() { return rs.MoveNext(), *this; }
   // ...
}

So you not only provide a convenient and standard interface to an array-like data source like a record-set, but you can use it directly in STL-like algorithms requiring bidirectional iterators.

If your CRecordset supports random access, then so would your iterator, easily. Otherwise, random access provision by itself is a good reason to copy (e.g. to sort columns).

iavr
  • 7,547
  • 1
  • 18
  • 53
  • 1
    Please don't use the `,` operator like that; write `rs.MoveNext(); return *this;` instead. – Mike DeSimone Mar 20 '14 at 14:24
  • @MikeDeSimone Could you be more specific on the problems of this use of `operator,`? Is it only a matter of style or something deeper? – iavr Mar 20 '14 at 14:28
  • Thank you iavr. This will be my first time working with iterators and while reading up on it here http://www.cs.northwestern.edu/~riesbeck/programming/c++/stl-iterators.html it seems that I could also define an iterator for the sFieldDef struct? Do you agree? – Jak Mar 20 '14 at 15:07
  • @Jak Actually I meant that no `sFieldDef` would be need, you could use the `const RS&` directly. But if you do need it, it doesn't have to define an iterator. Only a construct from `const CColumns&` would suffice. – iavr Mar 20 '14 at 15:09
  • @Jak There's a catch, however. It's not straightward or efficient to have the equivalent of `end()` and `operator==` without support from the underlying type `RS`. So you may need a more generic concept than iterator, which I call a *traversor*: define `operator bool() { return !rs.IsEOF(); }`, then loop like this: `for (auto r = ...; r; ++r) { ...*r... }`. Unfortunately, this is now forward-only (which can be corrected) and cannot be used in general STL-like algorithms (which cannot be corrected). I personally find this a flaw in STL design. – iavr Mar 20 '14 at 15:16
  • 1
    @Jak You may also check [Implementing custom iterators in C++11](http://stackoverflow.com/questions/22426974/implementing-custom-iterators-in-c11/22427652#22427652). – iavr Mar 20 '14 at 15:21
  • @iavr Is rs_iterator(CRecordset& rs) : rs{rs} { } the default constructor for a CRecordset parameter? – Jak Mar 24 '14 at 08:21
  • 1
    @Jak, Well, now that I see it again, the parameter should be `RS`. And in your concrete code, `RS` should be `CColumns`, not `CRecordSet`. I'll correct. So you the iterator it like this: `rs_iterator r(rsColumns);`. – iavr Mar 24 '14 at 09:09