5
5
\=============================================================================================================================*/
6
6
using System ;
7
7
using System . Collections . Generic ;
8
+ using System . Data ;
8
9
using System . Diagnostics ;
9
10
using System . Linq ;
10
11
using System . Net ;
@@ -19,7 +20,7 @@ namespace OnTopic.Data.Sql {
19
20
| CLASS: SQL DATA READER EXTENSIONS
20
21
\---------------------------------------------------------------------------------------------------------------------------*/
21
22
/// <summary>
22
- /// Extension methods for the <see cref="SqlDataReader "/> class.
23
+ /// Extension methods for the <see cref="IDataReader "/> class.
23
24
/// </summary>
24
25
/// <remarks>
25
26
/// Most of the extensions are optimized for reading the data returned from the <c>GetTopics</c> and <c>GetTopicVersion</c>
@@ -36,10 +37,10 @@ internal static class SqlDataReaderExtensions {
36
37
| METHOD: LOAD TOPIC GRAPH
37
38
\-------------------------------------------------------------------------------------------------------------------------*/
38
39
/// <summary>
39
- /// Given a <see cref="SqlDataReader "/> from a call to the <c>GetTopics</c> stored procedure, will extract a list of
40
+ /// Given a <see cref="IDataReader "/> from a call to the <c>GetTopics</c> stored procedure, will extract a list of
40
41
/// topics and populate their attributes, relationships, and children.
41
42
/// </summary>
42
- /// <param name="reader">The <see cref="SqlDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
43
+ /// <param name="reader">The <see cref="IDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
43
44
/// <param name="referenceTopic">
44
45
/// When loading a single topic or branch, offers a reference topic graph that can be used to ensure that topic references
45
46
/// and relationships, including <see cref="Topic.Parent"/>, are integrated with existing entities.
@@ -56,7 +57,7 @@ internal static class SqlDataReaderExtensions {
56
57
/// thus external references aren't likely to be available.
57
58
/// </param>
58
59
internal static Topic LoadTopicGraph (
59
- this SqlDataReader reader ,
60
+ this IDataReader reader ,
60
61
Topic ? referenceTopic = null ,
61
62
bool ? markDirty = null ,
62
63
bool includeExternalReferences = true
@@ -65,6 +66,7 @@ internal static Topic LoadTopicGraph(
65
66
/*----------------------------------------------------------------------------------------------------------------------
66
67
| Establish topic index
67
68
\---------------------------------------------------------------------------------------------------------------------*/
69
+ var sqlDataReader = reader as SqlDataReader ;
68
70
var topics = referenceTopic is not null ? referenceTopic . GetRootTopic ( ) . GetTopicIndex ( ) : new ( ) ;
69
71
var rootTopicId = - 1 ;
70
72
@@ -101,7 +103,9 @@ internal static Topic LoadTopicGraph(
101
103
102
104
// Loop through each extended attribute record associated with a specific topic
103
105
while ( reader . Read ( ) ) {
104
- reader . SetExtendedAttributes ( topics , markDirty ) ;
106
+ if ( sqlDataReader is not null ) {
107
+ sqlDataReader . SetExtendedAttributes ( topics , markDirty ) ;
108
+ }
105
109
}
106
110
107
111
/*----------------------------------------------------------------------------------------------------------------------
@@ -162,15 +166,15 @@ internal static Topic LoadTopicGraph(
162
166
/// Given the primary topic attributes from the <c>TopicIndex</c> view, establishes a barebones <see cref="Topic"/>
163
167
/// instance and adds it to the <paramref name="topics"/> collection.
164
168
/// </summary>
165
- /// <param name="reader">The <see cref="SqlDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
169
+ /// <param name="reader">The <see cref="IDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
166
170
/// <param name="topics">A <see cref="Dictionary{Int32, Topic}"/> of topics to be loaded.</param>
167
171
/// <param name="markDirty">
168
172
/// Specified whether the target collection value should be marked as dirty, assuming the value changes. By default, it
169
173
/// will be marked dirty if the value is new or has changed from a previous value. By setting this parameter, that
170
174
/// behavior is overwritten to accept whatever value is submitted. This can be used, for instance, to prevent an update
171
175
/// from being persisted to the data store on <see cref="Repositories.ITopicRepository.Save(Topic, Boolean)"/>.
172
176
/// </param>
173
- private static void AddTopic ( this SqlDataReader reader , TopicIndex topics , bool ? markDirty ) {
177
+ private static void AddTopic ( this IDataReader reader , TopicIndex topics , bool ? markDirty ) {
174
178
175
179
/*------------------------------------------------------------------------------------------------------------------------
176
180
| Identify attributes
@@ -217,15 +221,15 @@ private static void AddTopic(this SqlDataReader reader, TopicIndex topics, bool?
217
221
/// Given an attribute record from the <c>AttributeIndex</c> view, finds the associated <see cref="Topic"/> in the
218
222
/// <paramref name="topics"/> collection, and sets the corresponding <see cref="Topic.Attributes"/> value.
219
223
/// </summary>
220
- /// <param name="reader">The <see cref="SqlDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
224
+ /// <param name="reader">The <see cref="IDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
221
225
/// <param name="topics">A <see cref="Dictionary{Int32, Topic}"/> of topics to be loaded.</param>
222
226
/// <param name="markDirty">
223
227
/// Specified whether the target collection value should be marked as dirty, assuming the value changes. By default, it
224
228
/// will be marked dirty if the value is new or has changed from a previous value. By setting this parameter, that
225
229
/// behavior is overwritten to accept whatever value is submitted. This can be used, for instance, to prevent an update
226
230
/// from being persisted to the data store on <see cref="Repositories.ITopicRepository.Save(Topic, Boolean)"/>.
227
231
/// </param>
228
- private static void SetIndexedAttributes ( this SqlDataReader reader , TopicIndex topics , bool ? markDirty ) {
232
+ private static void SetIndexedAttributes ( this IDataReader reader , TopicIndex topics , bool ? markDirty ) {
229
233
230
234
/*------------------------------------------------------------------------------------------------------------------------
231
235
| Identify attributes
@@ -335,15 +339,15 @@ private static void SetExtendedAttributes(this SqlDataReader reader, TopicIndex
335
339
/// Topics can be cross-referenced with each other via a many-to-many relationships. Once the topics are populated in
336
340
/// memory, loop through the data to create these associations.
337
341
/// </remarks>
338
- /// <param name="reader">The <see cref="SqlDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
342
+ /// <param name="reader">The <see cref="IDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
339
343
/// <param name="topics">A <see cref="Dictionary{Int32, Topic}"/> of topics to be loaded.</param>
340
344
/// <param name="markDirty">
341
345
/// Specified whether the target collection value should be marked as dirty, assuming the value changes. By default, it
342
346
/// will be marked dirty if the value is new or has changed from a previous value. By setting this parameter, that
343
347
/// behavior is overwritten to accept whatever value is submitted. This can be used, for instance, to prevent an update
344
348
/// from being persisted to the data store on <see cref="Repositories.ITopicRepository.Save(Topic, Boolean)"/>.
345
349
/// </param>
346
- private static void SetRelationships ( this SqlDataReader reader , TopicIndex topics , bool ? isDirty = false ) {
350
+ private static void SetRelationships ( this IDataReader reader , TopicIndex topics , bool ? isDirty = false ) {
347
351
348
352
/*------------------------------------------------------------------------------------------------------------------------
349
353
| Identify attributes
@@ -392,15 +396,15 @@ private static void SetRelationships(this SqlDataReader reader, TopicIndex topic
392
396
/// Topics can be cross-referenced with each other topics via a one-to-one relationships. Once the topics are populated in
393
397
/// memory, loop through the data to create these associations.
394
398
/// </remarks>
395
- /// <param name="reader">The <see cref="SqlDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
399
+ /// <param name="reader">The <see cref="IDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
396
400
/// <param name="topics">A <see cref="Dictionary{Int32, Topic}"/> of topics to be loaded.</param>
397
401
/// <param name="markDirty">
398
402
/// Specified whether the target collection value should be marked as dirty, assuming the value changes. By default, it
399
403
/// will be marked dirty if the value is new or has changed from a previous value. By setting this parameter, that
400
404
/// behavior is overwritten to accept whatever value is submitted. This can be used, for instance, to prevent an update
401
405
/// from being persisted to the data store on <see cref="Repositories.ITopicRepository.Save(Topic, Boolean)"/>.
402
406
/// </param>
403
- private static void SetReferences ( this SqlDataReader reader , TopicIndex topics , bool ? markDirty ) {
407
+ private static void SetReferences ( this IDataReader reader , TopicIndex topics , bool ? markDirty ) {
404
408
405
409
/*------------------------------------------------------------------------------------------------------------------------
406
410
| Identify attributes
@@ -444,9 +448,9 @@ private static void SetReferences(this SqlDataReader reader, TopicIndex topics,
444
448
/// version history is aggregated per topic to allow topic information to be rolled back to a specific date.While version
445
449
/// content is not exposed directly via the Load() method, the metadata is.
446
450
/// </remarks>
447
- /// <param name="reader">The <see cref="SqlDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
451
+ /// <param name="reader">The <see cref="IDataReader "/> with output from the <c>GetTopics</c> stored procedure.</param>
448
452
/// <param name="topics">A <see cref="Dictionary{Int32, Topic}"/> of topics to be loaded.</param>
449
- private static void SetVersionHistory ( this SqlDataReader reader , TopicIndex topics ) {
453
+ private static void SetVersionHistory ( this IDataReader reader , TopicIndex topics ) {
450
454
451
455
/*------------------------------------------------------------------------------------------------------------------------
452
456
| Identify attributes
@@ -474,9 +478,9 @@ private static void SetVersionHistory(this SqlDataReader reader, TopicIndex topi
474
478
/// <summary>
475
479
/// Retrieves a string value by column name.
476
480
/// </summary>
477
- /// <param name="reader">The <see cref="SqlDataReader "/> object.</param>
481
+ /// <param name="reader">The <see cref="IDataReader "/> object.</param>
478
482
/// <param name="columnName">The name of the column to retrieve the value from.</param>
479
- private static string GetString ( this SqlDataReader reader , string columnName ) =>
483
+ private static string GetString ( this IDataReader reader , string columnName ) =>
480
484
reader . GetString ( reader . GetOrdinal ( columnName ) ) ;
481
485
482
486
/*==========================================================================================================================
@@ -485,9 +489,9 @@ private static string GetString(this SqlDataReader reader, string columnName) =>
485
489
/// <summary>
486
490
/// Retrieves a boolean value by column name.
487
491
/// </summary>
488
- /// <param name="reader">The <see cref="SqlDataReader "/> object.</param>
492
+ /// <param name="reader">The <see cref="IDataReader "/> object.</param>
489
493
/// <param name="columnName">The name of the column to retrieve the value from.</param>
490
- private static bool GetBoolean ( this SqlDataReader reader , string columnName ) =>
494
+ private static bool GetBoolean ( this IDataReader reader , string columnName ) =>
491
495
reader . GetBoolean ( reader . GetOrdinal ( columnName ) ) ;
492
496
493
497
/*==========================================================================================================================
@@ -496,9 +500,9 @@ private static bool GetBoolean(this SqlDataReader reader, string columnName) =>
496
500
/// <summary>
497
501
/// Retrieves an integer value by column name.
498
502
/// </summary>
499
- /// <param name="reader">The <see cref="SqlDataReader "/> object.</param>
503
+ /// <param name="reader">The <see cref="IDataReader "/> object.</param>
500
504
/// <param name="columnName">The name of the column to retrieve the value from.</param>
501
- private static int GetInteger ( this SqlDataReader reader , string columnName ) =>
505
+ private static int GetInteger ( this IDataReader reader , string columnName ) =>
502
506
Int32 . TryParse ( reader . GetValue ( reader . GetOrdinal ( columnName ) ) . ToString ( ) , out var output ) ? output : - 1 ;
503
507
504
508
/*==========================================================================================================================
@@ -507,9 +511,9 @@ private static int GetInteger(this SqlDataReader reader, string columnName) =>
507
511
/// <summary>
508
512
/// Retrieves a <see cref="Topic.Id"/> value by column name.
509
513
/// </summary>
510
- /// <param name="reader">The <see cref="SqlDataReader "/> object.</param>
514
+ /// <param name="reader">The <see cref="IDataReader "/> object.</param>
511
515
/// <param name="columnName">The name of the column to retrieve the value from.</param>
512
- private static int GetTopicId ( this SqlDataReader reader , string columnName = "TopicID" ) =>
516
+ private static int GetTopicId ( this IDataReader reader , string columnName = "TopicID" ) =>
513
517
reader . GetInt32 ( reader . GetOrdinal ( columnName ) ) ;
514
518
515
519
/*==========================================================================================================================
@@ -518,9 +522,9 @@ private static int GetTopicId(this SqlDataReader reader, string columnName = "To
518
522
/// <summary>
519
523
/// Retrieves a <see cref="Topic.Id"/> value by column name, while accepting null values.
520
524
/// </summary>
521
- /// <param name="reader">The <see cref="SqlDataReader "/> object.</param>
525
+ /// <param name="reader">The <see cref="IDataReader "/> object.</param>
522
526
/// <param name="columnName">The name of the column to retrieve the value from.</param>
523
- private static int ? GetNullableTopicId ( this SqlDataReader reader , string columnName = "TopicID" ) =>
527
+ private static int ? GetNullableTopicId ( this IDataReader reader , string columnName = "TopicID" ) =>
524
528
reader . IsDBNull ( reader . GetOrdinal ( columnName ) ) ? null : reader . GetInt32 ( reader . GetOrdinal ( columnName ) ) ;
525
529
526
530
/*==========================================================================================================================
@@ -529,8 +533,8 @@ private static int GetTopicId(this SqlDataReader reader, string columnName = "To
529
533
/// <summary>
530
534
/// Retrieves the version column, with precisions appropriate for setting the <see cref="Topic.VersionHistory"/>.
531
535
/// </summary>
532
- /// <param name="reader">The <see cref="SqlDataReader "/> object.</param>
533
- private static DateTime GetVersion ( this SqlDataReader reader ) =>
536
+ /// <param name="reader">The <see cref="IDataReader "/> object.</param>
537
+ private static DateTime GetVersion ( this IDataReader reader ) =>
534
538
reader . GetDateTime ( reader . GetOrdinal ( "Version" ) ) ;
535
539
536
540
} //Class
0 commit comments