This document describes what TOra extractor is and how it works.
Extractor (defined as class toExtract (files toextract.h/cpp)) is an interface to different databases. To execute different operations on different databases you will be calling extractor functions which will check which connection is currently being used (oracle, mysql etc.) and will call corresponding database specific implementation.
Extractor class has some subclasses to provide wrappers for abstract database objects. One of these objects is datatype (class datatype). This class defines one particular datatype and it's properties, f.e. what is maximum length of data, does it has precision etc.
Another part is extractor.
This class will have to be subclassed later in order to actually implement access to some specific database. It defines four major virtual methods:
Note that all four methods above do not actually create, drop or migrate the object, they just return sql statement to do that. It means after calling these procedures you will have to call the statement separately (or you can simply display the statement to the user).
Also note that create function works on existing object. So if you want to create new object (table, index, tablespace etc.) you will have to call migrate method. Migrate function should be able to handle both creation of new objects as well as altering existing objects (say adding a column to a table or changing a property of existing index).
In order for operation to be accessible it has to be registered in extractor by calling function registerExtract. For example after implementing functionality to drop role you would “register” it by calling:
registerExtract("ORACLE", "DROP", "ROLE");
toExtract::extractor class also contains a list of datatypes used in that specific database. This list should be initialised (filled in) in order for all funcionality to work (for example table creation dialog will not be able to display list of values for column types if this list is not filled in).
Before calling extractor you can set a number of properties controlling which parts of database object information will be extracted:
There are also getters for the same properties.
In order to transfer information about different database objects extractor uses it's own database independant format. It consists of a number of QString lines each describing a single property of specific database object.
Each line in it's turn consists of a number of string values separated by character \01
For example if table owner.mytable having columns a number and b varchar2(20) would be described in this format it would look like this:
owner\01TABLE\01mytable owner\01TABLE\01mytable\01COLUMN\01a owner\01TABLE\01mytable\01COLUMN\01a\01ORDER1 owner\01TABLE\01mytable\01COLUMN\01a\01NUMBER owner\01TABLE\01mytable\01COLUMN\01b owner\01TABLE\01mytable\01COLUMN\01b\01ORDER2 owner\01TABLE\01mytable\01COLUMN\01b\01VARCHAR2(20)
As you can see first row indicates that this is description of table “mytable” in schema “owner”. All further details about this object have the same start of the line (the same “context”). Then subproperty of object table is column (in this case “a”). All descriptions of column “a” will have the same begining as initial “declaration” of column. This way information gets kind of a hierarchy.
As depicted in schema above some part of code in TOra (say a function to create or modify a table) creates extractor format information about object (1). That information is forwarded to toExtractor (2). Depending on type of connection used database specific implementation of extractor is called. For example if Oracle connection was used - toOracleExtractor (3) will be invoked to create final script (4).
There are a number of functions defined in toextract.cpp helping in handling of this internal format. You would use them when implementing extractor for a specific database or when writing a database-independent extractor request.
This function will take two lists as parameters: 1st list is “source” list, 2nd list is “destination” list. Thus function will check which options are present in source list but are not present in destination list and return them as “drop” features. If feature is not in source but is listed in destination list it will be returned as part of “create” features.
This function will usually be used in migrate function to check what has to be changed in existing objects.
You provide a list of QStrings containing properties of object and a number of arguments to this function. It will combine given arguments into “\01” separated string and add it to given list of QString. This function should be used when creating lists describing database objects in TOra “meta” language.
Splits QString of “\01” separated properties into a std::list. Could be used if processing std::list is easier/clearer.
Splits “\01” separated string and returns requested (parameter level) part. If given string has less parts than described level then null is returned.
TODO
TODO
TODO
Main abstract (vendor independent) extractor functions create, describe, drop and migrate are wrappers of vendor specific functions adding possibility to request more than one extract operation in one go. For example you could request creation of two tables or one table and two indexes in one call. These four functions would group such “multicalls” and call corresponding vendor specific extractor for one specific object for one specific operation. (Note that for migrate function is different from the other three because it is taking two lists of descriptions of objects as compared to one line per object for the first three functions. migrateGroup is helping migrate function to split/group request lists per object/operation.
These wrappers provide progress feedback allowing user to cancel the loop.
If heading generation is switched on (see extractor property description above) then this function will create vendor independent description of script being generated. Description will include time of generation, application version etc.