|
|
SqlGuiDoc (QWidget *parent, const char *name=0)
| SqlGuiDoc |
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; |
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 also: db_components.h, base_t, table_t, column_t, row_t, field_t
~SqlGuiDoc ()
| ~SqlGuiDoc |
Destructor.
bool openDocument (const QString& url, const QString& uname, const QString& pwd, const QString& base)
| openDocument |
[virtual]
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.
Parameters:
url | host to connect to (maybe with :port) |
uname | username for login |
pwd | password for login |
base | the base to connect to (must be given on some database-systems, may be ignored if not needed [e.g.: mysql]) |
See also: SqlGuiDocMysql
base_t * getDBs ()
| getDBs |
returns the member DB, the pointer to the first element of the internal database-reprentation (no need for reimplementation).
See also: base_t
row_t * getFirstRes ()
| getFirstRes |
returns a pointer to the first row of the internal representation of a result from a query (no need for reimplementation).
See also: base_t
row_t * getNextRes ()
| getNextRes |
returns a pointer to the next row of the internal representation of a result from a query (no need for reimplementation).
See also: base_t
QString* resultDB ()
| resultDB |
returns the name of the database, which was affected by the last query (no need for reimplementation).
QString* resultTable ()
| resultTable |
Deprecated. returns the name of the tablee, which was affected by the last query (no need for reimplementation).
column_t* resultCols ()
| resultCols |
returns a pointer to the columns, which were affected by the last query (no need for reimplementation).
See also: base_t
bool newDocument ()
| newDocument |
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.
const KURL& URL ()
| URL |
[const]
returns the url of the currently connected host (no need for reimplementation).
void setURL (const KURL& url)
| setURL |
sets the url of the currently connected host (no need for reimplementation).
Parameters:
url | The url of the connected host |
QString * getLastTable ()
| getLastTable |
returns the name of the table, which was affected by the last query (no need for reimplementation).
QString * getPrimaryKey ()
| getPrimaryKey |
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 getHost ()
| getHost |
returns the hostname of the of the currently connected database-server (no need for reimplementation).
QString getUser ()
| getUser |
returns the username, which was given in the current connection (no need for reimplementation).
QString getPass ()
| getPass |
returns the password, which was given in the current connection (no need for reimplementation).
QString getBase ()
| getBase |
returns the name of the of the currently connected database (no need for reimplementation).
unsigned short int getPort ()
| getPort |
returns the portnumber, which was given in the current connection (no need for reimplementation).
bool gotoNextBase ()
| gotoNextBase |
moves the pointer in the internal database-representation to the next base (no need for reimplementation).
bool gotoNextTable ()
| gotoNextTable |
moves the pointer in the internal database-representation to the next table (no need for reimplementation).
bool gotoNextColumn ()
| gotoNextColumn |
moves the pointer in the internal database-representation to the next column (no need for reimplementation).
bool gotoNextRow ()
| gotoNextRow |
moves the pointer in the internal representation of a database-result to the next row (no need for reimplementation).
bool gotoNextField ()
| gotoNextField |
moves the pointer in the internal representation of a database-result the next field (no need for reimplementation).
base_t* getActualBase ()
| getActualBase |
returns the base, to which the pointer in the internal representation now points (no need for reimplementation).
table_t* getActualTable ()
| getActualTable |
returns the table, to which the pointer in the internal representation now points (no need for reimplementation).
column_t* getActualColumn ()
| getActualColumn |
returns the column, to which the pointer in the internal representation now points (no need for reimplementation).
row_t* getActualRow ()
| getActualRow |
returns the row, to which the pointer in the internal representation now points (no need for reimplementation).
field_t* getActualField ()
| getActualField |
returns the field, to which the pointer in the internal representation now points (no need for reimplementation).
QString getActualBaseName ()
| getActualBaseName |
returns the name of the base, to which the pointer in the internal representation now points (no need for reimplementation).
QString getActualTableName ()
| getActualTableName |
returns the name of the table, to which the pointer in the internal representation now points (no need for reimplementation).
QString getActualTableType ()
| getActualTableType |
returns the type of the table, to which the pointer in the internal representation now points (no need for reimplementation).
QString getActualColumnName ()
| getActualColumnName |
returns the name of the column, to which the pointer in the internal representation now points (no need for reimplementation).
void setView ( SqlGuiView* v )
| setView |
sets the view-widget for this database-representation (no need for reimplementation).
Parameters:
v | The view of this database-representation |
bool isConnected ()
| isConnected |
[virtual]
returns true, when connected, false otherwise.
purely virtual, must be reimplemented.
QString getProtocol ()
| getProtocol |
[virtual]
returns the protocol-name (i.e. mysql, pgsql, ...)
void slotDoLogin ( QString url, QString uname, QString pwd, QString base)
| slotDoLogin |
[slot]
calls openDocument with the given arguments.
Parameters:
h | hostname | hostname:port |
u | user |
p | passort |
void slotReConnect ()
| slotReConnect |
[slot]
closes the current connection and calls openDocument with the results from getHost, getUser and getPass.
void slotDoQuery (QString * Base, QString* Anfrage)
| slotDoQuery |
[virtual slot]
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.
Parameters:
Base | database |
Anfrage | sql-query |
See also: SqlGuiDocMysql, SqlGuiDocMysql::slotDoQuery
void slotDbCreate ( QString* db)
| slotDbCreate |
[virtual slot]
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 } |
Parameters:
db | databasename |
void slotDbDelete ( QString* db )
| slotDbDelete |
[virtual slot]
Deletes the database db. Emits DbErased() on success, DbQueryError() on failure. This may be done by calling slotDoQuery.
purely virtual, must be reimplemented
Parameters:
db | databasename |
void slotTableDelete (QString* db, QString* tb)
| slotTableDelete |
[virtual slot]
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.
Parameters:
db | databasename |
tb | tablename |
void slotTableCheck (QString* db, QString* tb)
| slotTableCheck |
[virtual slot]
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.
Parameters:
db | databasename |
tb | tablename |
void slotTableOptimize (QString* db, QString* tb)
| slotTableOptimize |
[virtual slot]
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.
Parameters:
db | databasename |
tb | tablename |
void slotTableRepair (QString* db, QString* tb)
| slotTableRepair |
[virtual slot]
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.
Parameters:
db | databasename |
tb | tablename |
void slotClearMemory ()
| slotClearMemory |
[slot]
Calls clearResult.
void slotServerStatus ()
| slotServerStatus |
[virtual slot]
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.
void slotCountRows ( QString* _db, QString* _tb)
| slotCountRows |
[virtual slot]
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.
Parameters:
db | databasename |
tb | tablename |
void connectionChanged ()
| connectionChanged |
[virtual signal]
void loginComplete ()
| loginComplete |
[virtual signal]
void loginError ()
| loginError |
[virtual signal]
void resultChanged ()
| resultChanged |
[virtual signal]
void tableChecked ()
| tableChecked |
[virtual signal]
void tableOptimized ()
| tableOptimized |
[virtual signal]
void tableRepaired ()
| tableRepaired |
[virtual signal]
void NewDbCreated ()
| NewDbCreated |
[virtual signal]
void NewTableCreated ()
| NewTableCreated |
[virtual signal]
void DbErased ()
| DbErased |
[virtual signal]
void TableErased ()
| TableErased |
[virtual signal]
void DbQueryError ( QString* errmsg )
| DbQueryError |
[virtual signal]
void QueryDone ()
| QueryDone |
[virtual signal]
void queryEmpty ()
| queryEmpty |
[virtual signal]
void lastActionChanged ( QString* db, QString* tab, QString* prim)
| lastActionChanged |
[virtual signal]
void serverStatus ( QString status )
| serverStatus |
[virtual signal]
QString doc_host | doc_host |
unsigned short int doc_port | doc_port |
QString doc_uname | doc_uname |
QString doc_pass | doc_pass |
QString doc_base | doc_base |
base_t * DB | DB |
QString * QUERY | QUERY |
QString * STATUS | STATUS |
QString * lastDB | lastDB |
QString * lastTable | lastTable |
QString * primKey | primKey |
int stat | stat |
int field_pos | field_pos |
int row_pos | row_pos |
row_t* RESULT_Start | RESULT_Start |
row_t* RESULT | RESULT |
void clearResult ()
| clearResult |
[protected slots slot]
The base, to which we are connected.
QString getDbFromSQL (QString * sql)
| getDbFromSQL |
[protected]
Extracts the database-name from the sql-statement sql. Still experimental, only tested for statements on MySQL.
QString getTableFromSQL (QString * sql)
| getTableFromSQL |
[protected]
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.
column_t * lastCols | lastCols |
[protected]
QWidget * myParentWidget | myParentWidget |
[protected]
KLocale* kl | kl |
[protected]
KURL doc_url | doc_url |
[protected]
base_t* cleardb ( base_t ** db )
| cleardb |
[protected]
table_t* cleartb ( table_t ** tb )
| cleartb |
[protected]
column_t* clearsp ( column_t ** sp )
| clearsp |
[protected]
row_t* clearrw ( row_t ** rw )
| clearrw |
[protected]
field_t* clearfd ( field_t ** fd )
| clearfd |
[protected]
base_t* basePosition | basePosition |
[protected]
table_t* tablePosition | tablePosition |
[protected]
column_t* columnPosition | columnPosition |
[protected]
row_t* rowPosition | rowPosition |
[protected]
field_t* fieldPosition | fieldPosition |
[protected]
SqlGuiView* view | view |
[protected]
bool connectionEnabled | connectionEnabled |
[protected]
Generated by: marcus on voyager on Mon Sep 16 15:31:33 2002, using kdoc 2.0a53. |