/// <summary> /// Insert a new document to this collection. Document Id must be a new value in collection - Returns document Id /// </summary> public virtual BsonValue Insert(T document) { if (document == null) { throw new ArgumentNullException("document"); } // set an id value if document object needs this.Database.Mapper.SetAutoId(document, this.GetBsonCollection()); var doc = this.Database.Mapper.ToDocument(document); BsonValue id; // add ObjectId to _id if _id not found if (!doc.RawValue.TryGetValue("_id", out id)) { id = doc["_id"] = ObjectId.NewObjectId(); } // test if _id is a valid type if (id.IsNull || id.IsMinValue || id.IsMaxValue) { throw LiteException.InvalidDataType("_id", id); } // serialize object var bytes = BsonSerializer.Serialize(doc); this.Database.Transaction.Begin(); try { var col = this.GetCollectionPage(true); // storage in data pages - returns dataBlock address var dataBlock = this.Database.Data.Insert(col, bytes); // store id in a PK index [0 array] var pk = this.Database.Indexer.AddNode(col.PK, id); // do links between index <-> data block pk.DataBlock = dataBlock.Position; dataBlock.IndexRef[0] = pk.Position; // for each index, insert new IndexNode foreach (var index in col.GetIndexes(false)) { var key = doc.Get(index.Field); var node = this.Database.Indexer.AddNode(index, key); // point my index to data object node.DataBlock = dataBlock.Position; // point my dataBlock dataBlock.IndexRef[index.Slot] = node.Position; } this.Database.Transaction.Commit(); return(id); } catch { this.Database.Transaction.Rollback(); throw; } }