Source: sqlguipart/sqlguidoc.h


Annotated List
Files
Globals
Hierarchy
Index
/***************************************************************************
                          sqlguidoc.h  -  description
                             -------------------
    begin                : Sat Apr 14 18:28:06 CEST 2001
    copyright            : (C) 2001 by mb
    email                : marcus@beranek.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef SQLGUIDOC_H
#define SQLGUIDOC_H

#ifdef HAVE_CONFIG_H
#include 
#endif 

// include files for QT
#include 
#include 
#include 

// include files for KDE
#include 

#include 
#include 

class SqlGuiView;
class KLocale;

#include "db_components.h"


class SqlGuiDoc : public QObject{

 Q_OBJECT

 public:
 /**
  *  API-Documentation for SqlGui
  *
  *  Note: to use this class, you must include the following: #include <sqlgui/sqlguidoc.h> and not <sqlguipart/sqlguidoc.h> as the headline says...
  *
  *  Note: This API is still under development and considered beta. The API might change in the future without notice. 
  *  SqlGui comes with libraries for the MySQL- and the PostgreSQL-database-system. These libraries fully implement the SqlGui-API.
  *  These libraries may be used as a "reference"-implementation.
  *
  *  SqlGuiDoc is the base class for communication with the database-server. All classes, which are used by sqlgui for communication with a database, should inherit from SqlGuiDoc.
  *  There is no need to overload the constructor, but you must reimplement the following member-functions:
  *
  * 
  *   openDocument  (very important, see below)
  *   slotDoQuery   (very important, see below)
  * 
  *   slotDbCreate
  *   slotDbDelete
  *   slotTableDelete
  *   slotTableCheck
  *   slotTableOptimize
  *   slotTableRepair
  *   slotServerStatus
  *   slotCountRows
  *
  * 
* * The starting-point is the internal representation of a databse-server. The member "DB" * is a pointer to this internal representation. DB points to the struct "base". * This structure contains all databases SqlGuiDoc finds on the connected server. * It has also pointers to the tables, which belong to the databases. * * The structure has the following definition: *
  * typedef
  * struct base {
  *     const char * name;     // basename
  *     table_t * table_list;  // list of tables in this database
  *     struct base * next;    // pointer to the next database
  * } base_t;
  * 
* * @see db_components.h * * The internal representation of the database-server is a linked list. * The list-linkage is simple, i.e. you can go from one element to the next one, but you can't go back. * *
  *   db1 -> db2 -> db3 -> ... -> NULL
  * 
* * There's no real need for a more complex structure, because sqlgui needs to get the elements once, everything else * (like sorting) is done by the database itself or the view (in SqlGuiView, which makes use of QTable, which handles sorting). * * Every entry in this list contains the name of the database, a pointer to its tables and a pointer to the next database: * *
  *   db1
  *    -> name
  *    -> table_list
  *    -> next
  * 
* * The fisrt element of this list is always "DB". * To go through the whole structure you just need to do the following: * *
  * #include "db_components.h"
  *
  * base_t * b = DB;
  *
  * while (b) {
  *     // do something with this base, for example read basename:
  *     cout << b->name << endl;
  *     // goto next base:
  *     b = b->next;
  * }
  *
  * 
* * The last entry of the list must be a NULL-pointer. * * The same mechanism is used for tables and their columnes: * *
  *   db1 -> table_list
  *             |
  *             tb1 -> tb2 -> tb3 -> ... -> NULL
  *             |
  *             colum_list
  *                |
  *                col1 -> col2 -> col3 -> ... -> NULL
  *
  * 
* * The table_list and column_list have the following definition (defined in db_components.h): * *
  * typedef
  * struct column{
  *     const char * name;          // column-name
  *     char * type;                // string, describing the column-type (depends on database).
  *     char pri;                   // 'Y' if column is primary-key, ' ' otherwise.
  *     const char * extra_flags;   // for attributes like INDEX, NOT NULL, AUTO_INC etc.
  *     struct column * next;       // pointer to the next column in list. last pointer in list must be a NULL-pointer.
  * } column_t;
  *
  * typedef
  * struct table{
  *     const char * name;          // table-name
  *     int type;                   // table-type (reserved. should be 0)
  *     const char * type_n;        // name of the table type (reserved. should be '')
  *     column_t * column_list;     // pointer to the columnes in this table
  *     struct table * next;        // pointer to the next table in this database. last pointer in list must be a NULL-pointer.
  * } table_t;
  *
  * 
* * To traverse the full server-structure, you need to do something like this: * *
  * #include "db_components.h"
  *
  * base_t * b = DB;
  *
  * while (b) {
  *     // do something with the database:
  *     cout << "Database " << d->name << ":" << endl;
  *     table_t * t = b->table_list;
  *
  *     while (t) {
  *         // do something with the table:
  *         cout << "  Table " << t->name << ":" << endl;
  *         column_t * c = t->column_list;
  *
  *         while(c) {
  *             // do something with the column:
  *             cout << "    Column " << c->name << endl;
  *             c = c->next;
  *         }
  *         t = t->next;
  *     }
  *     b = b->next;
  * }
  *
  * 
* * When building your own library for a specific database, you have to remember to include the following two factory-functions in your library (i.e. in the file "sqlguidoc_YOURDB.cpp"): * *
  * extern "C" SqlGuiDoc* create(QWidget *parent, const char *name){
  *     return new SqlGuiDocMysql( parent, name );      //  replace SqlGuiDocMysql with SqlGuiDocYOURDB
  * }
  *
  * extern "C" void destroy( SqlGuiDoc* p){
  *     delete p;
  * }
  *
  *
* * These to functions are needed by SqlguiPart to load the library * * @see base_t * @see table_t * @see column_t * @see row_t * @see field_t */ SqlGuiDoc(QWidget *parent, const char *name=0); /** * Destructor. */ ~SqlGuiDoc(); /** * * Opens a connection to the specified host "url" as user "uname" with password "pwd". * If the database requires a database-name to open a connection to, then the * database-name "base" must also be given. * * This method retrieves a list of all databases (if no database is given), their tables, columnes and column-types. * With this information it then constructs the internal representation of the database-server. * * If the datanbase-name is given, this method should retrieve exactly one database (the given one), its tables, columnes and column-types only. * When connecting to a MySQL-server no database-name must be given. This is because the MySQL-API offers a function to retrieve a list of all * databases without connecting to a specific database. Many other APIs don't offer this kind of function. * * It also sets the member "DB", so that it points to the first element of the internal database-representation. * * A typical implementation could be (here: pseudo-code; replace with the specific database-functions of your favourite database-server): * *
   *  connect_to_database( host, user, password );   // replace with specific db-code for "connect_to_database"
   *
   *  DB = NULL;
   *  base_t * old = NULL;
   *
   *  if ( connected ) {                             // replace with specific db-code for "connected"
   *
   *      while ( d = getDatabaseList() ) {          // replace with specific db-code for "getDatabaseList"
   *
   *          base_t * b = new base_t;
   *          b->name = d->name();                   // replace with specific db-code "d->name"
   *          b->table_list = getTables( d );        // replace with specific db-code "getTables"
   *          b->next = NULL;
   *
   *          if (old) {
   *              old->next = b;
   *              old = b;
   *          } else {
   *              DB = b;
   *              old = DB;
   *          }
   *      }
   *  }
   *
   * 
* * Of course you have to use the functions offered by your database-server. This example is just written here, to give you an idea of how to start * building the internal database-representation. Also a database may not offer the ability to get a list of its databases. Instead you must * already know the database-name, to which you would like to connect to. * * In some cases, it may be difficult to get previous example working. The easiest way to get the constuction of the DB-object working, * is to split up the information-retrieval into separte parts: * *
   * 1) get all database-names and store them in the DB-object
   * 2) for every database in DB get the tables and store them in DB
   * 3) for every database and for every table get the column-names and store them in DB
   * 
* *
   *  connect_to_database( host, user, password );   // replace with specific db-code for "connect_to_database"
   *
   *  DB = NULL;
   *  base_t * old = NULL;
   *
   *  if ( connected ) {                             // replace with specific db-code for "connected"
   *
   *      while ( d = getDatabaseList() ) {          // replace with specific db-code for "getDatabaseList"
   *
   *          base_t * b = new base_t;
   *          b->name = d->name();                   // replace with specific db-code "d->name"
   *          b->next = NULL;
   *
   *          if (old) {
   *              old->next = b;
   *              old = b;
   *          } else {
   *              DB = b;
   *              old = DB;
   *          }
   *      }
   *
   *      base_t * db = DB;
   *      while( db ){
   *          db->table_list = getTables( db );      // replace with specific db-code for "getTables"
   *          db = db->next;
   *      }
   *
   *      db = DB;
   *      while( db ){
   *          table_t * tb = db->table_list;
   *          while( tb ){
   *               tb->column_list = getColumnes( db, tb );      // replace with specific db-code for "getColumnes"
   *               tb = tb->next;
   *          }
   *          db = db->next;
   *      }
   *  }
   *
   * 
* * This may take a little bit longer to get all the information, but may also save you a lot of debugging-time and headaches. * * You might want to take a look at "sqlguidoc_mysql.cpp" or "sqlguidoc_pgsql.cpp". * * This member-function must be reimplemented. * * @param url host to connect to (maybe with :port) * @param uname username for login * @param pwd password for login * @param base the base to connect to (must be given on some database-systems, may be ignored if not needed [e.g.: mysql]) * @see SqlGuiDocMysql * */ virtual bool openDocument(const QString& url, const QString& uname, const QString& pwd, const QString& base); /** * returns the member DB, the pointer to the first element of the internal database-reprentation * (no need for reimplementation). * * @see base_t */ base_t * getDBs(); /** * returns a pointer to the first row of the internal representation of a result from a query * (no need for reimplementation). * * @see base_t */ row_t * getFirstRes(); /** * returns a pointer to the next row of the internal representation of a result from a query * (no need for reimplementation). * * @see base_t */ row_t * getNextRes(); /** * returns the name of the database, which was affected by the last query * (no need for reimplementation). */ QString* resultDB(); /** Deprecated. * returns the name of the tablee, which was affected by the last query * (no need for reimplementation). */ QString* resultTable(); /** * returns a pointer to the columns, which were affected by the last query * (no need for reimplementation). * * @see base_t */ column_t* resultCols(); /** * tells sqlgui, that a new connection will be opened. returns always true. * there's no real need for this function, so it may be removed in the future. */ bool newDocument(); /** * returns the url of the currently connected host * (no need for reimplementation). */ const KURL& URL() const; /** * sets the url of the currently connected host * (no need for reimplementation). * * @param url The url of the connected host */ void setURL(const KURL& url); /** * returns the name of the table, which was affected by the last query * (no need for reimplementation). */ QString * getLastTable(); /** * returns the column-name of the primary key, which was found in the last query. * if there is more than one key, only the first key will be returned. (ToDo: handle multiple keys) * (no need for reimplementation). */ QString * getPrimaryKey(); /** * returns the hostname of the of the currently connected database-server * (no need for reimplementation). */ QString getHost(); /** * returns the username, which was given in the current connection * (no need for reimplementation). */ QString getUser(); /** * returns the password, which was given in the current connection * (no need for reimplementation). */ QString getPass(); /** * returns the name of the of the currently connected database * (no need for reimplementation). */ QString getBase(); /** * returns the portnumber, which was given in the current connection * (no need for reimplementation). */ unsigned short int getPort(); /** * moves the pointer in the internal database-representation to the next base * (no need for reimplementation). */ bool gotoNextBase(); /** * moves the pointer in the internal database-representation to the next table * (no need for reimplementation). */ bool gotoNextTable(); /** * moves the pointer in the internal database-representation to the next column * (no need for reimplementation). */ bool gotoNextColumn(); /** * moves the pointer in the internal representation of a database-result to the next row * (no need for reimplementation). */ bool gotoNextRow(); /** * moves the pointer in the internal representation of a database-result the next field * (no need for reimplementation). */ bool gotoNextField(); /** * returns the base, to which the pointer in the internal representation now points * (no need for reimplementation). */ base_t* getActualBase(); /** * returns the table, to which the pointer in the internal representation now points * (no need for reimplementation). */ table_t* getActualTable(); /** * returns the column, to which the pointer in the internal representation now points * (no need for reimplementation). */ column_t* getActualColumn(); /** * returns the row, to which the pointer in the internal representation now points * (no need for reimplementation). */ row_t* getActualRow(); /** * returns the field, to which the pointer in the internal representation now points * (no need for reimplementation). */ field_t* getActualField(); /** * returns the name of the base, to which the pointer in the internal representation now points * (no need for reimplementation). */ QString getActualBaseName(); /** * returns the name of the table, to which the pointer in the internal representation now points * (no need for reimplementation). */ QString getActualTableName(); /** * returns the type of the table, to which the pointer in the internal representation now points * (no need for reimplementation). */ QString getActualTableType(); /** * returns the name of the column, to which the pointer in the internal representation now points * (no need for reimplementation). */ QString getActualColumnName(); /** * sets the view-widget for this database-representation * (no need for reimplementation). * * @param v The view of this database-representation */ void setView( SqlGuiView* v ); /** * returns true, when connected, false otherwise. * * purely virtual, must be reimplemented. * */ virtual bool isConnected(); /** * returns the protocol-name (i.e. mysql, pgsql, ...) */ virtual QString getProtocol(); public slots: /** * calls openDocument with the given arguments. * * @param h hostname | hostname:port * @param u user * @param p passort */ void slotDoLogin( QString url, QString uname, QString pwd, QString base); /** * closes the current connection and calls openDocument with the results from getHost, getUser and getPass. */ void slotReConnect(); /** * sends the query Anfrage to the base Base to the currently connected host. * Then reads the result from that query and updates the internal representation of the databses-server. * * Emits QueryDone() on success, resultChanged() when the result changed, DbQueryError( QString* errormsg ) on failure, * lastActionChanged( lastDB, lastTable, primKey ) to tell the part, to which table the last query was sent. * * If the query doesn't fail, then this method has to do the following: * *
   * 1) Check if the query returned a result. If not, emit QueryDone().
   *
   * 2) If there is a result, this method has to:
   *    - set lastDB (QString*, name of the database, which was affected)
   *    - set lastTable (QString*, name of the table, which was affected)
   *    - set lastCols (column_t*, list of the columnes with the column-names and -types)
   *    - set primKey (QString*, name of the first column, which is a primary key)
   *    - set RESULT (row_t*, list of the rows in the resultset)
   *    - set RESULT_Start (row_t*, pointer to the first element of the resultset, i.e. to RESULT)
   *    - emit resultChanged() when the result changes
   *    - emit lastActionChanged( lastDB, lastTable, primKey )
   *    - emit QueryDone() when finished successfully
   *
   *
   * 
* * The resultlist must be represented as a row-type row_t. It uses the same mechanism as the database_list, table_list and column_list: * *
   *  row1 -> row2 -> row3 -> ... -> NULL
   *    |
   *    field1 -> field2 -> field3 -> ... -> NULL
   *       |
   *       value (i.e. string-representation of the field-value)
   *
   * 
* * Thr row-list has the following definition: * *
   *  typedef
   *  struct field{
   *      int length;                 // (reserved).
   *      char * value;               // String-representation of the field-value.
   *      struct field * next;        // pointer to the next field in this row. last pointer in list must be a NULL-pointer.
   *  } field_t;
   *
   *  typedef
   *  struct row{
   *      field_t * feld;             // pointer to the first field in this row. Must not be NULL!
   *      struct row * next;          // pointer to the next row in the resultset. last pointer in result-set must be a NULL-pointer.
   *  } row_t;
   *
   * 
* * This method is purely virtual, must be reimplemented. * * @see SqlGuiDocMysql * @see SqlGuiDocMysql::slotDoQuery * * @param Base database * @param Anfrage sql-query */ virtual void slotDoQuery(QString * Base, QString* Anfrage); /** * Creates a new database. Emits NewDbCreated() on success, DbQueryError() on failure. This may be done by calling slotDoQuery (see below). * * purely virtual, must be reimplemented. * *
   *  SqlGuiDocYOURDB::slotDbCreate( QString* db ){
   *      QString * sql = new QString( "CREATE DATABASE ");
   *      sql->append( db );
   *      slotDoQuery( db, sql );
   *      emit( NewDbCreated() );    // emitted everytime, not very clean, but should work
   *  }
   * 
* * @param db databasename * */ virtual void slotDbCreate( QString* db); /** * Deletes the database db. Emits DbErased() on success, DbQueryError() on failure. This may be done by calling slotDoQuery. * * purely virtual, must be reimplemented * * @param db databasename */ virtual void slotDbDelete( QString* db ); /** * deletes the table tb in the database db. Emits TableErased() on success, DbQueryError() on failure. This may be done by calling slotDoQuery. * * purely virtual, must be reimplemented. * * @param db databasename * @param tb tablename */ virtual void slotTableDelete(QString* db, QString* tb); /** * checks the table tb in the database db. May also do nothing, if the database doesn't support checking tables. * Currently there is no signal emitted on success. This behaviour may change in the future. * * purely virtual, must be reimplemented. * * @param db databasename * @param tb tablename */ virtual void slotTableCheck(QString* db, QString* tb); /** * Optimizes the table tb in the database db. May also do nothing, if the database doesn't support optimizing tables. * Currently there is no signal emitted on success. This behaviour may change in the future. * * purely virtual, must be reimplemented. * * @param db databasename * @param tb tablename */ virtual void slotTableOptimize(QString* db, QString* tb); /** * repairs the table tb in the database db. May also do nothing, if the database doesn't support repairing tables. * Currently there is no signal emitted on success. This behaviour may change in the future. * * purely virtual, must be reimplemented. * * @param db databasename * @param tb tablename */ virtual void slotTableRepair(QString* db, QString* tb); /** * Calls clearResult. * */ void slotClearMemory(); /** * Gets some information from the server and represents them in a QString msg. Emits serverStatus( QString msg ). * The msg will be shown in a QMessagebox. * * purely virtual, must be reimplemented. * */ virtual void slotServerStatus(); /** * counts the rows in the table _tb in the databse _db. May be done by calling slotDoQuery(). * Currently there is no signal emitted on success. This behaviour may change in the future. * * purely virtual, must be reimplemented. * * @param db databasename * @param tb tablename */ virtual void slotCountRows( QString* _db, QString* _tb); signals: virtual void connectionChanged(); virtual void loginComplete(); virtual void loginError(); virtual void resultChanged(); virtual void tableChecked(); virtual void tableOptimized(); virtual void tableRepaired(); virtual void NewDbCreated(); virtual void NewTableCreated(); virtual void DbErased(); virtual void TableErased(); virtual void DbQueryError( QString* errmsg ); virtual void QueryDone(); virtual void queryEmpty(); virtual void lastActionChanged( QString* db, QString* tab, QString* prim); virtual void serverStatus( QString status ); public: /** * The hostname, to which we connect. */ QString doc_host; /** * The portnumber, on which the database-server is listening. */ unsigned short int doc_port; /** * The username, which we use for the login. */ QString doc_uname; /** * The password, which we use for the login. */ QString doc_pass; /** * The base, to which we are connected. */ QString doc_base; base_t * DB; QString *QUERY; QString *STATUS; QString *lastDB; QString *lastTable; QString *primKey; int stat; // MySQL-Error-Code int field_pos; // Aktuelle Position in der altuellen Zeile int row_pos; // Aktuelle Zeilen-Position row_t* RESULT_Start; // Pointer auf das erste Zeilen-Element der letzten SQL-Anfrage row_t* RESULT; // Pointer auf das aktuelle Zeilen-Element der letzten SQL-Anfrage protected slots: void clearResult(); protected: /** * Extracts the database-name from the sql-statement sql. Still experimental, only tested for statements on MySQL. */ QString getDbFromSQL(QString * sql); /** * Extracts the table-name from the sql-statement sql. Still experimental, only tested for statements on MySQL. * Currently works only, if exaclty one table is given in the statement. */ QString getTableFromSQL(QString * sql); /** * A pointer to a list of columns. This list contains the column-names and column-types of the last result. */ column_t * lastCols; // Pointer auf eine List mit den Spalten-Namen der letzten SQL-Query QWidget *myParentWidget; KLocale* kl; /** * An URL representing all data (i.e. database-type, host-, user- and basename) of the currently connected database-server. * * Valid URLs have the following structure: type://username\@hostname[/basename] * Valid database-types (i.e. valid protocols) are: ibmdb2, mysql, oracle, pgsql, sapdb. These names might change in the near future (to be compatible with jdbc). * * Examples: * mysql://nobody@localhost * sapdb://DBA@mysqerver.org/TEST * */ KURL doc_url; /** */ base_t* cleardb( base_t ** db ); /** */ table_t* cleartb( table_t ** tb ); /** */ column_t* clearsp( column_t ** sp ); /** */ row_t* clearrw( row_t ** rw ); /** */ field_t* clearfd( field_t ** fd ); /** */ base_t* basePosition; /** */ table_t* tablePosition; /** */ column_t* columnPosition; /** */ row_t* rowPosition; /** */ field_t* fieldPosition; /** */ SqlGuiView* view; /** */ bool connectionEnabled; }; typedef SqlGuiDoc* create_t(QWidget*); typedef void destroy_t(SqlGuiDoc*); #endif // SQLGUIDOC_H

Generated by: marcus on voyager on Mon Sep 16 15:31:33 2002, using kdoc 2.0a53.