//***************************************************************************
/*
* TOra - An Oracle Toolkit for DBA's and developers
* Copyright (C) 2003 Quest Software, Inc
*
* 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; only version 2 of
* the License is valid for this program.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* As a special exception, you have permission to link this program
* with the Oracle Client libraries and distribute executables, as long
* as you follow the requirements of the GNU GPL in regard to all of the
* software in the executable aside from Oracle client libraries.
*
* Specifically you are not permitted to link this program with the
* Qt/UNIX, Qt/Windows or Qt Non Commercial products of TrollTech.
* And you are not permitted to distribute binaries compiled against
* these libraries without written consent from Quest Software, Inc.
* Observe that this does not disallow linking to the Qt Free Edition.
*
* All trademarks belong to their respective owners.
*
****************************************************************************/
#ifndef TO_EXTRACT
#define TO_EXTRACT
#include <list>
#include <map>
#include <qfile.h>
#include <qstring.h>
#include <qtextstream.h>
#include <qvariant.h>
class QWidget;
class toConnection;
// Liberally ported from DDL::Oracle 1.06
// Copyright (c) 2000, 2001 Richard Sutherland - United States of America
/**
* This class can be used to reverse engineered database objects.
*/
class toExtract {
public:
/** This is an abstract class to implement part of an extractor for a database. Observe
* that an extractor must be stateless and threadsafe except for constructors and
* destructors. Use the toExtract::context function for saving context.
*/
class extractor {
protected:
/** Register an operation to be handled by this extractor.
* @param db Database this extractor works on.
* @param oper What kind of operation to implement. Can be one of CREATE,
* DESCRIBE, MIGRATE or DROP.
* @param type The type of object that this is implemented for. Database specific.
*/
void registerExtract(const QString &db,
const QString &oper,
const QString &type);
/** Unregister an operation to be handled by this extractor.
* @param db Database this extractor works on.
* @param oper What kind of operation to implement. Can be one of CREATE,
* DESCRIBE, MIGRATE or DROP.
* @param type The type of object that this is implemented for. Database specific.
*/
void unregisterExtract(const QString &db,
const QString &oper,
const QString &type);
public:
/** Create an extractor. Normally called from a statical instantiator. Should register
* objects it can handle @ref registerExtract. Apart from the objects it handles one
* extractor per database can also register an empty operation and type parameter to
* @ref registerExtract which will be called to initialize an extractor once per
* constructed toExtract object.
* operation.
*/
extractor();
/** Destructor.
*/
virtual ~extractor();
/** Initiate an extractor for a given connection. Can be used to set up states necessary
* for further processing. Should probably set blocksize to be used for resizing (@ref
* toExtract::setBlocksize).
* @param ext Extractor to generate script.
*/
virtual void initialize(toExtract &ext) const;
/** Called to generate a script to recreate a database object.
* @param ext Extractor to generate script.
* @param stream Stream to write script to.
* @param type Type of object to recreate.
* @param schema Specify the schema of the output script or description. If empty
* don't specify any object. If the string "1" use same object as input.
* Otherwise use the specified schema.
* @param owner Owner of database object.
* @param name Name of database object.
* @return A string containing a script to recreate an object.
*/
virtual void create(toExtract &ext,
QTextStream &stream,
const QString &type,
const QString &schema,
const QString &owner,
const QString &name) const;
/** Called to describe a database object.
* @param ext Extractor to generate script.
* @param lst List of descriptions for the object. Should be appended.
* @param type Type of object to recreate.
* @param schema Specify the schema of the output script or description. If empty
* don't specify any object. If the string "1" use same object as input.
* Otherwise use the specified schema.
* @param owner Owner of database object.
* @param name Name of database object.
*/
virtual void describe(toExtract &ext,
std::list<QString> &lst,
const QString &type,
const QString &schema,
const QString &owner,
const QString &name) const;
/** Called to generate a script to migrate a database object from one description to
* another description.
* @param ext Extractor to generate script.
* @param type Type of object to migrate.
* @param src Source description list.
* @param dst Destination description list.
* @return A script to change the src database object to dst.
*/
virtual void migrate(toExtract &ext,
QTextStream &stream,
const QString &type,
std::list<QString> &src,
std::list<QString> &dst) const;
/** Called to generate a script to drop an object.
* @param ext Extractor to generate script.
* @param type Type of object to recreate.
* @param schema Specify the schema of the output script or description. If empty
* don't specify any object. If the string "1" use same object as input.
* Otherwise use the specified schema.
* @param owner Owner of database object.
* @param name Name of database object.
* @return A string containing a script to recreate an object.
*/
virtual void drop(toExtract &ext,
QTextStream &stream,
const QString &type,
const QString &schema,
const QString &owner,
const QString &name) const;
};
private:
toConnection &Connection;
QWidget *Parent;
// Attributes
QString Schema;
QString Resize;
bool Code;
bool Comments;
bool Constraints;
bool Contents;
bool Grants;
bool Heading;
bool Indexes;
bool Parallel;
bool Partition;
bool Prompt;
bool Storage;
bool Initialized;
int CommitDistance;
// Database info
int BlockSize;
std::list<QString> Initial;
std::list<QString> Next;
std::list<QString> Limit;
// Context, can be used by the extractor to save context
std::map<QCString,QVariant> Context;
// Stuff to handle extractors
static std::map<QString,extractor *> *Extractors;
static void allocExtract(void);
static QString extractorName(const QString &db,
const QString &oper,
const QString &type);
static extractor *findExtractor(toConnection &conn,
const QString &oper,
const QString &type);
extractor *findExtractor(const QString &oper,
const QString &type)
{ return findExtractor(Connection,oper,type); }
void initialize(void);
// General internal functions
/** Parse an object string to get owner and name of the object.
* @param object Object string on the format {owner}.{name}.
* @param owner Reference to string which will get the object owner.
* @param name Reference to string which will get the object name.
*/
void parseObject(const QString &object,QString &owner,QString &name);
void setSizes(void);
void rethrow(const QString &what,const QString &object,const QString &exc);
QString generateHeading(const QString &action,std::list<QString> &list);
static std::map<QString,std::list<QString> > migrateGroup(std::list<QString> &grpLst);
public:
/** Create a new extractor.
* @param conn Connection to extract from.
* @param parent Parent widget of progress indicator.
*/
toExtract(toConnection &conn,QWidget *parent);
/** Create script to recreate list of objects.
* @param object List of object. This has the format {type}:{schema}.{object}.
* The type is database dependent but can as an example be of
* CONSTRAINT, DATABASE LINK, EXCHANGE INDEX,
* EXCHANGE TABLE, FUNCTION, INDEX, MATERIALIZED VIEW,
* MATERIALIZED VIEW LOG, PACKAGE, PACKAGE BODY, PROCEDURE,
* PROFILE, ROLE, ROLE GRANTS, ROLLBACK SEGMENT, SEQUENCE,
* SNAPSHOT, SNAPSHOT LOG, SYNONYM, TABLE, TABLE FAMILY,
* TABLE CONTENTS, TABLE REFERENCES, TABLESPACE, TRIGGER,
* TRIGGER, TYPE, USER, USER GRANTS for Oracle databases.
* @return A string containing a script to recreate the specified objects.
*/
QString create(std::list<QString> &object)
{ QString ret; QTextStream s(&ret,IO_WriteOnly); create(s,object); return ret; }
/** Create script to recreate list of objects.
* @param stream Stream to write result to.
* @param object List of object. This has the format {type}:{schema}.{object}.
* The type is database dependent but can as an example be of
* CONSTRAINT, DATABASE LINK, EXCHANGE INDEX,
* EXCHANGE TABLE, FUNCTION, INDEX, MATERIALIZED VIEW,
* MATERIALIZED VIEW LOG, PACKAGE, PACKAGE BODY, PROCEDURE,
* PROFILE, ROLE, ROLE GRANTS, ROLLBACK SEGMENT, SEQUENCE,
* SNAPSHOT, SNAPSHOT LOG, SYNONYM, TABLE, TABLE FAMILY,
* TABLE CONTENTS, TABLE REFERENCES, TABLESPACE, TRIGGER,
* TRIGGER, TYPE, USER, USER GRANTS for Oracle databases.
*/
void create(QTextStream &stream,std::list<QString> &object);
/** Create a description of objects.
* @param object List of object. This has the format {type}:{schema}.{object}.
* The type is database dependent but can as an example be of
* CONSTRAINT, DATABASE LINK, EXCHANGE INDEX,
* EXCHANGE TABLE, FUNCTION, INDEX, MATERIALIZED VIEW,
* MATERIALIZED VIEW LOG, PACKAGE, PACKAGE BODY, PROCEDURE,
* PROFILE, ROLE, ROLE GRANTS, ROLLBACK SEGMENT, SEQUENCE,
* SNAPSHOT, SNAPSHOT LOG, SYNONYM, TABLE, TABLE FAMILY,
* TABLE CONTENTS, TABLE REFERENCES, TABLESPACE, TRIGGER,
* TRIGGER, TYPE, USER, USER GRANTS for Oracle databases.
* @return A list of strings describing the objects. Each string should be
* considered like a list of strings separated by the character '\001'.
* The later in each string the smaller item the change and it is hierachical.
*/
std::list<QString> describe(std::list<QString> &object);
/** Create script to drop a list of objects.
* @param object List of object. This has the format {type}:{schema}.{object}.
* The type is database dependent but can as an example be of
* CONSTRAINT, DATABASE LINK, EXCHANGE INDEX,
* EXCHANGE TABLE, FUNCTION, INDEX, MATERIALIZED VIEW,
* MATERIALIZED VIEW LOG, PACKAGE, PACKAGE BODY, PROCEDURE,
* PROFILE, ROLE, ROLE GRANTS, ROLLBACK SEGMENT, SEQUENCE,
* SNAPSHOT, SNAPSHOT LOG, SYNONYM, TABLE, TABLE FAMILY,
* TABLE CONTENTS, TABLE REFERENCES, TABLESPACE, TRIGGER,
* TRIGGER, TYPE, USER, USER GRANTS for Oracle databases.
* @return A string containing a script to drop the specified objects.
*/
QString drop(std::list<QString> &object)
{ QString ret; QTextStream s(&ret,IO_WriteOnly); drop(s,object); return ret; }
/** Create script to drop a list of objects.
* @param stream Stream to write result to.
* @param object List of object. This has the format {type}:{schema}.{object}.
* The type is database dependent but can as an example be of
* CONSTRAINT, DATABASE LINK, EXCHANGE INDEX,
* EXCHANGE TABLE, FUNCTION, INDEX, MATERIALIZED VIEW,
* MATERIALIZED VIEW LOG, PACKAGE, PACKAGE BODY, PROCEDURE,
* PROFILE, ROLE, ROLE GRANTS, ROLLBACK SEGMENT, SEQUENCE,
* SNAPSHOT, SNAPSHOT LOG, SYNONYM, TABLE, TABLE FAMILY,
* TABLE CONTENTS, TABLE REFERENCES, TABLESPACE, TRIGGER,
* TRIGGER, TYPE, USER, USER GRANTS for Oracle databases.
* @return A string containing a script to drop the specified objects.
*/
void drop(QTextStream &stream,std::list<QString> &object);
/** Called to generate a script to migrate a database object from one description to
* another description.
* @param stream Stream to write result to.
* @param src Source description list, generated by describes for the same database.
* @param dst Destination description list, generated by describes for the same database.
* @return A script to change the src database object to dst.
*/
QString migrate(std::list<QString> &drpLst,std::list<QString> &crtLst)
{ QString ret; QTextStream s(&ret,IO_WriteOnly); migrate(s,drpLst,crtLst); return ret; }
/** Called to generate a script to migrate a database object from one description to
* another description.
* @param stream Stream to write result to.
* @param src Source description list, generated by describes for the same database.
* @param dst Destination description list, generated by describes for the same database.
* @return A script to change the src database object to dst.
*/
void migrate(QTextStream &stream,std::list<QString> &drpLst,std::list<QString> &crtLst);
/** Set a context for this extractor.
* @param name Name of this context
* @param val Value of this context
*/
void setState(const QCString &name,const QVariant &val);
/** Get the value of a context for the current extractor.
* @param name Name of the context to extract.
* @return The value of the context.
*/
QVariant state(const QCString &name);
/** Set the schema of the extraction.
* @param schema Specify the schema of the output script or description. If empty
* don't specify any object. If the string "1" use same object as input.
* Otherwise use the specified schema.
*/
void setSchema(const QString &schema)
{ Schema=schema; }
/** Set sizes to use for resize of object on extraction.
* @param A list of sizes separated by ':'. Should be an even multiple of three where
* the first value is the largest current size to use these values. The next
* value is the initial value to use, the last is the next increment value to
* use. As a special case the string "1" can be used to set up auto resize.
*/
void setResize(const QString &resize)
{ Resize=resize; setSizes(); }
/** Set inclusion of prompts.
* @param prompt If prompt generation should be generated.
*/
void setPrompt(bool prompt)
{ Prompt=prompt; }
/** Include heading in scripts.
* @param heading Include heading in scripts.
*/
void setHeading(bool heading)
{ Heading=heading; }
/** Include constraints in extraction.
* @param constraints Include constraints.
*/
void setConstraints(bool constraints)
{ Constraints=constraints; }
/** Include indexes in extraction.
* @param indexes Include indexes.
*/
void setIndexes(bool indexes)
{ Indexes=indexes; }
/** Include grants in extraction.
* @param val Include grants.
*/
void setGrants(bool val)
{ Grants=val; }
/** Include storage specification in extraction.
* @param val Include storage specification.
*/
void setStorage(bool val)
{ Storage=val; }
/** Include parallel specification in extraction.
* @param val Include parallel specification.
*/
void setParallel(bool val)
{ Parallel=val; }
/** Include partition specification in extraction.
* @param val Include partition specification.
*/
void setPartition(bool val)
{ Partition=val; }
/** Include contents of tables in scripts.
* @param val Include contents of tables.
* @param commitdistance The commit distance of the contents 0 means whole tables.
*/
void setContents(bool val,int commitdistance)
{ Contents=val; CommitDistance=commitdistance; }
/** Include comments in extraction.
* @param val Include indexes.
*/
void setComments(bool val)
{ Comments=val; }
/** Include code in extraction.
* @param val Include code.
*/
void setCode(bool val)
{ Code=val; }
/** Set blocksize of database.
* @param val New value of blocksize.
*/
void setBlockSize(int val)
{ BlockSize=val; setSizes(); }
/** Get schema specification.
* @return Schema specification.
* @see setSchema
*/
const QString &getSchema(void)
{ return Schema; }
/** Get resize specification.
* @return Resize specification.
* @see setResize
*/
bool getResize(void)
{ return !Resize.isEmpty(); }
/** Check if prompt are generated.
* @return If prompts are generated.
*/
bool getPrompt(void)
{ return Prompt; }
/** Check if headings are generated.
* @return If headings are generated.
*/
bool getHeading(void)
{ return Heading; }
/** Check if constraints are generated.
* @return If constraints are generated.
*/
bool getConstraints(void)
{ return Constraints; }
/** Check if indexes are generated.
* @return If indexes are generated.
*/
bool getIndexes(void)
{ return Indexes; }
/** Check if grants are generated.
* @return If grants are generated.
*/
bool getGrants(void)
{ return Grants; }
/** Check if storage specification are generated.
* @return If storage specification are generated.
*/
bool getStorage(void)
{ return Storage; }
/** Check if parallell specification are generated.
* @return If parallell specification are generated.
*/
bool getParallel(void)
{ return Parallel; }
/** Check if partition specification are generated.
* @return If partition specification are generated.
*/
bool getPartition(void)
{ return Partition; }
/** Check if contents of tables are generated.
* @return If content is generated.
*/
bool getContents(void)
{ return Contents; }
/** Get the distance of the commits when content is generated.
* @return Commit distance.
*/
int getCommitDistance(void)
{ return CommitDistance; }
/** Check if comments are generated.
* @return If comments are generated.
*/
bool getComments(void)
{ return Comments; }
/** Check if code is generated.
* @return If code is generated.
*/
bool getCode(void)
{ return Code; }
/** Get blocksize.
*/
int getBlockSize(void)
{ return BlockSize; }
/** Get the connection this extractor is working on.
*/
toConnection &connection()
{ return Connection; }
/** Fill in the initial and next value for an object currently holding a @ref number of
* allocated blocks. Uses the resize or default sizes.
* @param blocks Blocks currently allocated.
* @param initial New initial value.
* @param next New next value.
*/
void initialNext(const QString &blocks,QString &initial,QString &next);
/** Get the schema name specified by the extractor setup. Will include the following '.'
* if needed.
* @param owner Owner of object to get schema for.
* @param desc Used from describe and not to generate script.
* @return The translated schema.
*/
QString intSchema(const QString &owner,bool desc);
/** Create a source and destination object list to two other lists
* containing dropped and created objects or attributes.
* @param source Source list input (Will not be modified).
* @param destination Destination list input (Will not be modified).
* @param drop Drop list output (Will be overwritten).
* @param create Create list output (Will be overwritten).
*/
static void srcDst2DropCreate(std::list<QString> &source,std::list<QString> &destination,
std::list<QString> &drop,std::list<QString> &creat);
/** Check if a database is supported at all by the extractor.
* @param conn Connection to check for support.
* @return True if the database is supported.
*/
static bool canHandle(toConnection &conn);
/** Add a list to description.
* @param ret The return list to add a line to.
* @param ctx The current description context.
* @param arg1 First extra argument to add.
*/
static void addDescription(std::list<QString> &ret,std::list<QString> &ctx,
const QString &arg1=QString::null,const QString &arg2=QString::null,
const QString &arg3=QString::null,const QString &arg4=QString::null,
const QString &arg5=QString::null,const QString &arg6=QString::null,
const QString &arg7=QString::null,const QString &arg8=QString::null,
const QString &arg9=QString::null);
/** Split a description line into its components.
* @param str The description line to split.
* @return The list of components.
*/
static std::list<QString> splitDescribe(const QString &str);
/** Get the part of a description indicated by the level
* @param str Description string
* @param level The level to get (0 is the first level)
*/
static QString partDescribe(const QString &str,int level);
/** Get the context of a given level.
* @param str Description string
* @param level The level to get the context for (1 is the first to not return empty string.
* @return The context, if not enough parts are available null is returned.
*/
static QString contextDescribe(const QString &str,int level);
friend class extractor;
};
#endif