# Source: hk_classes/hk_classes/hk_datasource.h

Annotated List
Files
Globals
Hierarchy
Index

    // ****************************************************************************
    // copyright (c) 2000-2004 Horst Knorr <hk_classes@knoda.org>
    // This file is part of the hk_classes library.
    // This file may be distributed and/or modified under the terms of the
    // GNU Library Public License version 2 as published by the Free Software
    // Foundation and appearing in the file COPYING included in the
    // packaging of this file.
    // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    // ****************************************************************************
    #ifndef HK_DATASOURCE
    #define HK_DATASOURCE
    //#include <hk_definitions.h>
    #include "hk_data.h"
    #include <list>
    #include <algorithm>
    #include "hk_column.h"
    using namespace std;

    class hk_database;
    class hk_dsvisible;
    class hk_presentation;
    class hk_actionquery;
    class hk_datasourceprivate;
    /**
     *
     *@short  represents a resultquery or a table of a database.
     *@version $Revision: 1.64 $
     *@author Horst Knorr (hk_classes@knoda.org)

     *hk_datasource is the basic class which represents a resultquery or a table of a database.
     * Never create this table directly. Use the @ref hk_database::new_table method instead.
     *
     * Two types of this class can be distinguished. Tables and Resultqueries.
     *
     *Resultqueries are Queries with
     * a SELECT - SQL-statement. The resulting data cannot be edited or manipulated.
     *
     *Tables are a special form of resultqueries. The SQL-statement is fixed ("SELECT * FROM <tablename>),
     * but the resulting dataset can be edited.
     */

    class hk_datasource:public hk_data
    {
        friend class hk_column;
        friend class hk_dsvisible;
        friend class hk_database;
        friend class hk_presentation;
        public:
            virtual     ~hk_datasource();
    /**
     *sets the name of the datasource
     *@param n the name
     *@param registerchange if this class is part of a hk_presentation object (i.e. a form or a report) and registerchange
     *is true, then the changes will be stored when the hk_presentation object is closed.
     */
            virtual void    set_name(const hk_string& n,bool registerchange=true);
            virtual hk_string name(void);
            enum enum_tablemodes {mode_normal,mode_createtable,mode_altertable,mode_disabled,mode_insertrow,mode_deleterow,mode_unknown};
    /**
     *if this datasource is a table, it can be in different "modes".
     *For example if you want to create a new table and define
     *the different columns, the table has to be in "mode_create"
     *See @ref enum_tablemodes for the different modetypes.
     */
            enum_tablemodes mode(void);
    /**
     *brings the datasource in insertmode. To add a new row call this function, set the data of the new row
     *as usual in the columns (i.e.with @ref hk_column::ashk_string ) and finally call
     *either @ref setmode_normal or @ref store_changed_data.
     */
            void    setmode_insertrow(void);
    /**
     *this function tries to delete the actual row. If there is a depending datasource with equivalent rows
     *the actual row will not be deleted.
     */
            void    delete_actualrow(void);
    /**
     *This is the usual mode, where you can browse the data and if the data is not readonly change the data.
     */
            void    setmode_normal(void);

    /**
     *If you want to create a new table first  bring the table in createmode. Define new columns with
     *@ref  new_column. Afterwards you can create the table by calling @ref create_table_now
     */
            void    setmode_createtable(void);

    /**
     *If you want to alter an existing table first  bring the table in altermode. Define new columns with
     *@ref  new_column. Alter it with @ref alter_column and delete a column by calling @ref alter_column.
     * Afterwards you can alter the table by calling @ref alter_table_now
     */
            void setmode_altertable(void);

    /**
     *if this datasource is of type "table" and in mode "create" or "alter" you can
     *create a new column to define its parameters.
     */
            hk_column* new_column(void);

    /**
     *if this datasource is of type "table" and in mode "alter" you can
     *alter an existing column. NULL values mean, that this part will not be changed
     */

            bool alter_column(const hk_string& col, const hk_string* name=NULL,hk_column::enum_columntype* newtype=NULL,long* size=NULL,const hk_string* defaultvalue=NULL,const bool* primary=NULL,const bool* notnull=NULL);
    /**
     *if this datasource is of type "table" and in mode "alter" you can
     *delete an existing column.Just enter the name here.
     */
            bool delete_column(const hk_string& col);
    /**
     * After defining a new table with setmode_createtable and new_column this function
     *creates physically the table
     */
            bool create_table_now(void);
    /**
     * After altering an existing table with setmode_altertable, new_column
     *,alter_column and delete_column this function
     *alters physically the table
     */
            bool alter_table_now(void);

    /**
     *Goto a specific row. The first row number is 0, the last n-1 where n
     *is the number of rows as delivered from @ref max_rows().All depending objects
     *will be informed (visible objects, depending datasources etc)
     * @param r is the wished new row number to go.
     * @return true if success, else false.
     */
            virtual bool    goto_row(unsigned long r);
    /**
     *move the row selector to the first row. All depending objects
     *will be informed (visible objects, depending datasources etc)
     * @return true if success, else false.
     */
            bool    goto_first(void);
    /**
     *move the row selector to the last row. All depending objects
     *will be informed (visible objects, depending datasources etc)
     * @return true if success, else false.
     */
            bool    goto_last(void);
    /**
     *move the row selector to the next row. All depending objects
     *will be informed (visible objects, depending datasources etc)
     * @return true if success, else false.
     */
            bool    goto_next(void);
    /**
     *move the row selector to the previous row.  All depending objects
     *will be informed (visible objects, depending datasources etc)
     * @return true if success, else false.
     */
            bool    goto_previous(void);
    /**
     *moves the rowselector to a random row.
     */
            bool    goto_random(void);
    /**
     *number of the current row.
     */
            unsigned long row_position(void);
    /**
     *number of rows in this query.
     */
            unsigned long max_rows(void);
    /**
     * the accessmode regulates the behaviour of the datasource.
     * In mode 'standard' the datasource is readable and writeable, but usually first loads all the data from the
     * SQL server. This is in some cases not necessary. If you just need to serially read one row after another, you
     * can use the 'batchread' mode. In this case random access is not possible and it is not possible to edit the data
     * or insert rows (e.g. this is used in @ref hk_report). In 'batchwrite' mode data can't be read and is only used
     * for inserting data (e.g. used @ref hk_importcsv)
     *The batchmodes do not need as much memory as the standard mode.
     */
            enum enum_accessmode {standard,batchread,batchwrite};
            bool set_accessmode(enum_accessmode);
            enum_accessmode accessmode(void) const;

    /**
     *if hk_connection is connected, this method will enable the datasource. The SQL-Statement in @ref SQL
     *will be executed. If the SQL-statement is ok, the resulting data can be reached via the columns in @ref columns. You can browse
     *the data by using the methods @ref goto_row, @ref goto_first,
     *@ref goto_last, @ref goto_next and @ref goto_previous.
     *@return true if enable was successful.
     */
            bool    enable(void);
    /**
     *if the datasource is enabled, this function will disable it. The columnlist will be deleted.
     */
            bool    disable(void);
    /**
     *convenience function: if e is true the datasource will be enabled by calling @ref enable
     *else it will disable the datasource by calling @ref disable.
     */

            bool    set_enabled(bool e);
    /**
     *shows whether the datasource is enabled.
     */
            bool    is_enabled(void);
    /**
     * @return true if data in this datasource can be changed.
     * Always false if this datasource is a dml_query.
     */
            bool    is_readonly(void);
    /**
     *  If the datasource is of type ds_table you can allow or disallow data changes.
     */
            void    set_readonly(bool r);
    /**
     *if the datasource is enabled you get a list of all columns.
     *The fields can be reached by columns. See @ref hk_column for details.

     */
            list<hk_column*>* columns(void);
    /**
     *if the datasource is enabled, you can reach a particular column by name
     *@return @ref hk_column if there is a column with this name else NULL.
     */
            hk_column* column_by_name(const hk_string& c);
    /**
     *if the datasource is enabled, you can reach a particular column by name.
     * @param colnumber If there are more than 1 columns with the same name this parameter tells which one to
     *take (1 is the first column)
     *
     *@return @ref hk_column if there is a column with this name else NULL.
     */

            hk_column* column_by_name(const hk_string& c, int colnumber);
    /**
     *returns how many columns exist in this datasource with the name 'colname'.
     * Usually columnnames should be unique, but it is unfortunately technically possible to create
     * SQL statements that return ambigous columnnames
     */
            int columnname_occurances(const hk_string& colname);
    /**
     * returns if this is the first, second ... nth column with this name
     */
            int columnname_occurance(hk_column*);

    /**
     * set your own SQL statement, that will be executed when you enable the datasource.
     * if this datasource is of type "table" it will be automatically created.
     *@param  s is the sql statement
     *@param rawsql if true the sql statement will used as is (otherwise it may be changed to fit
     *@param registerchange if this class is part of a hk_presentation object (i.e. a form or a report) and registerchange
     *is true, then the changes will be stored when the hk_presentation object is closed.
     *sorting, filtering or depending on statements). So it is possible to execute driver specific
     *result queries which do not contain the "SELECT" statement, i.e. SHOW FIELDS in Mysql.
     */
            bool    set_sql(const hk_string& s,bool rawsql=false,bool registerchange=true);
            hk_string   sql(void);
            bool    is_rawsql(void);
            typedef class
            {
                public:
                    hk_string  name;
                    bool    unique;
                    list<hk_string> fields;
            } indexclass;
    /**
     * returns the list of all existing indices of a table or NULL in case of an error (i.e. not a table)
     */
            list<indexclass>* indices(void);
    /**
     * deletes an index of a table. returns true if successful otherwise false;
     *@param i name of the index
     */
            bool    drop_index(const hk_string& i);
    /**
     * creates an index of a table. returns true if successful otherwise false;
     * make sure you have set the tablename first.
     *@param name new name of the index
     *@param unique true if this should be a unique index
     *@param fields the field(column) names used by this index
     *@return true if successful otherwise false;
     */
            bool    create_index(const hk_string& name,bool unique, list<hk_string>& fields);
    /**
     * Alters an existing index by first dropping it with @ref drop_index and then by trying to recreate it
     * with @ref create_index
     */
            bool    alter_index(const hk_string& name,bool unique,list<hk_string>& fields);
    /**
     *See @ref dependingmode for details
     */
            enum enum_dependingmodes {depending_nohandle,depending_standard,depending_change,depending_delete,depending_changedelete};
    /**

    *   depending_nohandle     = ignore that this is a depending datasource
    *   depending_standard     = can't delete a master row when there are
    *                            depending rows in the depending datasource
    *                            and can't change the value of a master connection field.
    *   depending_change       = if a master connection field is changed, the
    *                            equivalent depending fields will change their values too.
    *   depending_delete       = if the master row is deleted the depending rows will also be deleted
    *   depending_changedelete = combination of depending_change and depending_delete

    See also @ref set_depending_on for details
    */
            enum_dependingmodes dependingmode(void);
    /**
     *if there are 2 datasources in a 1:n relation it is possible to connect the 2 datasources.
     *Add the master datasource here ( it's the '1'-datasource in the '1:n'-relation).
     *Except of the master datasource you also have to add the connected fields with @ref add_depending_fields
     *This (the depending) datasource will enable/disable automatically
     *when the master datasource will enable/disable.
     *if this datasource is part of a @ref hk_presentation use @ref set_depending_on_presentationdatasource instead
     *@param d is the master datasource
     *@param react_on_data_changes true if the datasource should react when a value of the masterdatasource is changed
     *but not yet stored
     *@param mode  how to react when the masterdatasource changes its data. See @ref enum_dependingmodes for details.
     */
            bool    set_depending_on(hk_datasource* d,bool react_on_data_changes=false,enum_dependingmodes mode=depending_standard);
            hk_datasource* depending_on(void);
    /**
     *See @ref dependingmode for details
     */
            bool depending_on_react_on_data_changes(void);
    /**
     * a list of the depending on columns of this datasource set with @ref add_depending_fields
     */
            list<hk_string>* depending_on_thisfields(void);
    /**
     * a list of the depending on columns of the master datasource set with @ref add_depending_fields
     */
            list<hk_string>* depending_on_masterfields(void);
    /**
     *if this datasource is part of a hk_presentation object (form or report) then set the depending on datasource with
     *this function. You can get the unique datasource number of a datasource with @ref presentationnumber
     *@param d the presentationnumber of the master datasource
     *@param registerchange if this class is part of a hk_presentation object (i.e. a form or a report) and registerchange
     *is true, then the changes will be stored when the hk_presentation object is closed.
     */
            bool   set_depending_on_presentationdatasource(long d,bool react_on_data_changes=false,enum_dependingmodes mode=depending_standard,bool registerchange=true);
            long    depending_on_presentationdatasource(void);
    /**
     * use this method in connection with @ref depending_on.
     *@param this_ds_field fieldname of a column of this datasource which has to be connected to the master datasource.
     *@param master_ds_field columnname of the masterdatasource which value has to be equal with the value of this_ds_field.
     *@param registerchange if this class is part of a hk_presentation object (i.e. a form or a report) and registerchange
     *is true, then the changes will be stored when the hk_presentation object is closed.
     */
            void    add_depending_fields(const hk_string& this_ds_field, const hk_string& master_ds_field,bool registerchange=true);
    /**
     *clears the depending list.
     */
            void    clear_depending_fields(void);
    /**
     * if the data of the actual row has changed you can manually send the changes to the SQL Server
     * by calling this function. The function will be called automatically before the datasource disables
     * or the row selector will be moved to another row.
     */
            bool    store_changed_data(enum_interaction c=interactive);
    	void    set_ignore_changed_data(void);
    	bool   ignore_changed_data(void) const;
    /**
     * it is possible to filter only specific rows from a datasource by setting this filter.
     * just add the conditions with this function.
     *@param f same syntax as a SQL statement in the 'WHERE' section, but without the word 'WHERE'
     *@param registerchange if this class is part of a hk_presentation object (i.e. a form or a report) and registerchange
     *is true, then the changes will be stored when the hk_presentation object is closed.
     *Example: SELECT * from addresses WHERE city="München", so you would call set_filter("city=\"München\"");
     *
     */
            void    set_filter(const hk_string& f,bool registerchange=true);
            hk_string filter(void);
    /**
     *temporary filters just work like filters (see @ref set_filter ), but have to be manually activated with
     *@ref set_use_temporaryfilter. When loaded with @ref loaddata temporaryfilters are deactivated by default.
     */
            void set_temporaryfilter(const hk_string&f);
            hk_string temporaryfilter(void);
            void set_use_temporaryfilter(bool use);
            bool use_temporaryfilter(void);
    /**
     * clears the filter which was set with @ref set_filter
     *@param registerchange if this class is part of a hk_presentation object (i.e. a form or a report) and registerchange
     *is true, then the changes will be stored when the hk_presentation object is closed.
     */
            void    clear_filter(bool registerchange=true);
    /**
     * it is possible to sort the datasource.
     * just add the conditions with this function.
     *@param f same syntax as a SQL statement in the "ORDER BY" section, but without the word "ORDER BY"
     *@param registerchange if this class is part of a hk_presentation object (i.e. a form or a report) and registerchange
     *is true, then the changes will be stored when the hk_presentation object is closed.
     *Example: SELECT * from addresses ORDER BY city DESC , so you would call set_sorting("city DESC");
     */
            void    set_sorting(const hk_string& s,bool registerchange=true);
            hk_string sorting(void);
            void set_temporarysorting(const hk_string& s);
            hk_string temporarysorting(void);
            void set_use_temporarysorting(bool use);
            bool use_temporarysorting(void);

    /**
     *clears the sorting instruction
     *@param registerchange if this class is part of a hk_presentation object (i.e. a form or a report) and registerchange
     *is true, then the changes will be stored when the hk_presentation object is closed.
     */
            void    clear_sorting(bool registerchange=true);
    /**
     *when data has changed and the row selector is moved to another row, usually the datasource will
     *be automatically updated. If the value is set to false, you have to update the data manually by calling
     * @ref store_changed_data.
     *@param u If you don't want the automatic update of data changes, set this paramter to false. The default
     *value is true.
     */
            void    set_automatic_data_update(bool u);
            bool    is_automatic_data_update(void);
            void    set_sqldelimiter(const hk_string&);
    /**
     *sets the default date and timeformats for new created columns
     */
            void    set_datetimeformat(const hk_string& datetime,const hk_string& date,const hk_string& time)
            {
                p_datetimeformat=datetime;
                p_dateformat=date;
                p_timeformat=time;
            }

            hk_database* database(void);
    /**
     *stores the object's values to stream s. The following tags will be used
     *
     *<TYPE> either QUERY or TABLE
     *
     *<DATASOURCENAME>  the name set with @ref set_name
     *
     *<SQL> the used sql statement
     *
     *Additionally the section <DATASOURCEEXTRA> has the following tags
     *
     *<FILTER> the filter set with @ref set_filter
     *
     *<SORTING> the sorting direction set with @ref set_sorting
     *
     *<DATETIMEFORMAT>
     *
     *<DATEFORMAT>
     *
     *<TIMEFORMAT>
     *
     *if this datasource is part of a @ref hk_presentation also the following tags will be stored
     *
     *<UPN>   the unique presentation number. See @ref presentationnumber
     *
     *<DEPENDING_ON>  the depending on datasource set with @ref set_depending_on_presentationdatasource
     *
     *one or more <DEPENDINGFIELDS> sections with the following tags
     *
     *<THISFIELD>   set with @ref add_depending_fields
     *
     *<MASTERFIELD> set with @ref add_depending_fields
     *
     *@param s the stream to which the data will be written
     *@param saveall if true the section <DATASOURCEEXTRA> will be stored additionally to the normal data
     */
            void  savedata(ostream& s,bool saveall=true);
    /**
     *loads the object's values out of the definition string.
     */
            void  loaddata(const hk_string& definition,bool loadsql=true);
    /**
     *  stores the datasource as a query file
     *@return true if successful else false
     */
    //      bool 	savequerytofile(void);
    /**
     *  load the datasource with the values of a query file
     *@return true if successful else false
     */
    //      bool 	loadqueryfromfile(void);
    /**
     * if the datasource is part of a @ref hk_presentation each datasource gets a unique datasource number
     *as an identifier
     *@return  the unique datasource number if part of a presenation else -1
     */
            long  presentationnumber(void) const {return p_dscounter;}
    /**
     * @return true if a hk_visible object or a depending datasource is using this datasource
     *else false
     */
            bool  datasource_used(void) const;
    #ifdef HK_DEBUG
    /**
     *@internal
     * prints all data of this datasource to the standard output
     */
            virtual        void   dump_data() ;
    #endif
    /**
     *asks interactively for a name
     */
            bool ask_name(void);
    /**
     *  Delete rows beginning from row number "from" to row number "to"
     */
            bool delete_rows(unsigned long from,unsigned long to,bool check_depending_datasources=true,bool ask=true);
    /**
     * Start a transaction. If the SQL server does not support transaction this function does nothing
     *@param name the name of the transaction
     */
            void transaction_begin(hk_string name="");
    /**
     * Commits  a transaction. If the SQL server does not support transaction this function does nothing
     *@param name the name of the transaction
     */
            void transaction_commit(hk_string name="");
    /**
     * Undo a transaction. If the SQL server does not support transaction this function does nothing
     *@param name the name of the transaction
     */

            void transaction_rollback(hk_string name="");

    /**
     *if true no visual objects will be informed when data changes in any kind, except the datasource will be deleted
     *Default is false
     */
            void set_blockvisiblesignals(bool v);
            bool blockvisiblesignals(void);
    /**
     *if true no data will be sent to the database server when data changes in any kind
     *Default is false
     */
            void set_blockserversignals(bool);
            bool blockserversignals(void);
    /**
     *if true no depending datasources will be informed when data changes in any kind
     *Default is false
     */
            void set_blockdatasourcesignals(bool);
            bool blockdatasourcesignals(void);
    /**
     *stores the structure of the datasource (fields,indices) in an xml format file and is database driver independent
     */
            void save_datasourcedefinition(ostream& s);
    /**
     *loads the structure of the datasource (fields,indices) in an xml format file and creates the tableand is database driver independent
     */
            bool load_datasourcedefinition(const hk_string& definition,bool use_xmltablename=true ,bool ask=true);
    hk_presentation* presentation(void);
    /**
    *the position will be used for the database designer GUI. Mostly you don't have to manipulate the values
    */
     void set_position(int x,int y, bool registerchange=true);
    /**
    *the size will be used for the database designer GUI. Mostly you don't have to manipulate the values
    */
     void set_size(int width,int height, bool registerchange=true);
     int x(void) const;
     int y(void) const;
     int width(void) const;
     int height(void) const;

        protected:
    /**
     *if database driver supports cassensitive column and table names p_casesensitive is true else p_casesensitive is false.
     *Then internally column_by_name() and name() return values in small letters
     */
            bool p_casesensitive;
            hk_datasource(hk_database* db,hk_presentation* p=NULL);
            void    column_remove(hk_column* col);
            void    visible_add(hk_dsvisible* v);
            void    visible_remove(hk_dsvisible* v);
            virtual void driver_specific_transaction_begin(hk_string);
            virtual void driver_specific_transaction_commit(hk_string);
            virtual void driver_specific_transaction_rollback(hk_string);
            virtual unsigned long driver_specific_max_rows(void){return 0;}
            virtual bool driver_specific_set_accessmode(enum_accessmode){return true;}
            virtual bool driver_specific_batch_enable(void){return false;}
            virtual bool driver_specific_batch_disable(void){return false;}
            virtual bool driver_specific_batch_goto_next(void){return false;}
            virtual bool driver_specific_batch_goto_previous(void){return false;}
    /**
     * has to make sure that the columns-list has been created. It also has to provide access to the data
     * of the datasource
     */
            virtual bool    driver_specific_enable(void){return false;}
            virtual bool    driver_specific_disable(void){return false;}
    /**
     * returns a list of the columns of the datasource. If the datasource is a table the list hast to be created
     * even if the datasource is disabled. Fill the p_columns list for this reason and then return it.
     * If necessary has to create one hk_column object per column and to add them to p_columns. Each column object has to
     * get a unique number in its (protected) hk_column::p_fieldnr .
     */
            virtual list<hk_column*>* driver_specific_columns(void){return NULL;}
            virtual bool    driver_specific_goto_row(unsigned long r);
            virtual hk_column* driver_specific_new_column(void){return NULL;}
            virtual bool    driver_specific_update_data(void){return true;}
            virtual bool    driver_specific_delete_data_at(unsigned long){return true;}
            virtual bool    driver_specific_insert_data(void){return true;}
            virtual bool    driver_specific_create_table_now(void){return false;}
            virtual bool    driver_specific_alter_table_now(void){return false;}
            virtual void    driver_specific_before_drop_table(void){}
            virtual void    filelist_changes(filetype t);
            virtual list<indexclass>* driver_specific_indices(void){return NULL;}
            virtual bool    driver_specific_drop_index(const hk_string& i);
            virtual bool    driver_specific_create_index(const hk_string& name,bool unique,list<hk_string>& fields);
            virtual void before_connection_disconnects(void);
            virtual void before_source_vanishes(void);

            void    depending_ds_add(hk_datasource* d);
            void    depending_ds_remove(hk_datasource* d);
            void    depending_on_datasource_row_change(bool take_changed_data=false);
            void    depending_on_datasource_data_has_changed(void);
            void    depending_on_datasource_after_store_changed_data(void);
            void    depending_on_datasource_insertmode(void);
            bool   depending_on_datasource_deleterow_ok(void);
            bool   depending_on_datasource_before_delete_row(void);
            bool   depending_on_datasource_updaterow_ok(void);
            void   depending_on_datasource_before_update_row(void);
            void   depending_on_datasource_after_update_row(void);
            void    reload_data(bool take_changed_data=false);
            void    create_actual_row_where_statement(void);
            hk_string create_row_where_statement_at(unsigned long int position,bool withwhere=true);
            void    create_new_sql_statement(bool take_changed_data=false);
            hk_string whole_datasource_where_statement(bool take_changed_data=false);
    	void print_sql(void);

    	bool    p_enabled;
            bool    p_readonly;
            bool    p_primary_key_used;
            bool    p_ignore_changed_data;
            void    clear_columnlist(void);
            void    clear_modecolumnlists(void);
            void    clear_visiblelist(void);
            void    parse_sql(void);
            virtual bool    update_row(enum_interaction c=interactive);
            virtual bool    insert_row(enum_interaction c=interactive);
            virtual bool    delete_row(enum_interaction c=interactive);
            unsigned long   p_counter;                // actual row number
            hk_database*    p_database;
            list<hk_column*>*      p_columns;
            typedef class
            {
                public:
                    hk_string name;
                    hk_string newname;
                    hk_column::enum_columntype type;
                    long size;
                    hk_string defaultvalue;
                    bool primary;
                    bool notnull;
            } class_altercolumns;
            list<class_altercolumns>       p_altercolumns;
            list<hk_string>       p_deletecolumns;
            list<hk_column*>       p_newcolumns;
            list<hk_string> depending_this_fields;
            list<hk_string> depending_master_fields;
    /**
     *struct_parsed_sql is needed for parsing th SQL-statement in hk_datasource
     */
            typedef class
            {
                public:
                    hk_string
                        select_part,
                        from_part,
                        where_part,
                        groupby_part,
                        having_part,
                        orderby_part ;
            } struct_parsed_sql;
            struct_parsed_sql* p_parsed_sql;
            hk_string   p_sql;
            hk_string  p_actual_row_where;
            bool    p_automatic_data_update;
            hk_actionquery* p_actionquery;
            hk_string p_datetimeformat;
            hk_string p_dateformat;
            hk_string p_timeformat;
            hk_string   p_sql_delimiter;
            hk_string       p_true;
            hk_string       p_false;

            bool    p_tablesql_set;
            void set_has_changed(void);
            void set_has_not_changed(void);

        private:

            enum_tablemodes p_mode;
            hk_string   p_original_sql;
            unsigned long p_length;
            bool    p_has_changed;
            list<hk_dsvisible*> p_visibles;
            list<hk_datasource*> p_dependinglist;
            hk_datasource*  p_depending_on_datasource;
            bool    p_depending_on_datasource_react_on_changed_data;
            void    inform_before_row_change(void);
            void    inform_visible_objects_before_store_changed_data(void);
            void    inform_visible_objects_after_store_changed_data(void);
            void    inform_visible_objects_row_change(void);
            void    inform_visible_objects_row_add(void);
            void    inform_visible_objects_row_delete(void);
            void    inform_visible_objects_before_insert_row(void);
            void    inform_before_enable(void);
            void    inform_before_disable(void);
            void    inform_visible_objects_ds_disable(void);
            void    inform_visible_objects_ds_enable(void);
            void    inform_depending_ds_goto_row(void);
            void    inform_depending_ds_store_data(void);
            void    inform_depending_ds_data_has_changed(void);
            void    inform_depending_ds_after_store_changed_data(void);
            void    inform_depending_ds_disable(void);
            void    inform_depending_ds_enable(void);
            void    inform_depending_ds_insertmode(void);
            void    inform_visible_objects_new_columns_created(void);
            void    inform_visible_objects_before_columns_deleted(void);
            void    inform_visible_objects_insertmode(void);
            void    reset_changed_data(void);
            void    inform_when_table_structure_changes(void);
            void    inform_when_indexlist_changes(void);
            void    mark_visible_objects_as_not_handled(void);
    	void execute_visible_object_script_before_update(void);
    	void execute_visible_object_script_after_update(void);
    	void execute_visible_object_before_row_change(void);
    	void execute_visible_object_after_row_change(void);
    	void execute_visible_object_before_delete(void);
    	void execute_visible_object_after_delete(void);
    	void execute_visible_object_before_insert(void);
    	void execute_visible_object_after_insert(void);
            hk_presentation* p_presentation;
    // unique number given from a hk_presentation object
            long    p_dscounter;

    	hk_datasourceprivate* p_private;
    }

    ;
    #endif

Generated by: horst on horstnotebook on Tue Mar 30 19:06:43 2004, using kdoc 2.0a54.