Introduction
CopySchema is a utility for copying all the data from one Oracle schema to another.
Detail documentation is mostly in the code. This document is rather to explain the design as a whole and to offer suggestions about how to get started at familiarizing yourself with the code.
Aside from a simple C++ COM utility that does the bulk copying, the main code areas are
- The Job classes, each of which defines a step in the process
- The ThreadController, which initializes and controls all the jobs
- The Worker class, which runs each worker thread
- The DbTable classes, which implement database operations at the table level
- The DbSchema, which implements database operations at the schema level
Sequence / Program Flow
The ThreadController and Worker classes control all the program flow. The ThreadController.Start() function creates the two first jobs (getting definitions from the two schemas) and starts the threads. The Worker classes run in a loop, getting jobs from the ThreadController, executing the job, and then returning the result to the ThreadController.
The following may be of interest:
Table 1. FormMain class
| Function | Notes |
|
|
A pseudo-singleton, in that a static variable stores the address of the last (and only) instance of the class. Classes can access the form using its Instance() static function |
| btnStart_Click () | Saves and sets up all the settings required to start the work, then calls ThreadController.Start() |
Table 2. ThreadController class
| Function | Notes |
|
|
Singleton, thread-safe |
| Start() |
Begin the copy process
|
| GetNextJob() | Simple function that pops off the next job in the queue. If no jobs are available, it returns a JobWait
|
| ReturnJob() | Decides what to do after any particular job finishes |
| Function | Notes |
|
|
Holds a reference to its own private logger (FormLog) and its own private CopyTable COM server |
| Start() | Although it looks complicated because of the error handling, the function essentially does the following:
|
Areas of Functionality
N.B.: the 'read schema' is the schema from which the data is copied, and the 'write schema' is the destination.
Similarly, the 'read tables' and 'write tables' are the source and destination for the data, respectively.
With the exception of the DbField class (which is a simple structure and does not do any database access), all classes that start with the prefix 'Db' are classes that contain code to access the databases. There is no database access in any other class.
DbSchema
The DbSchema class contains the list of tables for that schema, along with functions to retrieve that information from the database. In addition, there are functions to modify the entire schema (i.e. all tables or sequences within the schema) and to compare the two schemas.
Figure 1. DbSchema Class Members

N.B.: underlined names are static members, a '+' signifies a public member and '#' a protected member.
DbTables
The DbTables have members to hold the definition of a given table. The DbTable parent is an abstract class that has all the functions and members that are shared by both the read and write tables.
The way that functions are split into the classes may seem a little confusing at first, because most of the functionality that might be associated with the DbSelectTable is actually shared, and thus ends up in the parent class. The DbSelectTable actually contains very little code.
There are only two polymorphic functions:
Table 4. DbTable Polymorphic Functions
| Function | Notes |
| DbGetDefinition( | Gets the list and details of all the columns of the table. This function is overridden only in DbInsertTable, since it needs to retrieve supplementary information (this definition all that is required for the DbSelectTables) |
| OleDbConnectionString () | The 'read' and 'write' tables each access their own database |


Join the conversation! Your thoughts help the community grow.