Beispiel #1
0
        /// <summary>
        /// Saves a storable object in the database.
        /// </summary>
        /// <param name="obj">Storable object to save.</param>
        /// <param name="db">Database.</param>
        /// <param name="context">Serialization context.</param>
        /// <param name="saveChildren">If set to <c>false</c>, <see cref="IStorable"/> children are not saved.</param>
        internal static void SaveObject(IStorable obj, Database db, SerializationContext context = null,
                                        bool saveChildren = true)
        {
            if (context == null)
            {
                context = new SerializationContext(db, obj.GetType());
                if (obj.ParentID != Guid.Empty)
                {
                    context.RootID = obj.ParentID;
                }
                else
                {
                    context.RootID = obj.ID;
                }
            }
            context.SaveChildren = saveChildren;
            context.Stack.Push(obj);
            Document doc = db.GetDocument(DocumentsSerializer.StringFromID(obj.ID, context.RootID));

            doc.Update((UnsavedRevision rev) => {
                JObject jo = SerializeObject(obj, rev, context);
                IDictionary <string, object> props = jo.ToObject <IDictionary <string, object> > ();

                /* SetProperties sets a new properties dictionary, removing the attachments we
                 * added in the serialization */
                if (rev.Properties.ContainsKey("_attachments"))
                {
                    props ["_attachments"] = rev.Properties ["_attachments"];
                }
                rev.SetProperties(props);
                return(true);
            });
            context.Stack.Pop();
        }
Beispiel #2
0
        /// <summary>
        /// Store a collection of specified objects
        /// </summary>
        /// <param name="storableEnumerable">The objects collection to store.</param>
        /// <param name="forceUpdate">Update all children  ignoring the <see cref="!:IStorable.IsChanged" /> flag.</param>
        /// <typeparam name="T">The type of the objects to store.</typeparam>
        public void Store <T> (IEnumerable <T> storableEnumerable, bool forceUpdate = false) where T : IStorable
        {
            List <T> newDBObjects = new List <T> ();

            lock (mutex) {
                bool success = db.RunInTransaction(() => {
                    foreach (var t in storableEnumerable)
                    {
                        documentUpdated = false;
                        try {
                            var doc = db.GetExistingDocument(t.ID.ToString());
                            if (doc == null)
                            {
                                forceUpdate = true;
                                newDBObjects.Add(t);
                            }
                            StorableNode node;
                            ObjectChangedParser parser = new ObjectChangedParser();
                            parser.Parse(out node, t, Serializer.JsonSettings);

                            if (!forceUpdate)
                            {
                                Update(node);
                            }
                            if (forceUpdate)
                            {
                                DocumentsSerializer.SaveObject(t, db, saveChildren: true);
                            }
                            if (t.ID != Info.ID && (forceUpdate || documentUpdated))
                            {
                                Info.LastModified = DateTime.UtcNow;
                                DocumentsSerializer.SaveObject(Info, db);
                            }
                            foreach (IStorable storable in node.OrphanChildren)
                            {
                                db.GetDocument(DocumentsSerializer.StringFromID(storable.ID, t.ID)).Delete();
                            }
                        } catch (Exception ex) {
                            Log.Exception(ex);
                            return(false);
                        }
                    }
                    return(true);
                });
                if (!success)
                {
                    throw new StorageException(Catalog.GetString("Error storing object from the storage"));
                }
            }
            foreach (var newObject in newDBObjects)
            {
                // FIXME: StorageDeletedEvent should use a collection instead of having to send one event per storable
                App.Current.EventsBroker.Publish(new StorageAddedEvent <T> {
                    Object = newObject, Sender = this
                });
            }
        }
Beispiel #3
0
        void Delete(StorableNode node, Guid rootID)
        {
            Guid id = node.Storable.ID;

            db.GetDocument(DocumentsSerializer.StringFromID(id, rootID)).Delete();
            foreach (StorableNode child in node.Children)
            {
                Delete(child, rootID);
            }
        }
Beispiel #4
0
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            IStorable storable = value as IStorable;

            if (context.SaveChildren && !context.Stack.Contains(value) && !context.Cache.IsCached(storable.ID))
            {
                DocumentsSerializer.SaveObject(storable, context.DB, context);
                context.Cache.AddReference(storable);
            }
            writer.WriteValue(DocumentsSerializer.StringFromID(storable.ID, context.RootID));
        }