* src/**/*: Flush; syncs to DbLinq r1053. Adds
[mono.git] / mcs / class / System.Data.Linq / src / DbLinq / Data / Linq / DataContext.cs
index 2eaa680c1633f5ef70fc7d1495da4c2abeaec0ce..d00cbd7466b0b271bf4761662b5e0c7064509bf3 100644 (file)
@@ -83,7 +83,26 @@ namespace DbLinq.Data.Linq
         internal IDatabaseContext DatabaseContext { get; private set; }\r
         // /all properties...\r
 \r
-        private readonly EntityTracker entityTracker = new EntityTracker();\r
+        private bool objectTrackingEnabled = true;\r
+        private bool deferredLoadingEnabled = true;\r
+\r
+        private IEntityTracker entityTracker;\r
+        private IEntityTracker EntityTracker\r
+        {\r
+            get\r
+            {\r
+                if (this.entityTracker == null)\r
+                {\r
+                    if (this.ObjectTrackingEnabled)\r
+                        this.entityTracker = new EntityTracker();\r
+                    else\r
+                        this.entityTracker = new DisabledEntityTracker();\r
+                }\r
+                return this.entityTracker;\r
+            }\r
+        }\r
+\r
+\r
 \r
         private IIdentityReaderFactory identityReaderFactory;\r
         private readonly IDictionary<Type, IIdentityReader> identityReaders = new Dictionary<Type, IIdentityReader>();\r
@@ -113,7 +132,25 @@ namespace DbLinq.Data.Linq
         [DbLinqToDo]\r
         public DataContext(string fileOrServerOrConnection, MappingSource mapping)\r
         {\r
-            throw new NotImplementedException();\r
+            if (fileOrServerOrConnection == null)\r
+                throw new ArgumentNullException("fileOrServerOrConnection");\r
+            if (mapping == null)\r
+                throw new ArgumentNullException("mapping");\r
+\r
+            if (File.Exists(fileOrServerOrConnection))\r
+                throw new NotImplementedException("File names not supported.");\r
+\r
+            // Is this a decent server name check?\r
+            // It assumes that the connection string will have at least 2\r
+            // parameters (separated by ';')\r
+            if (!fileOrServerOrConnection.Contains(";"))\r
+                throw new NotImplementedException("Server name not supported.");\r
+\r
+            // Assume it's a connection string...\r
+            IVendor ivendor = GetVendor(fileOrServerOrConnection);\r
+\r
+            IDbConnection dbConnection = ivendor.CreateDbConnection(fileOrServerOrConnection);\r
+            Init(new DatabaseContext(dbConnection), mapping, ivendor);\r
         }\r
 \r
         /// <summary>\r
@@ -327,11 +364,13 @@ namespace DbLinq.Data.Linq
         /// <param name="failureMode"></param>\r
         public virtual void SubmitChanges(ConflictMode failureMode)\r
         {\r
+            if (this.objectTrackingEnabled == false)\r
+                throw new InvalidOperationException("Object tracking is not enabled for the current data context instance.");\r
             using (DatabaseContext.OpenConnection()) //ConnMgr will close connection for us\r
             using (IDatabaseTransaction transaction = DatabaseContext.Transaction())\r
             {\r
                 var queryContext = new QueryContext(this);\r
-                var entityTracks = entityTracker.EnumerateAll().ToList();\r
+                var entityTracks = EntityTracker.EnumerateAll().ToList();\r
                 foreach (var entityTrack in entityTracks)\r
                 {\r
                     switch (entityTrack.EntityState)\r
@@ -411,7 +450,7 @@ namespace DbLinq.Data.Linq
             if (identityKey == null) // if we don't have an entitykey here, it means that the entity has no PK\r
                 return entity;\r
             // even \r
-            var registeredEntityTrack = entityTracker.FindByIdentity(identityKey);\r
+            var registeredEntityTrack = EntityTracker.FindByIdentity(identityKey);\r
             if (registeredEntityTrack != null)\r
                 return registeredEntityTrack.Entity;\r
             return null;\r
@@ -440,18 +479,23 @@ namespace DbLinq.Data.Linq
                 return entity;\r
 \r
             // try to find an already registered entity and return it\r
-            var registeredEntityTrack = entityTracker.FindByIdentity(identityKey);\r
+            var registeredEntityTrack = EntityTracker.FindByIdentity(identityKey);\r
             if (registeredEntityTrack != null)\r
                 return registeredEntityTrack.Entity;\r
 \r
             // otherwise, register and return\r
-            entityTracker.RegisterToWatch(entity, identityKey);\r
+            EntityTracker.RegisterToWatch(entity, identityKey);\r
             return entity;\r
         }\r
 \r
         readonly IDataMapper DataMapper = ObjectFactory.Get<IDataMapper>();\r
         private void SetEntityRefQueries(object entity)\r
         {\r
+            if (!this.deferredLoadingEnabled)\r
+                return;\r
+\r
+            // BUG: This is ignoring External Mappings from XmlMappingSource.\r
+\r
             Type thisType = entity.GetType();\r
             IList<MemberInfo> properties = DataMapper.GetEntityRefAssociations(thisType);\r
 \r
@@ -512,6 +556,11 @@ namespace DbLinq.Data.Linq
         /// <param name="entity"></param>\r
         private void SetEntitySetsQueries(object entity)\r
         {\r
+            if (!this.deferredLoadingEnabled)\r
+                return;\r
+\r
+            // BUG: This is ignoring External Mappings from XmlMappingSource.\r
+\r
             IList<MemberInfo> properties = DataMapper.GetEntitySetAssociations(entity.GetType());\r
             \r
             if (properties.Any()) {\r
@@ -595,7 +644,7 @@ namespace DbLinq.Data.Linq
         /// <param name="entity"></param>\r
         internal void RegisterInsert(object entity)\r
         {\r
-            entityTracker.RegisterToInsert(entity);\r
+            EntityTracker.RegisterToInsert(entity);\r
         }\r
 \r
         /// <summary>\r
@@ -608,14 +657,16 @@ namespace DbLinq.Data.Linq
             if (entity == null)\r
                 throw new ArgumentNullException("entity");\r
 \r
+            if (!this.objectTrackingEnabled)\r
+                return;\r
+\r
             var identityReader = _GetIdentityReader(entity.GetType());\r
             var identityKey = identityReader.GetIdentityKey(entity);\r
-            Console.WriteLine("# identityKey={0}", identityKey == null ? "<null>" : identityKey.ToString());\r
             // if we have no key, we can not watch\r
             if (identityKey == null)\r
                 return;\r
             // register entity\r
-            entityTracker.RegisterToWatch(entity, identityKey);\r
+            EntityTracker.RegisterToWatch(entity, identityKey);\r
         }\r
 \r
         /// <summary>\r
@@ -625,6 +676,8 @@ namespace DbLinq.Data.Linq
         /// <returns></returns>\r
         internal object Register(object entity)\r
         {\r
+            if (! this.objectTrackingEnabled)\r
+                return entity;\r
             var registeredEntity = _GetOrRegisterEntity(entity);\r
             // the fact of registering again clears the modified state, so we're... clear with that\r
             MemberModificationHandler.Register(registeredEntity, Mapping);\r
@@ -639,6 +692,8 @@ namespace DbLinq.Data.Linq
         /// <param name="entityOriginalState"></param>\r
         internal void RegisterUpdate(object entity, object entityOriginalState)\r
         {\r
+            if (!this.objectTrackingEnabled)\r
+                return;\r
             RegisterUpdate(entity);\r
             MemberModificationHandler.Register(entity, entityOriginalState, Mapping);\r
         }\r
@@ -649,6 +704,8 @@ namespace DbLinq.Data.Linq
         /// <param name="entity"></param>\r
         internal void RegisterUpdateAgain(object entity)\r
         {\r
+            if (!this.objectTrackingEnabled)\r
+                return;\r
             MemberModificationHandler.ClearModified(entity, Mapping);\r
         }\r
 \r
@@ -658,7 +715,9 @@ namespace DbLinq.Data.Linq
         /// <param name="entity"></param>\r
         internal void RegisterDelete(object entity)\r
         {\r
-            entityTracker.RegisterToDelete(entity);\r
+            if (!this.objectTrackingEnabled)\r
+                return;\r
+            EntityTracker.RegisterToDelete(entity);\r
         }\r
 \r
         /// <summary>\r
@@ -667,7 +726,9 @@ namespace DbLinq.Data.Linq
         /// <param name="entity"></param>\r
         internal void UnregisterDelete(object entity)\r
         {\r
-            entityTracker.RegisterDeleted(entity);\r
+            if (!this.objectTrackingEnabled)\r
+                return;\r
+            EntityTracker.RegisterDeleted(entity);\r
         }\r
 \r
         #endregion\r
@@ -681,7 +742,7 @@ namespace DbLinq.Data.Linq
             var inserts = new List<object>();\r
             var updates = new List<object>();\r
             var deletes = new List<object>();\r
-            foreach (var entityTrack in entityTracker.EnumerateAll())\r
+            foreach (var entityTrack in EntityTracker.EnumerateAll())\r
             {\r
                 switch (entityTrack.EntityState)\r
                 {\r
@@ -746,7 +807,11 @@ namespace DbLinq.Data.Linq
         /// Gets or sets the load options\r
         /// </summary>\r
         [DbLinqToDo]\r
-        public DataLoadOptions LoadOptions { get; set; }\r
+        public DataLoadOptions LoadOptions \r
+        {\r
+            get { throw new NotImplementedException(); }\r
+            set { throw new NotImplementedException(); }\r
+        }\r
 \r
         public DbTransaction Transaction { get; set; }\r
 \r
@@ -856,12 +921,15 @@ namespace DbLinq.Data.Linq
             }\r
         }\r
 \r
-\r
-        [DbLinqToDo]\r
         public bool ObjectTrackingEnabled\r
         {\r
-            get { throw new NotImplementedException(); }\r
-            set { throw new NotImplementedException(); }\r
+            get { return this.objectTrackingEnabled; }\r
+            set \r
+            {\r
+                if (this.entityTracker != null && value != this.objectTrackingEnabled)\r
+                    throw new InvalidOperationException("Data context options cannot be modified after results have been returned from a query.");\r
+                this.objectTrackingEnabled = value;\r
+            }\r
         }\r
 \r
         [DbLinqToDo]\r
@@ -871,11 +939,15 @@ namespace DbLinq.Data.Linq
             set { throw new NotImplementedException(); }\r
         }\r
 \r
-        [DbLinqToDo]\r
         public bool DeferredLoadingEnabled\r
         {\r
-            get { throw new NotImplementedException(); }\r
-            set { throw new NotImplementedException(); }\r
+            get { return this.deferredLoadingEnabled; }\r
+            set\r
+            {\r
+                if (this.entityTracker != null && value != this.deferredLoadingEnabled)\r
+                    throw new InvalidOperationException("Data context options cannot be modified after results have been returned from a query.");\r
+                this.deferredLoadingEnabled = value;\r
+            }\r
         }\r
 \r
         [DbLinqToDo]\r