Welcome to mirror list, hosted at ThFree Co, Russian Federation.

DbProviderServices.cs « Common « Data « System « System.Data.Entity « referencesource « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 6647b41a6157870c08858debccbe225550e6a51a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
//------------------------------------------------------------------------------
// <copyright file="DbProviderServices.cs" company="Microsoft">
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//
// @owner  [....]
// @backupOwner [....]
//------------------------------------------------------------------------------

using System.Data.SqlClient;

namespace System.Data.Common
{
    using System.Data.Common.CommandTrees;
    using System.Data.Entity;
    using System.Data.Metadata.Edm;
    using System.Data.Spatial;
    using System.Diagnostics;
    using System.IO;
    using System.Reflection;
    using System.Xml;

    /// <summary>
    /// The factory for building command definitions; use the type of this object
    /// as the argument to the IServiceProvider.GetService method on the provider
    /// factory;
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
    [CLSCompliant(false)]
    abstract public class DbProviderServices
    {
        /// <summary>
        /// Create a Command Definition object given a command tree.
        /// </summary>
        /// <param name="commandTree">command tree for the statement</param>
        /// <returns>an exectable command definition object</returns>
        /// <remarks>
        /// This method simply delegates to the provider's implementation of CreateDbCommandDefinition.
        /// </remarks>
        public DbCommandDefinition CreateCommandDefinition(DbCommandTree commandTree)
        {
            EntityUtil.CheckArgumentNull(commandTree, "commandTree");
            ValidateDataSpace(commandTree);
            StoreItemCollection storeMetadata = (StoreItemCollection)commandTree.MetadataWorkspace.GetItemCollection(DataSpace.SSpace);
            Debug.Assert(storeMetadata.StoreProviderManifest != null, "StoreItemCollection has null StoreProviderManifest?");
            
            return CreateDbCommandDefinition(storeMetadata.StoreProviderManifest, commandTree);
        }

        /// <summary>
        /// Create a Command Definition object given a command tree.
        /// </summary>
        /// <param name="commandTree">command tree for the statement</param>
        /// <returns>an exectable command definition object</returns>
        /// <remarks>
        /// This method simply delegates to the provider's implementation of CreateDbCommandDefinition.
        /// </remarks>
        public DbCommandDefinition CreateCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)
        {
            try
            {
                return CreateDbCommandDefinition(providerManifest, commandTree);
            }
            catch (ProviderIncompatibleException)
            {
                throw;
            }
            catch (Exception e)
            {
                if (EntityUtil.IsCatchableExceptionType(e))
                {
                    throw EntityUtil.ProviderIncompatible(Strings.ProviderDidNotCreateACommandDefinition, e);
                }
                throw;
            }
        }

        /// <summary>
        /// Create a Command Definition object, given the provider manifest and command tree
        /// </summary>
        /// <param name="connection">provider manifest previously retrieved from the store provider</param>
        /// <param name="commandTree">command tree for the statement</param>
        /// <returns>an exectable command definition object</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
        protected abstract DbCommandDefinition CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree);

        /// <summary>
        /// Ensures that the data space of the specified command tree is the target (S-) space
        /// </summary>
        /// <param name="commandTree">The command tree for which the data space should be validated</param>
        internal virtual void ValidateDataSpace(DbCommandTree commandTree)
        {
            Debug.Assert(commandTree != null, "Ensure command tree is non-null before calling ValidateDataSpace");

            if (commandTree.DataSpace != DataSpace.SSpace)
            {
                throw EntityUtil.ProviderIncompatible(Strings.ProviderRequiresStoreCommandTree);
            }
        }

        /// <summary>
        /// Create a DbCommand object given a command tree.
        /// </summary>
        /// <param name="commandTree">command tree for the statement</param>
        /// <returns>a command object</returns>
        internal virtual DbCommand CreateCommand(DbCommandTree commandTree) {
            DbCommandDefinition commandDefinition = CreateCommandDefinition(commandTree);
            DbCommand command = commandDefinition.CreateCommand();
            return command;
        }

        /// <summary>
        /// Create the default DbCommandDefinition object based on the prototype command
        /// This method is intended for provider writers to build a default command definition
        /// from a command. 
        /// Note: This will clone the prototype
        /// </summary>
        /// <param name="prototype">the prototype command</param>
        /// <returns>an executable command definition object</returns>
        public virtual DbCommandDefinition CreateCommandDefinition(DbCommand prototype) {
            return DbCommandDefinition.CreateCommandDefinition(prototype);
        }
                
        /// <summary>
        /// Retrieve the provider manifest token based on the specified connection.
        /// </summary>
        /// <param name="connection">The connection for which the provider manifest token should be retrieved.</param>
        /// <returns>
        /// The provider manifest token that describes the specified connection, as determined by the provider.
        /// </returns>
        /// <remarks>
        /// This method simply delegates to the provider's implementation of GetDbProviderManifestToken.
        /// </remarks>
        public string GetProviderManifestToken(DbConnection connection) {
            try
            {
                string providerManifestToken = GetDbProviderManifestToken(connection);
                if (providerManifestToken == null)
                {
                    throw EntityUtil.ProviderIncompatible(Strings.ProviderDidNotReturnAProviderManifestToken);
                }
                return providerManifestToken;
            }
            catch (ProviderIncompatibleException)
            {
                throw;
            }
            catch (Exception e)
            {
                if (EntityUtil.IsCatchableExceptionType(e))
                {
                    throw EntityUtil.ProviderIncompatible(Strings.ProviderDidNotReturnAProviderManifestToken, e);
                }
                throw;
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
        protected abstract string GetDbProviderManifestToken(DbConnection connection);

        public DbProviderManifest GetProviderManifest(string manifestToken) {
            try
            {
                DbProviderManifest providerManifest = GetDbProviderManifest(manifestToken);
                if (providerManifest == null)
                {
                    throw EntityUtil.ProviderIncompatible(Strings.ProviderDidNotReturnAProviderManifest);
                }

                return providerManifest;
            }
            catch (ProviderIncompatibleException)
            {
                throw;
            }
            catch (Exception e)
            {
                if (EntityUtil.IsCatchableExceptionType(e)) {
                    throw EntityUtil.ProviderIncompatible(System.Data.Entity.Strings.ProviderDidNotReturnAProviderManifest, e);
                }
                throw;
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
        protected abstract DbProviderManifest GetDbProviderManifest(string manifestToken);

        public DbSpatialDataReader GetSpatialDataReader(DbDataReader fromReader, string manifestToken)
        {
            try
            {
                DbSpatialDataReader spatialReader = GetDbSpatialDataReader(fromReader, manifestToken);
                if (spatialReader == null)
                {
                    throw EntityUtil.ProviderIncompatible(Strings.ProviderDidNotReturnSpatialServices);
                }

                return spatialReader;
            }
            catch (ProviderIncompatibleException)
            {
                throw;
            }
            catch (Exception e)
            {
                if (EntityUtil.IsCatchableExceptionType(e))
                {
                    throw EntityUtil.ProviderIncompatible(System.Data.Entity.Strings.ProviderDidNotReturnSpatialServices, e);
                }
                throw;
            }
        }

        public DbSpatialServices GetSpatialServices(string manifestToken)
        {
            try
            {
                DbSpatialServices spatialServices = DbGetSpatialServices(manifestToken);
                if (spatialServices == null)
                {
                    throw EntityUtil.ProviderIncompatible(Strings.ProviderDidNotReturnSpatialServices);
                }

                return spatialServices;
            }
            catch (ProviderIncompatibleException)
            {
                throw;
            }
            catch (Exception e)
            {
                if (EntityUtil.IsCatchableExceptionType(e))
                {
                    throw EntityUtil.ProviderIncompatible(System.Data.Entity.Strings.ProviderDidNotReturnSpatialServices, e);
                }
                throw;
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
        protected virtual DbSpatialDataReader GetDbSpatialDataReader(DbDataReader fromReader, string manifestToken)
        {
            // Must be a virtual method; abstract would break previous implementors of DbProviderServices
            throw EntityUtil.ProviderIncompatible(Strings.ProviderDidNotReturnSpatialServices);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
        protected virtual DbSpatialServices DbGetSpatialServices(string manifestToken)
        {
            // Must be a virtual method; abstract would break previous implementors of DbProviderServices
            throw EntityUtil.ProviderIncompatible(Strings.ProviderDidNotReturnSpatialServices);
        }

        internal void SetParameterValue(DbParameter parameter, TypeUsage parameterType, object value)
        {
            Debug.Assert(parameter != null, "Validate parameter before calling SetParameterValue");
            Debug.Assert(parameterType != null, "Validate parameterType before calling SetParameterValue");

            this.SetDbParameterValue(parameter, parameterType, value);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
        protected virtual void SetDbParameterValue(DbParameter parameter, TypeUsage parameterType, object value)
        {
            EntityUtil.CheckArgumentNull(parameter, "parameter");
            EntityUtil.CheckArgumentNull(parameterType, "parameterType");

            parameter.Value = value;
        }

        /// <summary>
        /// Create an instance of DbProviderServices based on the supplied DbConnection
        /// </summary>
        /// <param name="connection">The DbConnection to use</param>
        /// <returns>An instance of DbProviderServices</returns>
        public static DbProviderServices GetProviderServices(DbConnection connection) {
            return GetProviderServices(GetProviderFactory(connection));
        }

        internal static DbProviderFactory GetProviderFactory(string providerInvariantName)
        {
            EntityUtil.CheckArgumentNull(providerInvariantName, "providerInvariantName");
            DbProviderFactory factory;
            try
            {
                factory = DbProviderFactories.GetFactory(providerInvariantName);
            }
            catch (ArgumentException e)
            {
                throw EntityUtil.Argument(Strings.EntityClient_InvalidStoreProvider, e);
            }
            return factory;
        }

        /// <summary>
        /// Retrieve the DbProviderFactory based on the specified DbConnection
        /// </summary>
        /// <param name="connection">The DbConnection to use</param>
        /// <returns>An instance of DbProviderFactory</returns>
        public static DbProviderFactory GetProviderFactory(DbConnection connection)
        {
            EntityUtil.CheckArgumentNull(connection, "connection");
            DbProviderFactory factory = DbProviderFactories.GetFactory(connection);
            if (factory == null)
            {
                throw EntityUtil.ProviderIncompatible(System.Data.Entity.Strings.EntityClient_ReturnedNullOnProviderMethod(
                        "get_ProviderFactory",
                        connection.GetType().ToString()));
            }
            Debug.Assert(factory != null, "Should have thrown on null"); 
            return factory;
        }

        internal static DbProviderServices GetProviderServices(DbProviderFactory factory) {
            EntityUtil.CheckArgumentNull(factory, "factory");

            // Special case SQL client so that it will work with System.Data from .NET 4.0 even without
            // a binding redirect.
            if (factory is SqlClientFactory)
            {
                return SqlProviderServices.Instance;
            }

            IServiceProvider serviceProvider = factory as IServiceProvider;
            if (serviceProvider == null) {
                throw EntityUtil.ProviderIncompatible(System.Data.Entity.Strings.EntityClient_DoesNotImplementIServiceProvider(
                    factory.GetType().ToString()));
            }

            DbProviderServices providerServices = serviceProvider.GetService(typeof(DbProviderServices)) as DbProviderServices;
            if (providerServices == null) {
                throw EntityUtil.ProviderIncompatible(
                    System.Data.Entity.Strings.EntityClient_ReturnedNullOnProviderMethod(
                        "GetService",
                        factory.GetType().ToString()));
            }

            return providerServices;
        }

        /// <summary>
        /// Return an XML reader which represents the CSDL description
        /// </summary>
        /// <returns>An XmlReader that represents the CSDL description</returns>
        internal static XmlReader GetConceptualSchemaDefinition(string csdlName) {
            return DbProviderServices.GetXmlResource("System.Data.Resources.DbProviderServices." + csdlName + ".csdl");
        }

        internal static XmlReader GetXmlResource(string resourceName) {
            Assembly executingAssembly = Assembly.GetExecutingAssembly();
            Stream stream = executingAssembly.GetManifestResourceStream(resourceName);
            return XmlReader.Create(stream, null, resourceName);
        }

        /// <summary>
        /// Generates a DDL script which creates schema objects (tables, primary keys, foreign keys) 
        /// based on the contents of the storeItemCollection and targeted for the version of the backend corresponding to 
        /// the providerManifestToken.
        /// Individual statements should be separated using database-specific DDL command separator. 
        /// It is expected that the generated script would be executed in the context of existing database with 
        /// sufficient permissions, and it should not include commands to create the database, but it may include 
        /// commands to create schemas and other auxiliary objects such as sequences, etc.
        /// </summary>
        /// <param name="providerManifestToken">The provider manifest token identifying the target version</param>
        /// <param name="storeItemCollection">The collection of all store items based on which the script should be created</param>
        /// <returns>
        /// A DDL script which creates schema objects based on contents of storeItemCollection 
        /// and targeted for the version of the backend corresponding to the providerManifestToken.
        /// </returns>
        public string CreateDatabaseScript(string providerManifestToken, StoreItemCollection storeItemCollection)
        {
           return DbCreateDatabaseScript(providerManifestToken, storeItemCollection);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
        protected virtual string DbCreateDatabaseScript(string providerManifestToken, StoreItemCollection storeItemCollection)
        {
            throw EntityUtil.ProviderIncompatible(Strings.ProviderDoesNotSupportCreateDatabaseScript);
        }

        /// <summary>
        /// Creates a database indicated by connection and creates schema objects 
        /// (tables, primary keys, foreign keys) based on the contents of storeItemCollection. 
        /// </summary>
        /// <param name="connection">Connection to a non-existent database that needs to be created 
        /// and be populated with the store objects indicated by the storeItemCollection</param>
        /// <param name="commandTimeout">Execution timeout for any commands needed to create the database.</param>
        /// <param name="storeItemCollection">The collection of all store items based on which the script should be created<</param>
        public void CreateDatabase(DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection)
        {
            DbCreateDatabase(connection, commandTimeout, storeItemCollection);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
        protected virtual void DbCreateDatabase(DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection)
        {
            throw EntityUtil.ProviderIncompatible(Strings.ProviderDoesNotSupportCreateDatabase);
        }

        /// <summary>
        /// Returns a value indicating whether given database exists on the server 
        /// and/or whether schema objects contained in teh storeItemCollection have been created.
        /// If the provider can deduct the database only based on the connection, they do not need
        /// to additionally verify all elements of the storeItemCollection.
        /// </summary>
        /// <param name="connection">Connection to a database whose existence is checked by this method</param>
        /// <param name="commandTimeout">Execution timeout for any commands needed to determine the existence of the database</param>
        /// <param name="storeItemCollection">The collection of all store items contained in the database 
        /// whose existence is determined by this method<</param>
        /// <returns>Whether the database indicated by the connection and the storeItemCollection exist</returns>
        public bool DatabaseExists(DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection)
        {
            return DbDatabaseExists(connection, commandTimeout, storeItemCollection);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
        protected virtual bool DbDatabaseExists(DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection)
        {
            throw EntityUtil.ProviderIncompatible(Strings.ProviderDoesNotSupportDatabaseExists);
        }


        /// <summary>
        /// Deletes all store objects specified in the store item collection from the database and the database itself.
        /// </summary>
        /// <param name="connection">Connection to an existing database that needs to be deleted</param>
        /// <param name="commandTimeout">Execution timeout for any commands needed to delete the database</param>
        /// <param name="storeItemCollection">The collection of all store items contained in the database that should be deleted<</param>
        public void DeleteDatabase(DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection)
        {
            DbDeleteDatabase(connection, commandTimeout, storeItemCollection);
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "Db")]
        protected virtual void DbDeleteDatabase(DbConnection connection, int? commandTimeout, StoreItemCollection storeItemCollection)
        {
            throw EntityUtil.ProviderIncompatible(Strings.ProviderDoesNotSupportDeleteDatabase);
        }
    }

}