20 #include "SqliteCursor.h"
22 #include "SqliteConnection.h"
23 #include "SqliteConnection_p.h"
24 #include "sqlite_debug.h"
26 #include "KDbDriver.h"
28 #include "KDbRecordData.h"
36 static bool sqliteStringToBool(
const QString& s)
44 class SqliteCursorData :
public SqliteConnectionInternal
48 : SqliteConnectionInternal(conn)
49 , prepared_st_handle(nullptr)
51 , curr_coldata(nullptr)
52 , curr_colname(nullptr)
53 , cols_pointers_mem_size(0)
71 sqlite3_stmt *prepared_st_handle;
74 const char **curr_coldata;
75 const char **curr_colname;
76 int cols_pointers_mem_size;
80 int type = sqlite3_column_type(prepared_st_handle, i);
81 if (type == SQLITE_NULL) {
83 }
else if (!f || type == SQLITE_TEXT) {
86 (
const char*)sqlite3_column_text(prepared_st_handle, i),
87 sqlite3_column_bytes(prepared_st_handle, i)));
94 }
else if (t == KDbField::Date) {
96 }
else if (t == KDbField::Time) {
98 return KDbUtils::stringToHackedQTime(text);
99 }
else if (t == KDbField::DateTime) {
100 if (text.length() > 10) {
103 return KDbUtils::dateTimeFromISODateStringWithMs(text);
105 return sqliteStringToBool(text);
109 }
else if (type == SQLITE_INTEGER) {
112 return QVariant(qint64(sqlite3_column_int64(prepared_st_handle, i)));
114 const int intVal = sqlite3_column_int(prepared_st_handle, i);
117 return sqlite3_column_int(prepared_st_handle, i) != 0;
119 return QVariant(
double(sqlite3_column_int(prepared_st_handle, i)));
123 }
else if (type == SQLITE_FLOAT) {
126 return QVariant(sqlite3_column_double(prepared_st_handle, i));
128 return QVariant(qint64(sqlite3_column_int64(prepared_st_handle, i)));
130 const double doubleVal = sqlite3_column_double(prepared_st_handle, i);
135 }
else if (type == SQLITE_BLOB) {
138 return QByteArray((
const char*)sqlite3_column_blob(prepared_st_handle, i),
139 sqlite3_column_bytes(prepared_st_handle, i));
145 Q_DISABLE_COPY(SqliteCursorData)
151 , d(new SqliteCursorData(conn))
158 , d(new SqliteCursorData(conn))
163 SqliteCursor::~SqliteCursor()
176 sqliteWarning() <<
"Missing database handle";
180 int res = sqlite3_prepare(
184 &d->prepared_st_handle,
187 if (res != SQLITE_OK) {
188 m_result.setServerErrorCode(res);
194 d->records.resize(128);
200 bool SqliteCursor::drv_close()
202 int res = sqlite3_finalize(d->prepared_st_handle);
203 if (res != SQLITE_OK) {
204 m_result.setServerErrorCode(res);
211 void SqliteCursor::drv_getNextRecord()
213 int res = sqlite3_step(d->prepared_st_handle);
214 if (res == SQLITE_ROW) {
215 m_fetchResult = FetchResult::Ok;
216 m_fieldCount = sqlite3_data_count(d->prepared_st_handle);
219 m_fieldsToStoreInRecord = m_fieldCount;
222 if (res == SQLITE_DONE) {
223 m_fetchResult = FetchResult::End;
225 m_result.setServerErrorCode(res);
226 m_fetchResult = FetchResult::Error;
241 void SqliteCursor::drv_appendCurrentRecordToBuffer()
244 if (!d->curr_coldata)
246 if (!d->cols_pointers_mem_size)
247 d->cols_pointers_mem_size = m_fieldCount *
sizeof(
char*);
248 const char **record = (
const char**)malloc(d->cols_pointers_mem_size);
249 const char **src_col = d->curr_coldata;
250 const char **dest_col = record;
251 for (
int i = 0; i < m_fieldCount; i++, src_col++, dest_col++) {
254 *dest_col = *src_col ? strdup(*src_col) : nullptr;
256 d->records[m_records_in_buf] = record;
260 void SqliteCursor::drv_bufferMovePointerNext()
265 void SqliteCursor::drv_bufferMovePointerPrev()
272 void SqliteCursor::drv_bufferMovePointerTo(qint64 at)
274 d->curr_coldata = d->records.at(at);
277 void SqliteCursor::drv_clearBuffer()
279 if (d->cols_pointers_mem_size > 0) {
280 const int records_in_buf = m_records_in_buf;
281 const char ***r_ptr = d->records.data();
282 for (
int i = 0; i < records_in_buf; i++, r_ptr++) {
283 const char **field_data = *r_ptr;
284 for (
int col = 0; col < m_fieldCount; col++, field_data++) {
285 free((
void*)*field_data);
290 m_records_in_buf = 0;
291 d->cols_pointers_mem_size = 0;
304 const char ** SqliteCursor::recordData()
const
306 return d->curr_coldata;
309 bool SqliteCursor::drv_storeCurrentRecord(
KDbRecordData* data)
const
311 if (!m_visibleFieldsExpanded) {
312 for (
int i = 0; i < m_fieldCount; i++) {
314 (
const char*)sqlite3_column_text(d->prepared_st_handle, i),
315 sqlite3_column_bytes(d->prepared_st_handle, i));
319 for (
int i = 0; i < m_fieldCount; ++i) {
320 KDbField *f = m_visibleFieldsExpanded->at(i)->field();
322 (*data)[i] = d->getValue(f, i);
329 if (i < 0 || i > (m_fieldCount - 1))
332 KDbField *f = (m_visibleFieldsExpanded && i < m_visibleFieldsExpanded->count())
333 ? m_visibleFieldsExpanded->at(i)->field() :
nullptr;
334 return d->getValue(f, i);
337 QString SqliteCursor::serverResultName()
const
339 return SqliteConnectionInternal::serverResultName(m_result.serverErrorCode());
342 void SqliteCursor::storeResult()
344 d->storeResult(&m_result);