QByteArray SqlQuery::baValue(int index) { return QByteArray(static_cast<const char *>(sqlite3_column_blob(_stmt, index)), sqlite3_column_bytes(_stmt, index)); }
static GtkWidget* _lib_import_get_extra_widget(dt_lib_import_metadata_t *data, gboolean import_folder) { // add extra lines to 'extra'. don't forget to destroy the widgets later. GtkWidget *expander = gtk_expander_new(_("import options")); gtk_expander_set_expanded(GTK_EXPANDER(expander), dt_conf_get_bool("ui_last/import_options_expanded")); GtkWidget *frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame),GTK_SHADOW_IN); GtkWidget *alignment = gtk_alignment_new(1.0, 1.0, 1.0, 1.0); gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 8, 8, 8, 8); GtkWidget *event_box = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(frame), event_box); gtk_container_add(GTK_CONTAINER(event_box), alignment); gtk_container_add(GTK_CONTAINER(alignment), expander); GtkWidget *extra; extra = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(expander), extra); GtkWidget *recursive = NULL, *ignore_jpeg = NULL; if(import_folder == TRUE) { // recursive opening. recursive = gtk_check_button_new_with_label (_("import directories recursively")); g_object_set(recursive, "tooltip-text", _("recursively import subdirectories. each directory goes into a new film roll."), NULL); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (recursive), dt_conf_get_bool("ui_last/import_recursive")); gtk_box_pack_start(GTK_BOX (extra), recursive, FALSE, FALSE, 0); // ignoring of jpegs. hack while we don't handle raw+jpeg in the same directories. ignore_jpeg = gtk_check_button_new_with_label (_("ignore JPEG files")); g_object_set(ignore_jpeg, "tooltip-text", _("do not load files with an extension of .jpg or .jpeg. this can be useful when there are raw+JPEG in a directory."), NULL); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (ignore_jpeg), dt_conf_get_bool("ui_last/import_ignore_jpegs")); gtk_box_pack_start(GTK_BOX (extra), ignore_jpeg, FALSE, FALSE, 0); } // default metadata GtkWidget *apply_metadata; GtkWidget *table, *label, *creator, *publisher, *rights, *tags; apply_metadata = gtk_check_button_new_with_label (_("apply metadata on import")); g_object_set(apply_metadata, "tooltip-text", _("apply some metadata to all newly imported images."), NULL); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (apply_metadata), dt_conf_get_bool("ui_last/import_apply_metadata")); gtk_box_pack_start(GTK_BOX (extra), apply_metadata, FALSE, FALSE, 0); GValue value = {0, }; g_value_init(&value, G_TYPE_INT); gtk_widget_style_get_property(apply_metadata, "indicator-size", &value); gint indicator_size = g_value_get_int(&value); // gtk_widget_style_get_property(apply_metadata, "indicator-spacing", &value); // gint indicator_spacing = g_value_get_int(&value); table = gtk_table_new(6, 3, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 5); gtk_table_set_col_spacings(GTK_TABLE(table), 5); alignment = gtk_alignment_new(0, 0, 1, 1); gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 2*indicator_size, 0); gtk_container_add(GTK_CONTAINER(alignment), table); gtk_box_pack_start(GTK_BOX (extra), alignment, FALSE, FALSE, 0); creator = gtk_entry_new(); gtk_widget_set_size_request(creator, 300, -1); gtk_entry_set_text(GTK_ENTRY(creator), dt_conf_get_string("ui_last/import_last_creator")); publisher = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(publisher), dt_conf_get_string("ui_last/import_last_publisher")); rights = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(rights), dt_conf_get_string("ui_last/import_last_rights")); tags = gtk_entry_new(); g_object_set(tags, "tooltip-text", _("comma separated list of tags"), NULL); gtk_entry_set_text(GTK_ENTRY(tags), dt_conf_get_string("ui_last/import_last_tags")); // presets from the metadata plugin GtkCellRenderer *renderer; GtkTreeIter iter; GtkListStore *model = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING /*name*/, G_TYPE_STRING /*creator*/, G_TYPE_STRING /*publisher*/, G_TYPE_STRING /*rights*/); GtkWidget *presets = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model)); renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(presets), renderer, FALSE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(presets), renderer, "text", NAME_COLUMN, NULL); sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select name, op_params from presets where operation = \"metadata\"", -1, &stmt, NULL); while(sqlite3_step(stmt) == SQLITE_ROW) { void *op_params = (void *)sqlite3_column_blob(stmt, 1); int32_t op_params_size = sqlite3_column_bytes(stmt, 1); char *buf = (char* )op_params; char *title = buf; buf += strlen(title) + 1; char *description = buf; buf += strlen(description) + 1; char *rights = buf; buf += strlen(rights) + 1; char *creator = buf; buf += strlen(creator) + 1; char *publisher = buf; if(op_params_size == strlen(title) + strlen(description) + strlen(rights) + strlen(creator) + strlen(publisher) + 5) { gtk_list_store_append(model, &iter); gtk_list_store_set (model, &iter, NAME_COLUMN, (char *)sqlite3_column_text(stmt, 0), CREATOR_COLUMN, creator, PUBLISHER_COLUMN, publisher, RIGHTS_COLUMN, rights, -1); } } sqlite3_finalize(stmt); g_object_unref(model); int line = 0; label = gtk_label_new(_("preset")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, line, line+1, GTK_FILL, 0, 0, 0); gtk_table_attach(GTK_TABLE(table), presets, 1, 2, line, line+1, GTK_FILL, 0, 0, 0); line++; label = gtk_label_new(_("creator")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, line, line+1, GTK_FILL, 0, 0, 0); gtk_table_attach(GTK_TABLE(table), creator, 1, 2, line, line+1, GTK_FILL, 0, 0, 0); line++; label = gtk_label_new(_("publisher")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, line, line+1, GTK_FILL, 0, 0, 0); gtk_table_attach(GTK_TABLE(table), publisher, 1, 2, line, line+1, GTK_FILL, 0, 0, 0); line++; label = gtk_label_new(_("rights")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, line, line+1, GTK_FILL, 0, 0, 0); gtk_table_attach(GTK_TABLE(table), rights, 1, 2, line, line+1, GTK_FILL, 0, 0, 0); line++; label = gtk_label_new(_("tags")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, line, line+1, GTK_FILL, 0, 0, 0); gtk_table_attach(GTK_TABLE(table), tags, 1, 2, line, line+1, GTK_FILL, 0, 0, 0); gtk_widget_show_all(frame); if(data != NULL) { data->frame = frame; data->recursive = recursive; data->ignore_jpeg = ignore_jpeg; data->expander = expander; data->apply_metadata = apply_metadata; data->presets = presets; data->creator = creator; data->publisher = publisher; data->rights = rights; data->tags = tags; } g_signal_connect(apply_metadata, "toggled", G_CALLBACK (_lib_import_apply_metadata_toggled), table); _lib_import_apply_metadata_toggled(apply_metadata, table); // needed since the apply_metadata starts being turned off, // and setting it to off doesn't emit the 'toggled' signal ... g_signal_connect(presets, "changed", G_CALLBACK(_lib_import_presets_changed), data); g_signal_connect(GTK_ENTRY(creator), "changed", G_CALLBACK (_lib_import_metadata_changed), presets); g_signal_connect(GTK_ENTRY(publisher), "changed", G_CALLBACK (_lib_import_metadata_changed), presets); g_signal_connect(GTK_ENTRY(rights), "changed", G_CALLBACK (_lib_import_metadata_changed), presets); return frame; }
static void dt_lib_presets_popup_menu_show(dt_lib_module_info_t *minfo) { GtkMenu *menu = darktable.gui->presets_popup_menu; if(menu) gtk_widget_destroy(GTK_WIDGET(menu)); darktable.gui->presets_popup_menu = GTK_MENU(gtk_menu_new()); menu = darktable.gui->presets_popup_menu; GtkWidget *mi; int active_preset = -1, cnt = 0, writeprotect = 0; sqlite3_stmt *stmt; // order: get shipped defaults first DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select name, op_params, writeprotect, description from presets where " "operation=?1 and op_version=?2 order by writeprotect desc, name, rowid", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, minfo->plugin_name, -1, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(stmt, 2, minfo->version); // collect all presets for op from db int found = 0; while(sqlite3_step(stmt) == SQLITE_ROW) { void *op_params = (void *)sqlite3_column_blob(stmt, 1); int32_t op_params_size = sqlite3_column_bytes(stmt, 1); const char *name = (char *)sqlite3_column_text(stmt, 0); if(darktable.gui->last_preset && strcmp(darktable.gui->last_preset, name) == 0) found = 1; // selected in bold: // printf("comparing %d bytes to %d\n", op_params_size, minfo->params_size); // for(int k=0;k<op_params_size && !memcmp(minfo->params, op_params, k);k++) printf("compare [%c %c] %d: // %d\n", // ((const char*)(minfo->params))[k], // ((const char*)(op_params))[k], // k, memcmp(minfo->params, op_params, k)); if(op_params_size == minfo->params_size && !memcmp(minfo->params, op_params, op_params_size)) { active_preset = cnt; writeprotect = sqlite3_column_int(stmt, 2); char *markup; mi = gtk_menu_item_new_with_label(""); markup = g_markup_printf_escaped("<span weight=\"bold\">%s</span>", name); gtk_label_set_markup(GTK_LABEL(gtk_bin_get_child(GTK_BIN(mi))), markup); g_free(markup); } else { mi = gtk_menu_item_new_with_label((const char *)name); } g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(pick_callback), minfo); g_object_set(G_OBJECT(mi), "tooltip-text", sqlite3_column_text(stmt, 3), (char *)NULL); gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); cnt++; } sqlite3_finalize(stmt); if(cnt > 0) gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_separator_menu_item_new()); // FIXME: this doesn't seem to work. if(active_preset >= 0) { if(!writeprotect) { mi = gtk_menu_item_new_with_label(_("edit this preset..")); g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(menuitem_edit_preset), minfo); gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); mi = gtk_menu_item_new_with_label(_("delete this preset")); g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(menuitem_delete_preset), minfo); gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); } } else { mi = gtk_menu_item_new_with_label(_("store new preset..")); g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(menuitem_new_preset), minfo); gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); if(darktable.gui->last_preset && found) { char label[128]; g_strlcpy(label, _("update preset"), sizeof(label)); g_strlcat(label, " <span weight=\"bold\">%s</span>", sizeof(label)); char *markup = g_markup_printf_escaped(label, darktable.gui->last_preset); mi = gtk_menu_item_new_with_label(""); gtk_label_set_markup(GTK_LABEL(gtk_bin_get_child(GTK_BIN(mi))), markup); g_signal_connect(G_OBJECT(mi), "activate", G_CALLBACK(menuitem_update_preset), minfo); gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi); g_free(markup); } } }
static void init_presets(dt_lib_module_t *module) { // since lighttable presets can't end up in styles or any other place outside of the presets table it is // sufficient // to update that very table here and assume that everything is up to date elsewhere. // the intended logic is as follows: // - no set_params -> delete all presets // - op_version >= module_version -> done // - op_version < module_version -> // - module has legacy_params -> try to update // - module doesn't have legacy_params -> delete it if(module->set_params == NULL) { sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "delete from presets where operation=?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, module->plugin_name, -1, SQLITE_TRANSIENT); sqlite3_step(stmt); sqlite3_finalize(stmt); } else { sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select rowid, op_version, op_params, name from presets where operation=?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_TEXT(stmt, 1, module->plugin_name, -1, SQLITE_TRANSIENT); while(sqlite3_step(stmt) == SQLITE_ROW) { int rowid = sqlite3_column_int(stmt, 0); int op_version = sqlite3_column_int(stmt, 1); void *op_params = (void *)sqlite3_column_blob(stmt, 2); size_t op_params_size = sqlite3_column_bytes(stmt, 2); const char *name = (char *)sqlite3_column_text(stmt, 3); int version = module->version(); if(op_version < version) { size_t new_params_size = 0; void *new_params = NULL; if(module->legacy_params && (new_params = module->legacy_params(module, op_params, op_params_size, op_version, version, &new_params_size))) { // write the updated preset back to db fprintf(stderr, "[lighttable_init_presets] updating '%s' preset '%s' from version %d to version %d\n", module->plugin_name, name, op_version, version); sqlite3_stmt *innerstmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "update presets set op_version=?1, op_params=?2 where rowid=?3", -1, &innerstmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(innerstmt, 1, version); DT_DEBUG_SQLITE3_BIND_BLOB(innerstmt, 2, new_params, new_params_size, SQLITE_TRANSIENT); DT_DEBUG_SQLITE3_BIND_INT(innerstmt, 3, rowid); sqlite3_step(innerstmt); sqlite3_finalize(innerstmt); } else { // delete the preset fprintf(stderr, "[lighttable_init_presets] Can't upgrade '%s' preset '%s' from version %d to %d, " "no legacy_params() implemented or unable to update\n", module->plugin_name, name, op_version, version); sqlite3_stmt *innerstmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "delete from presets where rowid=?1", -1, &innerstmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(innerstmt, 1, rowid); sqlite3_step(innerstmt); sqlite3_finalize(innerstmt); } free(new_params); } } sqlite3_finalize(stmt); } if(module->init_presets) module->init_presets(module); }
VALUE do_sqlite3_typecast(sqlite3_stmt *stmt, int i, VALUE type, int encoding) { int original_type = sqlite3_column_type(stmt, i); int length = sqlite3_column_bytes(stmt, i); if (original_type == SQLITE_NULL) { return Qnil; } #ifdef HAVE_RUBY_ENCODING_H rb_encoding *internal_encoding = rb_default_internal_encoding(); #else void *internal_encoding = NULL; #endif if (type == Qnil) { switch (original_type) { case SQLITE_INTEGER: type = rb_cInteger; break; case SQLITE_FLOAT: type = rb_cFloat; break; case SQLITE_BLOB: type = rb_cByteArray; break; default: type = rb_cString; break; } } if (type == rb_cInteger) { return LL2NUM(sqlite3_column_int64(stmt, i)); } else if (type == rb_cString) { return DATA_OBJECTS_STR_NEW((char*)sqlite3_column_text(stmt, i), length, encoding, internal_encoding); } else if (type == rb_cFloat) { return rb_float_new(sqlite3_column_double(stmt, i)); } else if (type == rb_cBigDecimal) { return rb_funcall(rb_cBigDecimal, ID_NEW, 1, rb_str_new((char*)sqlite3_column_text(stmt, i), length)); } else if (type == rb_cDate) { return data_objects_parse_date((char*)sqlite3_column_text(stmt, i)); } else if (type == rb_cDateTime) { return data_objects_parse_date_time((char*)sqlite3_column_text(stmt, i)); } else if (type == rb_cTime) { return data_objects_parse_time((char*)sqlite3_column_text(stmt, i)); } else if (type == rb_cTrueClass) { return strcmp((char*)sqlite3_column_text(stmt, i), "t") == 0 ? Qtrue : Qfalse; } else if (type == rb_cByteArray) { return rb_funcall(rb_cByteArray, ID_NEW, 1, rb_str_new((char*)sqlite3_column_blob(stmt, i), length)); } else if (type == rb_cClass) { return rb_funcall(mDO, rb_intern("full_const_get"), 1, rb_str_new((char*)sqlite3_column_text(stmt, i), length)); } else if (type == rb_cNilClass) { return Qnil; } else { return DATA_OBJECTS_STR_NEW((char*)sqlite3_column_text(stmt, i), length, encoding, internal_encoding); } }
void OGRGeoPackageLayer::BuildFeatureDefn( const char *pszLayerName, sqlite3_stmt *hStmt ) { m_poFeatureDefn = new OGRSQLiteFeatureDefn( pszLayerName ); SetDescription( m_poFeatureDefn->GetName() ); m_poFeatureDefn->SetGeomType(wkbNone); m_poFeatureDefn->Reference(); int nRawColumns = sqlite3_column_count( hStmt ); panFieldOrdinals = (int *) CPLMalloc( sizeof(int) * nRawColumns ); int iCol; for( iCol = 0; iCol < nRawColumns; iCol++ ) { OGRFieldDefn oField( OGRSQLiteParamsUnquote(sqlite3_column_name( hStmt, iCol )), OFTString ); // In some cases, particularly when there is a real name for // the primary key/_rowid_ column we will end up getting the // primary key column appearing twice. Ignore any repeated names. if( m_poFeatureDefn->GetFieldIndex( oField.GetNameRef() ) != -1 ) continue; if( EQUAL(oField.GetNameRef(), "FID") ) { CPLFree(m_pszFidColumn); m_pszFidColumn = CPLStrdup(oField.GetNameRef()); iFIDCol = iCol; } if( m_pszFidColumn != NULL && EQUAL(m_pszFidColumn, oField.GetNameRef())) continue; // The rowid is for internal use, not a real column. if( EQUAL(oField.GetNameRef(),"_rowid_") ) continue; int nColType = sqlite3_column_type( hStmt, iCol ); const char * pszDeclType = sqlite3_column_decltype(hStmt, iCol); // Recognize a geometry column from trying to build the geometry // Usefull for OGRSQLiteSelectLayer if( nColType == SQLITE_BLOB && m_poFeatureDefn->GetGeomFieldCount() == 0 ) { const int nBytes = sqlite3_column_bytes( hStmt, iCol ); if( nBytes > 4 ) { const GByte* pabyGpkg = (const GByte*)sqlite3_column_blob( hStmt, iCol ); GPkgHeader oHeader; if( GPkgHeaderFromWKB(pabyGpkg, &oHeader) == OGRERR_NONE ) { OGRGeomFieldDefn oGeomField(oField.GetNameRef(), wkbUnknown); /* Read the SRS */ OGRSpatialReference *poSRS = m_poDS->GetSpatialRef(oHeader.iSrsId); if ( poSRS ) { oGeomField.SetSpatialRef(poSRS); poSRS->Dereference(); } OGRwkbGeometryType eGeomType = wkbUnknown; if( pszDeclType != NULL ) { eGeomType = GPkgGeometryTypeToWKB(pszDeclType, (oHeader.iDims == 3)); if( eGeomType != wkbNone ) oGeomField.SetType( eGeomType ); } #ifdef SQLITE_HAS_COLUMN_METADATA const char* pszTableName = sqlite3_column_table_name( hStmt, iCol ); if( oGeomField.GetType() == wkbUnknown && pszTableName != NULL ) { OGRGeoPackageLayer* poLayer = (OGRGeoPackageLayer*) m_poDS->GetLayerByName(pszTableName); if( poLayer != NULL && poLayer->GetLayerDefn()->GetGeomFieldCount() > 0) { oGeomField.SetType( poLayer->GetLayerDefn()->GetGeomFieldDefn(0)->GetType() ); } } #endif m_poFeatureDefn->AddGeomFieldDefn(&oGeomField); iGeomCol = iCol; continue; } } } switch( nColType ) { case SQLITE_INTEGER: oField.SetType( OFTInteger ); break; case SQLITE_FLOAT: oField.SetType( OFTReal ); break; case SQLITE_BLOB: oField.SetType( OFTBinary ); break; default: /* leave it as OFTString */; } if (pszDeclType != NULL) { OGRFieldType eFieldType = GPkgFieldToOGR(pszDeclType); if( (int)eFieldType <= OFTMaxType ) oField.SetType(eFieldType); } m_poFeatureDefn->AddFieldDefn( &oField ); panFieldOrdinals[m_poFeatureDefn->GetFieldCount() - 1] = iCol; } }
OGRFeature *OGRGeoPackageLayer::TranslateFeature( sqlite3_stmt* hStmt ) { /* -------------------------------------------------------------------- */ /* Create a feature from the current result. */ /* -------------------------------------------------------------------- */ int iField; OGRFeature *poFeature = new OGRFeature( m_poFeatureDefn ); /* -------------------------------------------------------------------- */ /* Set FID if we have a column to set it from. */ /* -------------------------------------------------------------------- */ if( iFIDCol >= 0 ) poFeature->SetFID( sqlite3_column_int64( hStmt, iFIDCol ) ); else poFeature->SetFID( iNextShapeId ); iNextShapeId++; m_nFeaturesRead++; /* -------------------------------------------------------------------- */ /* Process Geometry if we have a column. */ /* -------------------------------------------------------------------- */ if( iGeomCol >= 0 ) { OGRGeomFieldDefn* poGeomFieldDefn = m_poFeatureDefn->GetGeomFieldDefn(0); if ( sqlite3_column_type(hStmt, iGeomCol) != SQLITE_NULL && !poGeomFieldDefn->IsIgnored() ) { OGRSpatialReference* poSrs = poGeomFieldDefn->GetSpatialRef(); int iGpkgSize = sqlite3_column_bytes(hStmt, iGeomCol); GByte *pabyGpkg = (GByte *)sqlite3_column_blob(hStmt, iGeomCol); OGRGeometry *poGeom = GPkgGeometryToOGR(pabyGpkg, iGpkgSize, poSrs); if ( ! poGeom ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to read geometry"); } poFeature->SetGeometryDirectly( poGeom ); } } /* -------------------------------------------------------------------- */ /* set the fields. */ /* -------------------------------------------------------------------- */ for( iField = 0; iField < m_poFeatureDefn->GetFieldCount(); iField++ ) { OGRFieldDefn *poFieldDefn = m_poFeatureDefn->GetFieldDefn( iField ); if ( poFieldDefn->IsIgnored() ) continue; int iRawField = panFieldOrdinals[iField]; if( sqlite3_column_type( hStmt, iRawField ) == SQLITE_NULL ) continue; switch( poFieldDefn->GetType() ) { case OFTInteger: //FIXME use int64 when OGR has 64bit integer support poFeature->SetField( iField, sqlite3_column_int( hStmt, iRawField ) ); break; case OFTReal: poFeature->SetField( iField, sqlite3_column_double( hStmt, iRawField ) ); break; case OFTBinary: { const int nBytes = sqlite3_column_bytes( hStmt, iRawField ); poFeature->SetField( iField, nBytes, (GByte*)sqlite3_column_blob( hStmt, iRawField ) ); break; } case OFTDate: { const char* pszTxt = (const char*)sqlite3_column_text( hStmt, iRawField ); int nYear, nMonth, nDay; if( sscanf(pszTxt, "%d-%d-%d", &nYear, &nMonth, &nDay) == 3 ) poFeature->SetField(iField, nYear, nMonth, nDay, 0, 0, 0, 0); break; } case OFTDateTime: { const char* pszTxt = (const char*)sqlite3_column_text( hStmt, iRawField ); int nYear, nMonth, nDay, nHour, nMinute; float fSecond; if( sscanf(pszTxt, "%d-%d-%dT%d:%d:%fZ", &nYear, &nMonth, &nDay, &nHour, &nMinute, &fSecond) == 6 ) poFeature->SetField(iField, nYear, nMonth, nDay, nHour, nMinute, (int)(fSecond + 0.5), 0); break; } case OFTString: poFeature->SetField( iField, (const char *) sqlite3_column_text( hStmt, iRawField ) ); break; default: break; } } return poFeature; }
/** * Convert a row from result into db API representation */ int db_sqlite_convert_row(const db_con_t* _h, db_res_t* _res, db_row_t* _r) { int col; db_val_t* _v; const char* db_value; if ((!_h) || (!_res) || (!_r)) { LM_ERR("invalid parameter value\n"); return -1; } if (!CON_SQLITE_PS(_h)) { LM_ERR("conn has no prepared statement! sqlite requires one\n"); return -1; } /* Save the number of columns in the ROW structure */ ROW_N(_r) = RES_COL_N(_res); for(col=0; col < RES_COL_N(_res); col++) { _v = &(ROW_VALUES(_r)[col]); if (sqlite3_column_type(CON_SQLITE_PS(_h), col) == SQLITE_NULL) { VAL_NULL(_v) = 1; continue; } switch (RES_TYPES(_res)[col]) { case DB_INT: VAL_INT(_v) = sqlite3_column_int(CON_SQLITE_PS(_h), col); VAL_TYPE(_v) = DB_INT; break; case DB_BIGINT: VAL_BIGINT(_v) = sqlite3_column_int64(CON_SQLITE_PS(_h), col); VAL_TYPE(_v) = DB_BIGINT; break; case DB_DATETIME: db_value = (char *)sqlite3_column_text(CON_SQLITE_PS(_h), col); if (db_str2time(db_value, &VAL_TIME(_v)) < 0) { LM_ERR("error while converting datetime value from string\n"); return -1; } VAL_TYPE(_v) = DB_DATETIME; break; case DB_DOUBLE: VAL_DOUBLE(_v) = sqlite3_column_double(CON_SQLITE_PS(_h), col); VAL_TYPE(_v) = DB_DOUBLE; break; case DB_BLOB: VAL_BLOB(_v).len = sqlite3_column_bytes(CON_SQLITE_PS(_h), col); db_value = sqlite3_column_blob(CON_SQLITE_PS(_h), col); VAL_BLOB(_v).s = pkg_malloc(VAL_BLOB(_v).len+1); memcpy(VAL_BLOB(_v).s, db_value, VAL_BLOB(_v).len); VAL_BLOB(_v).s[VAL_BLOB(_v).len]='\0'; VAL_TYPE(_v) = DB_BLOB; break; case DB_STRING: VAL_STR(_v).len = sqlite3_column_bytes(CON_SQLITE_PS(_h), col); db_value = (char *)sqlite3_column_text(CON_SQLITE_PS(_h), col); VAL_STR(_v).s = pkg_malloc(VAL_STR(_v).len+1); memcpy(VAL_STR(_v).s, db_value, VAL_STR(_v).len); VAL_STR(_v).s[VAL_STR(_v).len]='\0'; VAL_TYPE(_v) = DB_STR; break; default: LM_ERR("invalid type for sqlite!\n"); return -1; } } return 0; }
static void Database_query (LIScrArgs* args) { int i; int col; int row; int ret; int size; const char* query; const char* str; sqlite3* self; LIArcPacket* packet; LIScrData* data; sqlite3_stmt* statement; self = args->self; if (!liscr_args_geti_string (args, 0, &query) && !liscr_args_gets_string (args, "query", &query)) return; /* Create a statement. */ if (sqlite3_prepare_v2 (self, query, -1, &statement, NULL) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL prepare: %s", sqlite3_errmsg (self)); lisys_error_report (); return; } /* Bind variables. */ if (liscr_args_geti_table (args, 1) || liscr_args_gets_table (args, "bind")) { for (i = 1 ; i < sqlite3_bind_parameter_count (statement) + 1 ; i++) { /* We got a table that has the bound variables in fields matching the indices of the bound variables. We can simply loop through the table and use the binding index as the key. */ lua_pushnumber (args->lua, i); lua_gettable (args->lua, -2); switch (lua_type (args->lua, -1)) { /* Bind numbers as doubles. */ case LUA_TNUMBER: if (sqlite3_bind_double (statement, i, lua_tonumber (args->lua, -1)) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; /* Bind strings as text. */ case LUA_TSTRING: if (sqlite3_bind_text (statement, i, lua_tostring (args->lua, -1), -1, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; /* Bind packets as blobs. */ case LUA_TUSERDATA: data = liscr_isdata (args->lua, -1, LISCR_SCRIPT_PACKET); if (data == NULL) break; packet = liscr_data_get_data (data); if (packet->writer != NULL) { if (sqlite3_bind_blob (statement, i, packet->writer->memory.buffer, packet->writer->memory.length, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } } else { if (sqlite3_bind_blob (statement, i, packet->reader->buffer, packet->reader->length, SQLITE_TRANSIENT) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } } break; /* Bind any other values as NULL. */ default: if (sqlite3_bind_null (statement, i) != SQLITE_OK) { lisys_error_set (EINVAL, "SQL bind: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } break; } lua_pop (args->lua, 1); } lua_pop (args->lua, 1); } /* Execute the statement and process results. */ for (row = 0, ret = sqlite3_step (statement) ; ret != SQLITE_DONE ; ret = sqlite3_step (statement), row++) { /* Check for errors. */ if (ret != SQLITE_ROW) { lisys_error_set (EINVAL, "SQL step: %s", sqlite3_errmsg (self)); lisys_error_report (); sqlite3_finalize (statement); return; } if (!row) liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); /* Create a row table. */ lua_newtable (args->lua); /* Push the columns to the table. */ for (col = 0 ; col < sqlite3_column_count (statement) ; col++) { switch (sqlite3_column_type (statement, col)) { case SQLITE_INTEGER: lua_pushnumber (args->lua, col + 1); lua_pushnumber (args->lua, sqlite3_column_int (statement, col)); lua_settable (args->lua, -3); break; case SQLITE_FLOAT: lua_pushnumber (args->lua, col + 1); lua_pushnumber (args->lua, sqlite3_column_double (statement, col)); lua_settable (args->lua, -3); break; case SQLITE_TEXT: str = (const char*) sqlite3_column_text (statement, col); size = sqlite3_column_bytes (statement, col); lua_pushnumber (args->lua, col + 1); if (size > 0 && str != NULL) lua_pushstring (args->lua, str); else lua_pushstring (args->lua, str); lua_settable (args->lua, -3); break; case SQLITE_BLOB: str = sqlite3_column_blob (statement, col); size = sqlite3_column_bytes (statement, col); packet = liarc_packet_new_readable (str, size); if (packet != NULL) { lua_pushnumber (args->lua, col + 1); data = liscr_data_new (args->script, args->lua, packet, LISCR_SCRIPT_PACKET, liarc_packet_free); if (data != NULL) lua_settable (args->lua, -3); else { lua_pop (args->lua, 1); liarc_packet_free (packet); } } break; case SQLITE_NULL: break; default: lisys_assert (0 && "invalid column type"); break; } } /* Add the row to the return values. */ liscr_args_seti_stack (args); } if (!row) liscr_args_set_output (args, LISCR_ARGS_OUTPUT_TABLE_FORCE); sqlite3_finalize (statement); }