Suche die Datenbank die zu mir passt

Algorithmen, Sprachunabhängige Diskussionen zu Konzepten, Programmiersprachen-Design
AnGaiNoR
Beiträge: 212
Registriert: Sa Jul 19, 2008 7:07 pm
Wohnort: Dresden

Re: Suche die Datenbank die zu mir passt

Beitrag von AnGaiNoR » Do Dez 03, 2009 6:09 pm

Bebu hat geschrieben:Hui, bin grade ganz erschlagen von meiner Unwissenheit Kerli :oops:
Deine Klasse muss ich mir mal ganz in Ruhe ansehen, mein Wissen über Klassen ist wohl noch seeeeeehhhhhrrrrr ausbaufähig.
Aber trotzdem danke dafür, ich denke das wird mir noch sehr nützlich sein.
Die Klasse, die dir da präsentiert wurde, hat aber nur eher mäßig viel mit OOP zu tun; sollte also auch ohne alzu große Probleme verständlich sein.
Physics is like sex: sure, it may give some practical result, but that's not why we do it.
(Richard P. Feynman)

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Suche die Datenbank die zu mir passt

Beitrag von Kerli » Do Dez 03, 2009 7:15 pm

AnGaiNoR hat geschrieben:Die Klasse, die dir da präsentiert wurde, hat aber nur eher mäßig viel mit OOP zu tun; sollte also auch ohne alzu große Probleme verständlich sein.
Die Frage ist ab wann ist etwas objektorientiert und wann noch nicht :P Aber es stimmt schon, sobald man weiß was Klassen, Konstruktor/Destruktor und Methoden sind sollte es kein Problem sein die Klasse zu verwenden bzw. zu verstehen.

In dem Fall repräsentiert die Klasse eine Datenbankverbindung nach dem RAII Prinzip, dh. im Konstruktor wird eine Datenbankverbindung aufgemacht, dann kann man mit ihr Arbeiten, und sobald der Gültigkeitsbereich verlassen wird, wird die Verbindungen zur Datenbank wieder geschlossen.
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

AnGaiNoR
Beiträge: 212
Registriert: Sa Jul 19, 2008 7:07 pm
Wohnort: Dresden

Re: Suche die Datenbank die zu mir passt

Beitrag von AnGaiNoR » Do Dez 03, 2009 7:49 pm

Kerli hat geschrieben: Die Frage ist ab wann ist etwas objektorientiert und wann noch nicht :P
Objektorientierung in C++ fängt bei mir bei einem gezielten virtual an ^^ (Außer natürlich bei Destruktoren, die ich im Normalfall immer als virtual deklariere.)
Physics is like sex: sure, it may give some practical result, but that's not why we do it.
(Richard P. Feynman)

Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Re: Suche die Datenbank die zu mir passt

Beitrag von Bebu » Do Dez 03, 2009 10:12 pm

Sie hat mich in dem Moment nur umgehauen, weil ich mich mit Konstruktor und Destruktor bis dahin noch nicht befasst hatte und mir den Teil überhaupt nicht erklären konnte. Außerdem bin ich mit der STL auch erst am Anfang, aber das wird schon. Die Funktionen kann ich größtenteils nachvollziehen, ich muss mich aber erst noch genauer in die libsqlite hineinarbeiten, damit sich der Sinn der Funktionen bis ins Detail erschließt und da mir in letzter Zeit die Zeit und auch die Muse gefehlt hat... Na ihr wisst ja wie das ist ;)
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Re: Suche die Datenbank die zu mir passt

Beitrag von Bebu » Fr Dez 04, 2009 2:45 pm

Sorry für den Doppelpost, ich habe eine Frage an Kerli: Ich habe jetzt der Einfachheit halber, deine Wrapperklasse und deine Main mal in eine Datei zusammengefasst:

Code: Alles auswählen

//------------------------------------------------------------------------------
// sqlite_cpp.hpp
// (c) copyright 2009 Thomas Geymayer <tomgey@gmail.com>
//------------------------------------------------------------------------------

/*!
* @file
* @brief
* @details
* @author Thomas Geymayer <tomgey@gmail.com>
* @date Date of Creation: 24.10.2009
*/

#include <string>
#include <sqlite3.h>
#include <stdexcept>
#include <vector>
#include <map>
#include <iostream>

class SQLite
{
  public:

    typedef std::map<std::string,std::string> Row;
    typedef std::vector<Row> Result;

    //--------------------------------------------------------------------------
    SQLite( const std::string& dbase)
    {
      checkCall( sqlite3_open(dbase.c_str(), &_db) );
    }

    //--------------------------------------------------------------------------
    ~SQLite()
    {
      sqlite3_close(_db);
    }

    //--------------------------------------------------------------------------
    Result query( const std::string& query )
    {
      //std::cout << query << std::endl;

      sqlite3_stmt *stmt;
      checkCall( sqlite3_prepare_v2(_db, query.c_str(), query.size(), &stmt, 0) );

      int cols = sqlite3_column_count(stmt);
      Result result;

      while( sqlite3_step(stmt) == SQLITE_ROW )
      {
        Row cur_row;

        for( int i = 0; i < cols; ++i )
        {
          if( !sqlite3_column_name(stmt,i) )
            continue;

          std::string name( sqlite3_column_name(stmt,i) );
          if( name.empty() )
            continue;

          std::string value;
          if( sqlite3_column_text(stmt,i) )
            value = reinterpret_cast<const char*>(sqlite3_column_text(stmt,i));

          cur_row[ name ] = value;
        }

        result.push_back(cur_row);
      }

      sqlite3_finalize(stmt);

      return result;
    }

    //--------------------------------------------------------------------------
    void insert( const std::string& table,
                 const Row& values )
    {
      std::string col_names, col_values;

      for( Row::const_iterator col = values.begin();
          col != values.end();
          ++col )
      {
        if( !col_names.empty() )
        {
          col_names  += ",";
          col_values += ",";
        }

        col_names  += "`" + col->first  + "`";
        col_values += "'" + col->second + "'";
      }

      query(  "INSERT INTO " + table
            + " (" + col_names + ") VALUES (" + col_values + ")" );
    }

    //--------------------------------------------------------------------------
    Result select( const std::string& table,
                   const Row& values )
    {
      std::string checks;

      for( Row::const_iterator col = values.begin();
          col != values.end();
          ++col )
      {
        if( !checks.empty() )
          checks += " and ";

        checks += "`" + col->first + "`='" + col->second + "'";
      }

      return query( "SELECT * FROM " + table + " WHERE " + checks );
    }

    //--------------------------------------------------------------------------
    void update( const std::string& table,
                 const Row& values,
                 const std::string& where )
    {
      std::string sets;

      for( Row::const_iterator col = values.begin();
          col != values.end();
          ++col )
      {
        if( !sets.empty() )
          sets += ',';

        sets += "`" + col->first  + "`='" + col->second + "'";
      }

      query(  "UPDATE " + table + " SET " + sets + " WHERE " + where );
    }

    //--------------------------------------------------------------------------
    void deleteFrom( const std::string& table,
                     const Row& checks,
                     const std::string& id_col )
    {
      Result values = select(table, checks);

      for( Result::const_iterator row = values.begin();
          row != values.end();
          ++row )
      {
        query(   "DELETE FROM " + table
               + " WHERE `" + id_col + "`='" + row->at(id_col) + "'" );
      }
    }

  private:

    void checkCall( int retval )
    {
      if( retval != SQLITE_OK )
        throw std::runtime_error( sqlite3_errmsg(_db) );
    }
sqlite3* _db;
};



int main(int argc, char* argv[])
{
  // open the database
  SQLite db("messages.db");

  // create new entry
  SQLite::Row input;
  input["type"        ] = argv[2];
  input["host"        ] = argv[3];
  input["service"     ] = argv[4];
  input["state"       ] = argv[5];
  input["duration"    ] = argv[6];
  input["email"       ] = argv[7];

  std::cout << "Inserting new notification..." << std::endl;
  db.insert("messages", input);

  // print out the database
  SQLite::Result result = db.query("select * from messages");

  for( SQLite::Result::iterator row = result.begin();
       row != result.end();
       ++row )
  {
    std::cout << "-----------------------------------------------------------"
              << "---------------------" << std::endl;
    std::cout << row->at("id")      << "|"
              << row->at("type")    << "|"
              << row->at("host")    << "|"
              << row->at("service") << "|"
              << row->at("state")   << "|"
              << row->at("duration")<< "|"
              << row->at("inserted")<< "|"
              << row->at("message_sent")
              << std::endl;
  }

  return 0;
}
Allerdings will die ganze Sache nicht kompilieren. Ich bekomme für eine Fehlermeldung in der Checkcall Funktion: "undefined reference to 'sqlite3_errmsg'" Wenn ich die Zeile auskommentiere und eine leere Anweisung einfüge, moniert er den selben Fehler an anderer Stelle. Woran liegt das? Muss die "sqlite3* _db;"-Anweisung eher erfolgen?
Vielleicht wirst du daraus schlau, habs mit GNU GCC unter Codeblocks probiert.
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Suche die Datenbank die zu mir passt

Beitrag von Kerli » Fr Dez 04, 2009 5:36 pm

Bebu hat geschrieben:Ich habe jetzt der Einfachheit halber, deine Wrapperklasse und deine Main mal in eine Datei zusammengefasst:
Ich glaub ich werd das jetzt einmal wirklich ins Wiki packen :P
Bebu hat geschrieben:Ich bekomme für eine Fehlermeldung in der Checkcall Funktion: "undefined reference to 'sqlite3_errmsg'" Wenn ich die Zeile auskommentiere und eine leere Anweisung einfüge, moniert er den selben Fehler an anderer Stelle. Woran liegt das? Muss die "sqlite3* _db;"-Anweisung eher erfolgen?
Nein, das ist es nicht. Ich würde einmal darauf tippen dass du nicht zur libsqlite linkst...

Code: Alles auswählen

g++ -o sqlite_test sqlite.cpp -lsqlite3
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Benutzeravatar
Bebu
Beiträge: 562
Registriert: Mi Okt 21, 2009 6:19 pm
Wohnort: In der Nähe von Salzburg - Bin aber kein Österreicher!

Re: Suche die Datenbank die zu mir passt

Beitrag von Bebu » Fr Dez 04, 2009 10:23 pm

Tja so einfach kann das sein. Aber wenn man es nicht weiß, dann kommt man nie drauf
Wer immer nach dem Unerreichbaren jagt, der wird irgendwann auf die Schnauze fallen!

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Suche die Datenbank die zu mir passt

Beitrag von Kerli » Fr Dez 04, 2009 10:40 pm

Aus Fehlern lernt man. Und irgendwann weißt du dann auch dass "undefined references" auf fehlende Objektdateien und oft eben auch Bibliotheken zurück zu führen sind ;)
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Antworten