# Source: toextract.h

Annotated List
Files
Globals
Hierarchy
Index

    /*****
     *
     * TOra - An Oracle Toolkit for DBA's and developers
     * Copyright (C) 2003-2005 Quest Software, Inc
     * Portions Copyright (C) 2005 Other Contributors
     *
     * 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.
     *
     *      You may link this product with any GPL'd Qt library such as Qt/Free
     *
     * All trademarks belong to their respective owners.
     *
     *****/

    #ifndef TO_EXTRACT
    #define TO_EXTRACT

    #include <list>
    #include

    #include <qfile.h>
    #include <qstring.h>
    #include <qtextstream.h>
    #include <qvariant.h>

    class QWidget;
    class toConnection;

    #include "tosqlparse.h"

    // 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:
      /** Describes an available datatype for the database.
       */
      class datatype {
      private:
        QString Name;
        int MaxLength;
        int MaxPrecision;
      public:
        /** Create a new datatype description.
         * @param name Name of datatype.
         * @param maxLength Maximum length of parameter if length is needed.
         * @param maxPrecision Maximum precision of parameter if precision is supported.
         */
        datatype(const QString &name,int maxLength=-1,int maxPrecision=-1)
          : Name(name),MaxLength(maxLength),MaxPrecision(maxPrecision)
        { }
        /** Returns true if type has length specification.
         */
        bool hasLength()
        { return MaxLength!=-1; }
        /** Returns true if type has precision specification.
         */
        bool hasPrecision()
        { return MaxPrecision!=-1; }
        /** Get the maximum length value.
         */
        int maxLength()
        { return MaxLength; }
        /** Get the maximum precision of the datatype.
         */
        int maxPrecision()
        { return MaxPrecision; }
        /** Get the name of the datatype.
         */
        const QString &name()
        { return Name; }

        /** Implemented so that you can easily sort a list of them. Just compares the names.
         */
        bool operator < (const datatype &dat) const
        { return Name<dat.Name; }
        /** Implemented so that you can easily sort a list of them. Just compares the names.
         */
        bool operator == (const datatype &dat) const
        { return Name==dat.Name; }
      };

      /** 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;

        /** Get the available datatypes for the database.
         */
        virtual std::list<datatype> datatypes() 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);

      /** Get the available datatypes for a database.
       * @return A list of datatypes.
       */
      std::list<datatype> datatypes();

      /** Utility function, creates a statement from the start to the end specified by the
       * parameters. The connection used to specify parsing is the one of the extractor.
       * @param start Start of parameters.
       * @param end End of parameters.
       * @return The indented statement.
       */
      QString createFromParse(std::list<toSQLParse::statement>::iterator start,
    			  std::list<toSQLParse::statement>::iterator end);

      /** 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,const 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);

      /** Used to get column information from a describe list
       */
      struct columnInfo {
        /** Name of column
         */
        QString Name;
        /** Definition of column
         */
        QString Definition;
        /** Extra data for the column (Except for order which has own field.
         */
        std::map<QString,QString> Data;
        /** Order of the column. Used for sorting.
         */
        int Order;

        /** Create column information from name.
         */
        columnInfo(const QString &name)
          : Name(name)
        { Order=0; }
        /** Implement sort order based only on Order field.
         */
        bool operator <(const columnInfo &inf)
        { return Order<inf.Order; }
        /** Implement sort order based only on Order field.
         */
        bool operator ==(const columnInfo &inf)
        { return Order==inf.Order; }
      };

      /** Parse a column description and return a sorted list of column data.
       * @param begin The iterator indicating the beginning to start searching from (Inclusive).
       * @param end The iterator indicating the end to end searching at (Not inclusive).
       * @param level Number of levels of context to discard before looking for "COLUMN" definition.
       * @return The list of column definitions. Sorted by column order.
       */
      static std::list<columnInfo> parseColumnDescription(std::list<QString>::const_iterator begin,
    						      std::list<QString>::const_iterator end,
    						      int level=3);

      /** Parse a column description and return a sorted list of column data.
       * @param description A description list. Will go through entire list.
       * @param level Number of levels of context to discard before looking for "COLUMN" definition.
       * @return The list of column definitions. Sorted by column order.
       */
      static std::list<columnInfo> parseColumnDescription(const std::list<QString> &description,int level=3)
      { return parseColumnDescription(description.begin(),description.end(),level); }

      friend class extractor;
    };

    #endif

Generated by: nneul on skyhawk on Wed Feb 23 19:49:58 2005, using kdoc 2.0a54.