diff --git a/src/drivers/sqlite/SqliteCursor.cpp b/src/drivers/sqlite/SqliteCursor.cpp --- a/src/drivers/sqlite/SqliteCursor.cpp +++ b/src/drivers/sqlite/SqliteCursor.cpp @@ -41,15 +41,15 @@ //---------------------------------------------------- +typedef QVector Buffer; + class SqliteCursorData : public SqliteConnectionInternal { public: explicit SqliteCursorData(SqliteConnection* conn) : SqliteConnectionInternal(conn) , prepared_st_handle(nullptr) - , utail(nullptr) - , curr_coldata(nullptr) - , curr_colname(nullptr) + , curr_coldata() , cols_pointers_mem_size(0) { data_owned = false; @@ -70,11 +70,9 @@ sqlite3_stmt *prepared_st_handle; - char *utail; - const char **curr_coldata; - const char **curr_colname; - int cols_pointers_mem_size; //!< size of record's array of pointers to values - QVector records; //!< buffer data + Buffer::const_iterator curr_coldata; + size_t cols_pointers_mem_size; //!< size of record's array of pointers to values + Buffer records; //!< buffer data inline QVariant getValue(KDbField *f, int i) { int type = sqlite3_column_type(prepared_st_handle, i); @@ -192,6 +190,7 @@ if (isBuffered()) { //! @todo manage size dynamically d->records.resize(128); + d->curr_coldata = Buffer::const_iterator(); } return true; @@ -231,7 +230,6 @@ /* if ((int)m_result == (int)FetchResult::Ok && d->curr_coldata) { for (int i=0;icurr_colname[i]<<" "<< d->curr_colname[m_fieldCount+i] << " = " << (d->curr_coldata[i] ? QString::fromLocal8Bit(d->curr_coldata[i]) : "(NULL)"); } // sqliteDebug() << m_fieldCount << "col(s) fetched"; @@ -241,19 +239,20 @@ void SqliteCursor::drv_appendCurrentRecordToBuffer() { // sqliteDebug(); - if (!d->curr_coldata) - return; if (!d->cols_pointers_mem_size) - d->cols_pointers_mem_size = m_fieldCount * sizeof(char*); - const char **record = (const char**)malloc(d->cols_pointers_mem_size); - const char **src_col = d->curr_coldata; - const char **dest_col = record; - for (int i = 0; i < m_fieldCount; i++, src_col++, dest_col++) { -// sqliteDebug() << i <<": '" << *src_col << "'"; -// sqliteDebug() << "src_col: " << src_col; - *dest_col = *src_col ? strdup(*src_col) : nullptr; + d->cols_pointers_mem_size = size_t(m_fieldCount) * sizeof(QVariant *); + const QVariant **record = static_cast(malloc(d->cols_pointers_mem_size)); + const QVariant **dest_col = record; + for (int i = 0; i < m_fieldCount; i++, dest_col++) { + KDbField *f = (m_visibleFieldsExpanded && i < m_visibleFieldsExpanded->count()) + ? m_visibleFieldsExpanded->at(i)->field() : nullptr; + *dest_col = new QVariant(d->getValue(f, i)); + } + if (m_records_in_buf >= d->records.size()) { + d->records.resize(qMax(d->records.size() * 2, m_records_in_buf + 1)); } d->records[m_records_in_buf] = record; + drv_bufferMovePointerTo(m_records_in_buf); // sqliteDebug() << "ok."; } @@ -271,24 +270,25 @@ //and move internal buffer pointer to that place void SqliteCursor::drv_bufferMovePointerTo(qint64 at) { - d->curr_coldata = d->records.at(at); + d->curr_coldata = d->records.cbegin() + at; } void SqliteCursor::drv_clearBuffer() { if (d->cols_pointers_mem_size > 0) { const int records_in_buf = m_records_in_buf; - const char ***r_ptr = d->records.data(); + const QVariant ***r_ptr = d->records.data(); for (int i = 0; i < records_in_buf; i++, r_ptr++) { - const char **field_data = *r_ptr; + const QVariant **field_data = *r_ptr; for (int col = 0; col < m_fieldCount; col++, field_data++) { - free((void*)*field_data); //free field memory + delete *field_data; } free(*r_ptr); //free pointers to fields array } } m_records_in_buf = 0; d->cols_pointers_mem_size = 0; + d->curr_coldata = Buffer::const_iterator(); d->records.clear(); } @@ -303,7 +303,8 @@ const char ** SqliteCursor::recordData() const { - return d->curr_coldata; + //! @todo + return nullptr; } bool SqliteCursor::drv_storeCurrentRecord(KDbRecordData* data) const @@ -329,6 +330,9 @@ if (i < 0 || i > (m_fieldCount - 1)) //range checking return QVariant(); //! @todo allow disable range checking! - performance reasons + if (d->curr_coldata) { + return *((*d->curr_coldata)[i]); + } KDbField *f = (m_visibleFieldsExpanded && i < m_visibleFieldsExpanded->count()) ? m_visibleFieldsExpanded->at(i)->field() : nullptr; return d->getValue(f, i); //, i==m_logicalFieldCount/*ROWID*/);