Click here to Skip to main content
15,896,348 members
Articles / Programming Languages / C#

Using a Database Over a Webservice

Rate me:
Please Sign up or sign in to vote.
4.43/5 (5 votes)
29 May 20073 min read 48.6K   539   44  
This article shows an example implementation of a database used over a Web-Service
/* Copyright (C) 2004 - 2007  db4objects Inc.  http://www.db4o.com */

using System;
using Db4objects.Db4o;
using Db4objects.Db4o.Config;
using Db4objects.Db4o.Ext;
using Db4objects.Db4o.Reflect;
using Db4objects.Db4o.Reflect.Generic;
using Db4objects.Db4o.Replication;
using Db4objects.Db4o.Types;

namespace Db4objects.Db4o.Ext
{
	/// <summary>
	/// extended functionality for the
	/// <see cref="IObjectContainer">ObjectContainer</see>
	/// interface.
	/// <br /><br />Every db4o
	/// <see cref="IObjectContainer">ObjectContainer</see>
	/// always is an <code>ExtObjectContainer</code> so a cast is possible.<br /><br />
	/// <see cref="IObjectContainer.Ext">IObjectContainer.Ext</see>
	/// is a convenient method to perform the cast.<br /><br />
	/// The ObjectContainer functionality is split to two interfaces to allow newcomers to
	/// focus on the essential methods.
	/// </summary>
	public interface IExtObjectContainer : IObjectContainer
	{
		/// <summary>backs up a database file of an open ObjectContainer.</summary>
		/// <remarks>
		/// backs up a database file of an open ObjectContainer.
		/// <br /><br />While the backup is running, the ObjectContainer can continue to be
		/// used. Changes that are made while the backup is in progress, will be applied to
		/// the open ObjectContainer and to the backup.<br /><br />
		/// While the backup is running, the ObjectContainer should not be closed.<br /><br />
		/// If a file already exists at the specified path, it will be overwritten.<br /><br />
		/// The backup call may be started in a seperated thread by the application,
		/// if concurrent execution with normal database access is desired.<br /><br />
		/// </remarks>
		/// <param name="path">a fully qualified path</param>
		/// <exception cref="Db4oIOException">I/O operation failed or was unexpectedly interrupted.
		/// 	</exception>
		/// <exception cref="DatabaseClosedException">db4o database file was closed or failed to open.
		/// 	</exception>
		/// <exception cref="NotSupportedException">
		/// is thrown when the operation is not supported in current
		/// configuration/environment
		/// </exception>
		void Backup(string path);

		/// <summary>binds an object to an internal object ID.</summary>
		/// <remarks>
		/// binds an object to an internal object ID.
		/// <br /><br />This method uses the ID parameter to load the
		/// correspondig stored object into memory and replaces this memory
		/// reference with the object parameter. The method may be used to replace
		/// objects or to reassociate an object with it's stored instance
		/// after closing and opening a database file. A subsequent call to
		/// <see cref="IObjectContainer.Set">set(Object)</see>
		/// is
		/// necessary to update the stored object.<br /><br />
		/// <b>Requirements:</b><br />- The ID needs to be a valid internal object ID,
		/// previously retrieved with
		/// <see cref="IExtObjectContainer.GetID">getID(Object)</see>
		/// .<br />
		/// - The object parameter needs to be of the same class as the stored object.<br /><br />
		/// </remarks>
		/// <seealso cref="IExtObjectContainer.GetID">IExtObjectContainer.GetID</seealso>
		/// <param name="obj">the object that is to be bound</param>
		/// <param name="id">the internal id the object is to be bound to</param>
		/// <exception cref="DatabaseClosedException">db4o database file was closed or failed to open.
		/// 	</exception>
		/// <exception cref="InvalidIDException">
		/// when the provided id is outside the scope of the
		/// database IDs.
		/// </exception>
		void Bind(object obj, long id);

		/// <summary>
		/// returns the
		/// <see cref="IDb4oCollections">IDb4oCollections</see>
		/// interface to create or modify database-aware
		/// collections for this
		/// <see cref="IObjectContainer">IObjectContainer</see>
		/// .<br /><br />
		/// </summary>
		/// <returns>
		/// the
		/// <see cref="IDb4oCollections">IDb4oCollections</see>
		/// interface for this
		/// <see cref="IObjectContainer">IObjectContainer</see>
		/// .
		/// </returns>
		IDb4oCollections Collections();

		/// <summary>returns the Configuration context for this ObjectContainer.</summary>
		/// <remarks>
		/// returns the Configuration context for this ObjectContainer.
		/// <br /><br />
		/// Upon opening an ObjectContainer with any of the factory methods in the
		/// <see cref="Db4oFactory">Db4o class</see>
		/// , the global
		/// <see cref="IConfiguration">Configuration</see>
		/// context
		/// is copied into the ObjectContainer. The
		/// <see cref="IConfiguration">Configuration</see>
		/// can be modified individually for
		/// each ObjectContainer without any effects on the global settings.<br /><br />
		/// </remarks>
		/// <returns>
		/// 
		/// <see cref="IConfiguration">Configuration</see>
		/// the Configuration
		/// context for this ObjectContainer
		/// </returns>
		/// <seealso cref="Db4oFactory.Configure">Db4oFactory.Configure</seealso>
		IConfiguration Configure();

		/// <summary>returns a member at the specific path without activating intermediate objects.
		/// 	</summary>
		/// <remarks>
		/// returns a member at the specific path without activating intermediate objects.
		/// <br /><br />
		/// This method allows navigating from a persistent object to it's members in a
		/// performant way without activating or instantiating intermediate objects.
		/// </remarks>
		/// <param name="obj">the parent object that is to be used as the starting point.</param>
		/// <param name="path">an array of field names to navigate by</param>
		/// <returns>the object at the specified path or null if no object is found</returns>
		object Descend(object obj, string[] path);

		/// <summary>returns the stored object for an internal ID.</summary>
		/// <remarks>
		/// returns the stored object for an internal ID.
		/// <br /><br />This is the fastest method for direct access to objects. Internal
		/// IDs can be obtained with
		/// <see cref="IExtObjectContainer.GetID">getID(Object)</see>
		/// .
		/// Objects will not be activated by this method. They will be returned in the
		/// activation state they are currently in, in the local cache.<br /><br />
		/// </remarks>
		/// <param name="ID">the internal ID</param>
		/// <returns>
		/// the object associated with the passed ID or <code>null</code>,
		/// if no object is associated with this ID in this <code>ObjectContainer</code>.
		/// </returns>
		/// <seealso cref="IConfiguration.ActivationDepth">Why activation?</seealso>
		/// <exception cref="DatabaseClosedException">db4o database file was closed or failed to open.
		/// 	</exception>
		/// <exception cref="InvalidIDException">when the provided id is outside the scope of the
		/// 	</exception>
		object GetByID(long ID);

		/// <summary>
		/// returns a stored object for a
		/// <see cref="Db4oUUID">Db4oUUID</see>
		/// .
		/// <br /><br />
		/// This method is intended for replication and for long-term
		/// external references to objects. To get a
		/// <see cref="Db4oUUID">Db4oUUID</see>
		/// for an
		/// object use
		/// <see cref="IExtObjectContainer.GetObjectInfo">IExtObjectContainer.GetObjectInfo</see>
		/// and
		/// <see cref="IObjectInfo.GetUUID">IObjectInfo.GetUUID</see>
		/// .<br /><br />
		/// Objects will not be activated by this method. They will be returned in the
		/// activation state they are currently in, in the local cache.<br /><br />
		/// </summary>
		/// <param name="uuid">the UUID</param>
		/// <returns>the object for the UUID</returns>
		/// <seealso cref="IConfiguration.ActivationDepth">Why activation?</seealso>
		/// <exception cref="Db4oIOException">I/O operation failed or was unexpectedly interrupted.
		/// 	</exception>
		/// <exception cref="DatabaseClosedException">db4o database file was closed or failed to open.
		/// 	</exception>
		object GetByUUID(Db4oUUID uuid);

		/// <summary>returns the internal unique object ID.</summary>
		/// <remarks>
		/// returns the internal unique object ID.
		/// <br /><br />db4o assigns an internal ID to every object that is stored. IDs are
		/// guaranteed to be unique within one <code>ObjectContainer</code>.
		/// An object carries the same ID in every db4o session. Internal IDs can
		/// be used to look up objects with the very fast
		/// <see cref="IExtObjectContainer.GetByID">getByID</see>
		/// method.<br /><br />
		/// Internal IDs will change when a database is defragmented. Use
		/// <see cref="IExtObjectContainer.GetObjectInfo">IExtObjectContainer.GetObjectInfo</see>
		/// ,
		/// <see cref="IObjectInfo.GetUUID">IObjectInfo.GetUUID</see>
		/// and
		/// <see cref="IExtObjectContainer.GetByUUID">IExtObjectContainer.GetByUUID</see>
		/// for long-term external references to
		/// objects.<br /><br />
		/// </remarks>
		/// <param name="obj">any object</param>
		/// <returns>
		/// the associated internal ID or <code>0</code>, if the passed
		/// object is not stored in this <code>ObjectContainer</code>.
		/// </returns>
		long GetID(object obj);

		/// <summary>
		/// returns the
		/// <see cref="IObjectInfo">IObjectInfo</see>
		/// for a stored object.
		/// <br /><br />This method will return null, if the passed
		/// object is not stored to this <code>ObjectContainer</code>.<br /><br />
		/// </summary>
		/// <param name="obj">the stored object</param>
		/// <returns>
		/// the
		/// <see cref="IObjectInfo">IObjectInfo</see>
		/// 
		/// </returns>
		IObjectInfo GetObjectInfo(object obj);

		/// <summary>returns the Db4oDatabase identity object for this ObjectContainer.</summary>
		/// <remarks>returns the Db4oDatabase identity object for this ObjectContainer.</remarks>
		/// <returns>the Db4oDatabase identity object for this ObjectContainer.</returns>
		Db4oDatabase Identity();

		/// <summary>tests if an object is activated.</summary>
		/// <remarks>
		/// tests if an object is activated.
		/// <br /><br /><code>isActive</code> returns <code>false</code> if an object is not
		/// stored within the <code>ObjectContainer</code>.<br /><br />
		/// </remarks>
		/// <param name="obj">to be tested<br /><br /></param>
		/// <returns><code>true</code> if the passed object is active.</returns>
		bool IsActive(object obj);

		/// <summary>tests if an object with this ID is currently cached.</summary>
		/// <remarks>
		/// tests if an object with this ID is currently cached.
		/// <br /><br />
		/// </remarks>
		/// <param name="ID">the internal ID</param>
		bool IsCached(long ID);

		/// <summary>tests if this <code>ObjectContainer</code> is closed.</summary>
		/// <remarks>
		/// tests if this <code>ObjectContainer</code> is closed.
		/// <br /><br />
		/// </remarks>
		/// <returns><code>true</code> if this <code>ObjectContainer</code> is closed.</returns>
		bool IsClosed();

		/// <summary>tests if an object is stored in this <code>ObjectContainer</code>.</summary>
		/// <remarks>
		/// tests if an object is stored in this <code>ObjectContainer</code>.
		/// <br /><br />
		/// </remarks>
		/// <param name="obj">to be tested<br /><br /></param>
		/// <returns><code>true</code> if the passed object is stored.</returns>
		/// <exception cref="DatabaseClosedException">db4o database file was closed or failed to open.
		/// 	</exception>
		bool IsStored(object obj);

		/// <summary>
		/// returns all class representations that are known to this
		/// ObjectContainer because they have been used or stored.
		/// </summary>
		/// <remarks>
		/// returns all class representations that are known to this
		/// ObjectContainer because they have been used or stored.
		/// </remarks>
		/// <returns>
		/// all class representations that are known to this
		/// ObjectContainer because they have been used or stored.
		/// </returns>
		IReflectClass[] KnownClasses();

		/// <summary>returns the main synchronisation lock.</summary>
		/// <remarks>
		/// returns the main synchronisation lock.
		/// <br /><br />
		/// Synchronize over this object to ensure exclusive access to
		/// the ObjectContainer.<br /><br />
		/// Handle the use of this functionality with extreme care,
		/// since deadlocks can be produced with just two lines of code.
		/// </remarks>
		/// <returns>Object the ObjectContainer lock object</returns>
		object Lock();

		/// <summary>aids migration of objects between ObjectContainers.</summary>
		/// <remarks>
		/// aids migration of objects between ObjectContainers.
		/// <br /><br />When objects are migrated from one ObjectContainer to another, it is
		/// desirable to preserve virtual object attributes such as the object version number
		/// or the UUID. Use this method to signal to an ObjectContainer that it should read
		/// existing version numbers and UUIDs from another ObjectContainer. This method should
		/// also be used during the Defragment. It is included in the default
		/// implementation supplied in Defragment.java/Defragment.cs.<br /><br />
		/// </remarks>
		/// <param name="objectContainer">
		/// the
		/// <see cref="IObjectContainer">IObjectContainer</see>
		/// objects are to be migrated
		/// from or <code>null</code> to denote that migration is completed.
		/// </param>
		void MigrateFrom(IObjectContainer objectContainer);

		/// <summary>
		/// returns a transient copy of a persistent object with all members set
		/// to the values that are currently stored to the database.
		/// </summary>
		/// <remarks>
		/// returns a transient copy of a persistent object with all members set
		/// to the values that are currently stored to the database.
		/// <br /><br />
		/// The returned objects have no connection to the database.<br /><br />
		/// With the <code>committed</code> parameter it is possible to specify,
		/// whether the desired object should contain the committed values or the
		/// values that were set by the running transaction with
		/// <see cref="IObjectContainer.Set">IObjectContainer.Set</see>
		/// .
		/// <br /><br />A possible usecase for this feature:<br />
		/// An application might want to check all changes applied to an object
		/// by the running transaction.<br /><br />
		/// </remarks>
		/// <param name="@object">the object that is to be cloned</param>
		/// <param name="depth">the member depth to which the object is to be instantiated</param>
		/// <param name="committed">whether committed or set values are to be returned</param>
		/// <returns>the object</returns>
		object PeekPersisted(object @object, int depth, bool committed);

		/// <summary>unloads all clean indices from memory and frees unused objects.</summary>
		/// <remarks>
		/// unloads all clean indices from memory and frees unused objects.
		/// <br /><br />Call commit() and purge() consecutively to achieve the best
		/// result possible. This method can have a negative impact
		/// on performance since indices will have to be reread before further
		/// inserts, updates or queries can take place.
		/// </remarks>
		void Purge();

		/// <summary>unloads a specific object from the db4o reference mechanism.</summary>
		/// <remarks>
		/// unloads a specific object from the db4o reference mechanism.
		/// <br /><br />db4o keeps references to all newly stored and
		/// instantiated objects in memory, to be able to manage object identities.
		/// <br /><br />With calls to this method it is possible to remove an object from the
		/// reference mechanism, to allow it to be garbage collected. You are not required to
		/// call this method in the .NET and JDK 1.2 versions, since objects are
		/// referred to by weak references and garbage collection happens
		/// automatically.<br /><br />An object removed with  <code>purge(Object)</code> is not
		/// "known" to the <code>ObjectContainer</code> afterwards, so this method may also be
		/// used to create multiple copies of  objects.<br /><br /> <code>purge(Object)</code> has
		/// no influence on the persistence state of objects. "Purged" objects can be
		/// reretrieved with queries.<br /><br />
		/// </remarks>
		/// <param name="obj">the object to be removed from the reference mechanism.</param>
		void Purge(object obj);

		/// <summary>Return the reflector currently being used by db4objects.</summary>
		/// <remarks>Return the reflector currently being used by db4objects.</remarks>
		/// <returns>the current Reflector.</returns>
		GenericReflector Reflector();

		/// <summary>refreshs all members on a stored object to the specified depth.</summary>
		/// <remarks>
		/// refreshs all members on a stored object to the specified depth.
		/// <br /><br />If a member object is not activated, it will be activated by this method.
		/// <br /><br />The isolation used is READ COMMITTED. This method will read all objects
		/// and values that have been committed by other transactions.<br /><br />
		/// </remarks>
		/// <param name="obj">the object to be refreshed.</param>
		/// <param name="depth">
		/// the member
		/// <see cref="IConfiguration.ActivationDepth">depth</see>
		/// to which refresh is to cascade.
		/// </param>
		void Refresh(object obj, int depth);

		/// <summary>releases a semaphore, if the calling transaction is the owner.</summary>
		/// <remarks>releases a semaphore, if the calling transaction is the owner.</remarks>
		/// <param name="name">the name of the semaphore to be released.</param>
		void ReleaseSemaphore(string name);

		/// <deprecated>
		/// Since db4o-5.2. Use db4o Replication System (dRS)
		/// instead.<br /><br />
		/// prepares for replication with another
		/// <see cref="IObjectContainer">IObjectContainer</see>
		/// .
		/// <br /><br />An
		/// <see cref="IObjectContainer">IObjectContainer</see>
		/// can only be involved in a replication
		/// process with one other
		/// <see cref="IObjectContainer">IObjectContainer</see>
		/// at the same time.<br /><br />
		/// The returned
		/// <see cref="IReplicationProcess">IReplicationProcess</see>
		/// interface provides methods to commit
		/// and to cancel the replication process.
		/// <br /><br />This ObjectContainer will be "peerA" for the
		/// returned ReplicationProcess. The other ObjectContainer will be "peerB".
		/// </deprecated>
		/// <param name="peerB">
		/// the
		/// <see cref="IObjectContainer">IObjectContainer</see>
		/// to replicate with.
		/// </param>
		/// <param name="conflictHandler">
		/// the conflict handler for this ReplicationProcess.
		/// Conflicts occur
		/// whenever
		/// <see cref="IReplicationProcess.Replicate">IReplicationProcess.Replicate</see>
		/// is called with an
		/// object that was modified in both ObjectContainers since the last
		/// replication run between the two. Upon a conflict the
		/// <see cref="IReplicationConflictHandler.ResolveConflict">IReplicationConflictHandler.ResolveConflict
		/// 	</see>
		/// method will be called in the conflict handler.
		/// </param>
		/// <returns>
		/// the
		/// <see cref="IReplicationProcess">IReplicationProcess</see>
		/// interface for this replication process.
		/// </returns>
		IReplicationProcess ReplicationBegin(IObjectContainer peerB, IReplicationConflictHandler
			 conflictHandler);

		/// <summary>deep update interface to store or update objects.</summary>
		/// <remarks>
		/// deep update interface to store or update objects.
		/// <br /><br />In addition to the normal storage interface,
		/// <see cref="IObjectContainer.Set">ObjectContainer#set(Object)</see>
		/// ,
		/// this method allows a manual specification of the depth, the passed object is to be updated.<br /><br />
		/// </remarks>
		/// <param name="obj">the object to be stored or updated.</param>
		/// <param name="depth">the depth to which the object is to be updated</param>
		/// <seealso cref="IObjectContainer.Set">IObjectContainer.Set</seealso>
		void Set(object obj, int depth);

		/// <summary>attempts to set a semaphore.</summary>
		/// <remarks>
		/// attempts to set a semaphore.
		/// <br /><br />
		/// Semaphores are transient multi-purpose named flags for
		/// <see cref="IObjectContainer">ObjectContainers</see>
		/// .
		/// <br /><br />
		/// A transaction that successfully sets a semaphore becomes
		/// the owner of the semaphore. Semaphores can only be owned
		/// by a single transaction at one point in time.<br /><br />
		/// This method returns true, if the transaction already owned
		/// the semaphore before the method call or if it successfully
		/// acquires ownership of the semaphore.<br /><br />
		/// The waitForAvailability parameter allows to specify a time
		/// in milliseconds to wait for other transactions to release
		/// the semaphore, in case the semaphore is already owned by
		/// another transaction.<br /><br />
		/// Semaphores are released by the first occurence of one of the
		/// following:<br />
		/// - the transaction releases the semaphore with
		/// <see cref="IExtObjectContainer.ReleaseSemaphore">IExtObjectContainer.ReleaseSemaphore
		/// 	</see>
		/// <br /> - the transaction is closed with
		/// <see cref="IObjectContainer.Close">IObjectContainer.Close</see>
		/// <br /> - C/S only: the corresponding
		/// <see cref="IObjectServer">IObjectServer</see>
		/// is
		/// closed.<br /> - C/S only: the client
		/// <see cref="IObjectContainer">IObjectContainer</see>
		/// looses the connection and is timed
		/// out.<br /><br /> Semaphores are set immediately. They are independant of calling
		/// <see cref="IObjectContainer.Commit">IObjectContainer.Commit</see>
		/// or
		/// <see cref="IObjectContainer.Rollback">IObjectContainer.Rollback</see>
		/// .<br /><br /> <b>Possible usecases
		/// for semaphores:</b><br /> - prevent other clients from inserting a singleton at the same time.
		/// A suggested name for the semaphore:  "SINGLETON_" + Object#getClass().getName().<br />  - lock
		/// objects. A suggested name:   "LOCK_" +
		/// <see cref="IExtObjectContainer.GetID">getID(Object)</see>
		/// <br /> -
		/// generate a unique client ID. A suggested name:  "CLIENT_" +
		/// System.currentTimeMillis().<br /><br />
		/// </remarks>
		/// <param name="name">the name of the semaphore to be set</param>
		/// <param name="waitForAvailability">
		/// the time in milliseconds to wait for other
		/// transactions to release the semaphore. The parameter may be zero, if
		/// the method is to return immediately.
		/// </param>
		/// <returns>
		/// boolean flag
		/// <br /><code>true</code>, if the semaphore could be set or if the
		/// calling transaction already owned the semaphore.
		/// <br /><code>false</code>, if the semaphore is owned by another
		/// transaction.
		/// </returns>
		bool SetSemaphore(string name, int waitForAvailability);

		/// <summary>
		/// returns a
		/// <see cref="IStoredClass">IStoredClass</see>
		/// meta information object.
		/// <br /><br />
		/// There are three options how to use this method.<br />
		/// Any of the following parameters are possible:<br />
		/// - a fully qualified classname.<br />
		/// - a Class object.<br />
		/// - any object to be used as a template.<br /><br />
		/// </summary>
		/// <param name="clazz">class name, Class object, or example object.<br /><br /></param>
		/// <returns>
		/// an instance of an
		/// <see cref="IStoredClass">IStoredClass</see>
		/// meta information object.
		/// </returns>
		IStoredClass StoredClass(object clazz);

		/// <summary>
		/// returns an array of all
		/// <see cref="IStoredClass">IStoredClass</see>
		/// meta information objects.
		/// </summary>
		IStoredClass[] StoredClasses();

		/// <summary>
		/// returns the
		/// <see cref="ISystemInfo">ISystemInfo</see>
		/// for this ObjectContainer.
		/// <br /><br />The
		/// <see cref="ISystemInfo">ISystemInfo</see>
		/// supplies methods that provide
		/// information about system state and system settings of this
		/// ObjectContainer.
		/// </summary>
		/// <returns>
		/// the
		/// <see cref="ISystemInfo">ISystemInfo</see>
		/// for this ObjectContainer.
		/// </returns>
		ISystemInfo SystemInfo();

		/// <summary>returns the current transaction serial number.</summary>
		/// <remarks>
		/// returns the current transaction serial number.
		/// <br /><br />This serial number can be used to query for modified objects
		/// and for replication purposes.
		/// </remarks>
		/// <returns>the current transaction serial number.</returns>
		long Version();
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United Arab Emirates United Arab Emirates
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions