Exemplo n.º 1
0
        public void Deserialize(XmlReader reader)
        {
            Reset();

            SoodaObject        currentObject   = null;
            SoodaRelationTable currentRelation = null;
            bool inDebug = false;

            // state data for just-being-read object

            bool   objectForcePostCommit       = false;
            bool   objectDisableObjectTriggers = false;
            bool   objectDelete = false;
            string objectClassName;
            string objectMode = null;

            object[]            objectPrimaryKey = null;
            ClassInfo           objectClassInfo;
            ISoodaObjectFactory objectFactory = null;
            int objectKeyCounter      = 0;
            int objectTotalKeyCounter = 0;

            try
            {
                _savingObjects = true;

                // in case we get any "deleteobject" which require us to delete the objects
                // within transaction
                foreach (SoodaDataSource source in _dataSources)
                {
                    source.BeginSaveChanges();
                }

                while (reader.Read())
                {
                    if (reader.NodeType == XmlNodeType.Element && !inDebug)
                    {
                        switch (reader.Name)
                        {
                        case "field":
                            if (currentObject == null)
                            {
                                throw new Exception("Field without an object during deserialization!");
                            }

                            currentObject.DeserializeField(reader);
                            break;

                        case "persistent":
                            if (currentObject == null)
                            {
                                throw new Exception("Field without an object during deserialization!");
                            }

                            currentObject.DeserializePersistentField(reader);
                            break;

                        case "object":
                            if (currentObject != null)
                            {
                                // end deserialization

                                currentObject.EnableFieldUpdateTriggers();
                                currentObject = null;
                            }

                            objectKeyCounter            = 0;
                            objectForcePostCommit       = false;
                            objectDisableObjectTriggers = false;
                            objectClassName             = reader.GetAttribute("class");
                            objectMode            = reader.GetAttribute("mode");
                            objectDelete          = false;
                            objectFactory         = GetFactory(objectClassName);
                            objectClassInfo       = objectFactory.GetClassInfo();
                            objectTotalKeyCounter = objectClassInfo.GetPrimaryKeyFields().Length;
                            if (objectTotalKeyCounter > 1)
                            {
                                objectPrimaryKey = new object[objectTotalKeyCounter];
                            }
                            if (reader.GetAttribute("forcepostcommit") != null)
                            {
                                objectForcePostCommit = true;
                            }
                            if (reader.GetAttribute("disableobjecttriggers") != null)
                            {
                                objectDisableObjectTriggers = true;
                            }
                            if (reader.GetAttribute("delete") != null)
                            {
                                objectDelete = true;
                            }
                            break;

                        case "key":
                            int    ordinal = Convert.ToInt32(reader.GetAttribute("ordinal"));
                            object val     = objectFactory.GetFieldHandler(ordinal).RawDeserialize(reader.GetAttribute("value"));

                            if (objectTotalKeyCounter > 1)
                            {
                                objectPrimaryKey[objectKeyCounter] = val;
                            }

                            objectKeyCounter++;

                            if (objectKeyCounter == objectTotalKeyCounter)
                            {
                                object primaryKey = objectTotalKeyCounter == 1 ? val : new SoodaTuple(objectPrimaryKey);

                                currentObject = BeginObjectDeserialization(objectFactory, primaryKey, objectMode);
                                if (objectForcePostCommit)
                                {
                                    currentObject.ForcePostCommit();
                                }
                                if (objectDisableObjectTriggers)
                                {
                                    currentObject.DisableObjectTriggers();
                                }
                                currentObject.DisableFieldUpdateTriggers();
                                if (objectDelete)
                                {
                                    DeletedObjects.Add(currentObject);
                                    currentObject.DeleteMarker = true;
                                    currentObject.CommitObjectChanges();
                                    currentObject.SetObjectDirty();
                                }
                            }
                            break;

                        case "transaction":
                            break;

                        case "relation":
                            currentRelation = GetRelationFromXml(reader);
                            break;

                        case "tuple":
                            currentRelation.DeserializeTuple(reader);
                            break;

                        case "debug":
                            if (!reader.IsEmptyElement)
                            {
                                inDebug = true;
                            }
                            break;

                        default:
                            throw new NotImplementedException("Element not implemented in deserialization: " + reader.Name);
                        }
                    }
                    else if (reader.NodeType == XmlNodeType.EndElement)
                    {
                        if (reader.Name == "debug")
                        {
                            inDebug = false;
                        }
                        else if (reader.Name == "object")
                        {
                            currentObject.EnableFieldUpdateTriggers();
                        }
                    }
                }

                foreach (WeakSoodaObject wr in _objectList)
                {
                    SoodaObject ob = wr.TargetSoodaObject;
                    if (ob != null)
                    {
                        ob.AfterDeserialize();
                    }
                }
            }
            finally
            {
                _savingObjects = false;

                foreach (SoodaDataSource source in _dataSources)
                {
                    source.FinishSaveChanges();
                }
            }
        }