No matter how carefully your schema was designed, sooner or later changes in your application requirements will probably make it necessary to make changes to classes that are already instantiated and in use. When this happens, you will want the process of propagating your changes to be smooth and to impact your work as little as possible.
This chapter discusses the mechanisms GemStone and GemBuilder provide to help you accomplish this.
Schema Modification
explains how GemStone supports schema modification by maintaining versions of classes in class history objects. It shows you how to migrate some or all instances from one version of a class to another while retaining the data that these instances hold.
Schema Coordination
explains how to synchronize schema modifications between GemStone and the client Smalltalk.
Client Smalltalk and GemStone Smalltalk both have schema modification support.
Client Smalltalk supports only a single version of a class. When a class definition is modified, migration of instances to the new class definition occurs immediately.
Because GemStone stores persistent objects, schema modification is a more complex issue.
GemStone Smalltalk supports schema modification and allows a more flexible migration by allowing you to define different versions of classes.These versions are associated by a class history object. When you redefine a class (or create a new class with the same name as an existing class, within the same SymbolDictionary), it automatically creates a new version of the class, leaving the old class definition also present in the repository; voth versions refer to the same classHistory, which contains both class defintions.
It is not necessary that all versions of a class have the same name or other shared attribute; versions of a class are identified by being part of a single class history.
When you create a class defintion, GBS will ask if you wish to commit your change and migrate all instances. This will migrate all instance of the old class definition to the new class definition. While convenient, this may be time-consuming for large repositories.
GemStone server smalltalk supports highly configurable instance migration. For details about schema modification, how GemStone handles class versioning, and the options for instance migration, see the “Class Creation, Versions, and Instance Migration” chapter in the Programming Guide.
GemBuilder’s goal in supporting schema migration is to provide an interaction between the client Smalltalk and the GemStone server that provides as much of GemStone’s capabilities as possible, while minimizing the impact on the client Smalltalk system.
GemBuilder preserves the behavior of having only a single version of a given class in client Smalltalk at one time. That client Smalltalk class will be mapped to a specific version of a GemStone server class, resolved at login time (if a connector is defined) by its name. If, while faulting an object into client Smalltalk, GemBuilder discovers that the server object is an instance of a class that is a different version of the class that is in client Smalltalk, and the class version of the server object is earlier than the class version that is already mapped to the client class, it will be faulted in in the format of the class in client Smalltalk and flagged so that if it is modified and written back to the server, the server instance will be of the newer class version. This will lazily-migrate forward server instances to newer class versions.
For example, suppose you have a class named Foo on the GemStone server, and there are two versions of it: Foo [1] and Foo [2]. Suppose that client Smalltalk has a representation of Foo [2]. Instances of Foo [2] are replicated back and forth between client and server, as usual. If GemBuilder attempts to fault an instance of Foo [1], however, GemBuilder will discover that there is no class mapping for Foo [1]. GemBuilder will then do the following:
1. It will fetch the name of the GemStone server class and discover that there is a client Smalltalk class by the same name that is already mapped to a server class.
2. It will verify that the two server classes are in the same class history, and that the version of Foo [1] is earlier than the version of Foo [2].
3. It will then ask GemStone to make a copy of the Foo [1] instance, migrate the copy to Foo [2], and replicate that migrated copy to the client. The client replicate is mapped to the original Foo [1] server instance.
4. If the client replicate is later modified in client Smalltalk, marked dirty, and flushed to the server, it will not be migrated back, and the server object will become an instance of Foo [2].
This process is fairly expensive. If you are running GemBuilder in verbose mode, the discovery of an client Smalltalk class that is mapped to an old version of a GemStone server class (a version that is not the migration destination) will be logged to the transcript. If you see this happening frequently, you should consider migrating your instances to the GemStone server class version corresponding to your client Smalltalk class.