Sophie

Sophie

distrib > Fedora > 15 > i386 > by-pkgid > 2e9c43658e374d290a2de15d25134ac8 > files > 373

db4o-doc-8.0-1.fc15.i686.rpm

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" MadCap:lastBlockDepth="2" MadCap:lastHeight="120" MadCap:lastWidth="624" MadCap:disableMasterStylesheet="true" MadCap:tocPath="Advanced Features|Callbacks|Possible Usecases" MadCap:InPreviewMode="false" MadCap:RuntimeFileType="Topic" MadCap:TargetType="WebHelp" MadCap:PathToHelpSystem="../../../../" MadCap:HelpSystemFileName="index.xml" MadCap:SearchType="Stem">
    <head><title>Autoincrement	</title>
        <script type="text/javascript">/* <![CDATA[ */
window.onload = function(){
	var pathToFlash = $('html').attr('MadCap:PathToHelpSystem') + 'Content/Resources/Code/ZeroClipboard.swf';
	ZeroClipboard.setMoviePath(pathToFlash);
			
	function bindToClipBord(element,content){
		var clip = new ZeroClipboard.Client();
		clip.setText(content);
		clip.glue(element);
	};
		
	if(location.protocol==='file:'){
		$('.copylink-marker').remove();
	} else{
			$('.copylink-marker').each(function(){
				var text = $(this).parent().parent().children('.prettyprint').html();
				$(this).hover(function(){
					bindToClipBord(this,text);
				},
				function(){});
			});	
	}		
	prettyPrint();	
};
                /* ]]> */</script>
        <link href="../../../SkinSupport/MadCap.css" rel="stylesheet" />
        <link href="../../../Resources/Stylesheets/OnlineStyle.css" rel="stylesheet" />
        <script src="../../../SkinSupport/MadCapAll.js">
        </script>
        <script src="../../../Resources/Code/prettify.js">
        </script>
        <script src="../../../Resources/Code/lang-vb.js">
        </script>
        <script src="../../../Resources/Code/jquery.min.js">
        </script>
        <script src="../../../Resources/Code/ZeroClipboard.js">
        </script>
    </head>
    <body>
        <p class="MCWebHelpFramesetLink" style="display: none;"><a href="../../../../index_CSH.html#advanced_topics/callbacks/possible_usecases/autoincrement.htm" style="">Open topic with navigation</a>
        </p>
        <div class="MCBreadcrumbsBox"><span class="MCBreadcrumbsPrefix">You are here: </span><a class="MCBreadcrumbsLink" href="../../../advanced_topics.htm">Advanced Features</a><span class="MCBreadcrumbsDivider"> &gt; </span><a class="MCBreadcrumbsLink" href="../../callbacks.htm">Callbacks</a><span class="MCBreadcrumbsDivider"> &gt; </span><a class="MCBreadcrumbsLink" href="../possible_usecases.htm">Possible Usecases</a><span class="MCBreadcrumbsDivider"> &gt; </span><span class="MCBreadcrumbs">Autoincrement</span>
        </div>
        <p>
            <script type="text/javascript">/*<![CDATA[*/document.write('<a href="' + location.href +'">');
				document.write("Direct Link");
			document.write('</a>');/*]]>*/</script>
        </p>
        <p>
        </p>
        <h1><a name="kanchor82"></a>Autoincrement</h1>
        <p>db4o does not deliver a field auto increment feature, which
is common in <span class="MCTextPopup"><a href="javascript:void(0);" class="MCTextPopupSpot" onclick="FMCTextPopup( event, this ); return false;">RDBMS<img style="border: none;margin-left: 5px;" src="../../../SkinSupport/ExpandingClosed.gif" MadCap:altsrc="../../../SkinSupport/ExpandingOpen.gif" class="MCExpandingIcon" onload="if ( typeof( FMCPreloadImage ) == 'function' ) { FMCPreloadImage( '../../../SkinSupport/ExpandingOpen.gif' ); }" /></a><span class="MCTextPopupBody" style="display: none; ">Relational Database Management System</span></span>. Normally you don't need any additional ids, since db4o manages objects by object-identity. However cases where you have <a href="../../../platform_specific_issues/disconnected_objects.htm">disconnected objects</a>, you need additional ids. One of then possibilities it to use auto incremented ids.</p>
        <p> If your application logic requires this feature you can
implement it using external callbacks. One of the possible solutions is
presented below. Note that this example only works in embedded-mode.</p>
        <p>This example assumes that all object which need an auto incremented id are subclasses of the IDHolder-class. This class contains the auto-incremented id.</p>
        <div class="codesnippet" MadCap:conditions="Primary.c#">
            <pre class="prettyprint" xml:space="preserve">private int id;

public int Id
{
    get { return id; }
    set { id = value; }
}
</pre>
            <div class="codesnippet-meta">IDHolder.cs: id holder
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-csharp.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <div class="codesnippet" MadCap:conditions="Primary.VB.NET">
            <pre class="prettyprint lang-vb" MadCap:conditions="Primary.Online" xml:space="preserve">Private m_id As Integer

Public Property Id() As Integer
    Get
        Return m_id
    End Get
    Set(ByVal value As Integer)
        m_id = value
    End Set
End Property
</pre>
            <div class="codesnippet-meta">IDHolder.vb: id holder
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-vb.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <p>First create a class which keeps the state of the auto-increment numbers. For example a map which keeps the latest auto incremented id for each class.</p>
        <div class="codesnippet" MadCap:conditions="Primary.c#">
            <pre class="prettyprint" xml:space="preserve">private class PersistedAutoIncrements
{
    private readonly IDictionary&lt;Type, int&gt; currentHighestIds = new Dictionary&lt;Type, int&gt;();

    public int NextNumber(Type forClass)
    {
        int number;
        if (!currentHighestIds.TryGetValue(forClass, out number))
        {
            number = 0;
        }
        number += 1;
        currentHighestIds[forClass] = number;
        return number;
    }
}
</pre>
            <div class="codesnippet-meta">AutoIncrement.cs: persistent auto increment
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-csharp.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <div class="codesnippet" MadCap:conditions="Primary.VB.NET">
            <pre class="prettyprint lang-vb" MadCap:conditions="Primary.Online" xml:space="preserve">Private Class PersistedAutoIncrements
    Private ReadOnly currentHighestIds As IDictionary(Of Type, Integer) _
                        = New Dictionary(Of Type, Integer)()

    Public Function NextNumber(ByVal forClass As Type) As Integer
        Dim number As Integer
        If Not currentHighestIds.TryGetValue(forClass, number) Then
            number = 0
        End If
        number += 1
        currentHighestIds(forClass) = number
        Return number
    End Function
End Class
</pre>
            <div class="codesnippet-meta">AutoIncrement.vb: persistent auto increment
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-vb.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <p>Then create two methods, which are called later. One which returns the next auto-incremented id for a certain class. Another which stores the current state of the auto-increments.</p>
        <div class="codesnippet" MadCap:conditions="Primary.c#">
            <pre class="prettyprint" xml:space="preserve">public int GetNextID(Type forClass)
{
    lock (dataLock)
    {
        PersistedAutoIncrements incrementState = EnsureLoadedIncrements();
        return incrementState.NextNumber(forClass);
    }
}

public void StoreState()
{
    lock (dataLock)
    {
        if (null != state)
        {
            container.Ext().Store(state,2);
        }
    }
}
</pre>
            <div class="codesnippet-meta">AutoIncrement.cs: getting the next id and storing state
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-csharp.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <div class="codesnippet" MadCap:conditions="Primary.VB.NET">
            <pre class="prettyprint lang-vb" MadCap:conditions="Primary.Online" xml:space="preserve">Public Function GetNextID(ByVal forClass As Type) As Integer
    SyncLock dataLock
        Dim incrementState As PersistedAutoIncrements = EnsureLoadedIncrements()
        Return incrementState.NextNumber(forClass)
    End SyncLock
End Function

Public Sub StoreState()
    SyncLock dataLock
        If state IsNot Nothing Then
            container.Ext().Store(state, 2)
        End If
    End SyncLock
End Sub
</pre>
            <div class="codesnippet-meta">AutoIncrement.vb: getting the next id and storing state
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-vb.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <p>The last part is to ensure that the existing auto-increments are loaded from the database. Or if not existing a new instance is created.</p>
        <div class="codesnippet" MadCap:conditions="Primary.c#">
            <pre class="prettyprint" xml:space="preserve">private PersistedAutoIncrements EnsureLoadedIncrements()
{
    if (null == state)
    {
        state = LoadOrCreateState();
    }
    return state;
}

private PersistedAutoIncrements LoadOrCreateState()
{
    IList&lt;PersistedAutoIncrements&gt; existingState = container.Query&lt;PersistedAutoIncrements&gt;();
    if (0 == existingState.Count)
    {
        return new PersistedAutoIncrements();
    }
    else if (1 == existingState.Count)
    {
        return existingState[0];
    }
    else
    {
        throw new InvalidOperationException("Cannot have more than one state stored in database");
    }
}
</pre>
            <div class="codesnippet-meta">AutoIncrement.cs: load the state from the database
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-csharp.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <div class="codesnippet" MadCap:conditions="Primary.VB.NET">
            <pre class="prettyprint lang-vb" MadCap:conditions="Primary.Online" xml:space="preserve">Private Function EnsureLoadedIncrements() As PersistedAutoIncrements
    If state Is Nothing Then
        state = LoadOrCreateState()
    End If
    Return state
End Function

Private Function LoadOrCreateState() As PersistedAutoIncrements
    Dim existingState As IList(Of PersistedAutoIncrements) = container.Query(Of PersistedAutoIncrements)()
    If 0 = existingState.Count Then
        Return New PersistedAutoIncrements()
    ElseIf 1 = existingState.Count Then
        Return existingState(0)
    Else
        Throw New InvalidOperationException("Cannot have more than one state stored in database")
    End If
End Function

</pre>
            <div class="codesnippet-meta">AutoIncrement.vb: load the state from the database
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-vb.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <p>Now it's time to use the callbacks. Every time when a new object is created, assign a new id. For this the creating-event is perfect. When commiting  also make the auto increment-state persistent, to ensure that no id is used twice.</p>
        <div class="codesnippet" MadCap:conditions="Primary.c#">
            <pre class="prettyprint" xml:space="preserve">AutoIncrement increment = new AutoIncrement(container);
IEventRegistry eventRegistry = EventRegistryFactory.ForObjectContainer(container);

eventRegistry.Creating+=
    delegate(object sender, CancellableObjectEventArgs args)
    {
        if (args.Object is IDHolder)
        {
            IDHolder idHolder = (IDHolder)args.Object;
            idHolder.Id = increment.GetNextID(idHolder.GetType());
        }    
    };
eventRegistry.Committing +=
    delegate(object sender, CommitEventArgs args)
        {
            increment.StoreState();    
        };</pre>
            <div class="codesnippet-meta">AutoIncrementExample.cs: use events to assign the ids
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-csharp.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <div class="codesnippet" MadCap:conditions="Primary.VB.NET">
            <pre class="prettyprint lang-vb" MadCap:conditions="Primary.Online" xml:space="preserve">Dim increment As New AutoIncrement(container)
Dim eventRegistry As IEventRegistry = EventRegistryFactory.ForObjectContainer(container)

AddHandler eventRegistry.Creating, AddressOf increment.HandleCreating
AddHandler eventRegistry.Committing, AddressOf increment.HandleCommiting</pre>
            <div class="codesnippet-meta">AutoIncrementExample.vb: use events to assign the ids
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-vb.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <p>Last, don't forget to index the id-field. Otherwise looks-ups will be slow.</p>
        <div class="codesnippet" MadCap:conditions="Primary.c#">
            <pre class="prettyprint" xml:space="preserve">configuration.Common.ObjectClass(typeof (IDHolder)).ObjectField("id").Indexed(true);</pre>
            <div class="codesnippet-meta">AutoIncrementExample.cs: index the id-field
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-csharp.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <div class="codesnippet" MadCap:conditions="Primary.VB.NET">
            <pre class="prettyprint lang-vb" MadCap:conditions="Primary.Online" xml:space="preserve">configuration.Common.ObjectClass(GetType(IDHolder)).ObjectField("id").Indexed(True)</pre>
            <div class="codesnippet-meta">AutoIncrementExample.vb: index the id-field
			<div class="codedownload"><a href="../../../CodeExamples/disconnectedobj/idexamples/Example-disconnectedobj-idexamples-vb.zip" class="codedownload" MadCap:conditions="Primary.Online">Download Code</a></div><div class="codedownload copylink-marker" MadCap:conditions="Primary.Online"><a href="#copy">Copy Code</a></div></div>
        </div>
        <script type="text/javascript" src="../../../SkinSupport/MadCapBodyEnd.js">
        </script>
    </body>
</html>