1
+ using Analogy . Interfaces ;
2
+ using Analogy . LogViewer . LiteDB . Properties ;
3
+ using Analogy . LogViewer . Template . Managers ;
4
+ using LiteDB ;
5
+ using Microsoft . Extensions . Logging ;
6
+ using Newtonsoft . Json . Linq ;
7
+ using System ;
8
+ using System . Collections ;
9
+ using System . Collections . Generic ;
10
+ using System . Data ;
11
+ using System . Drawing ;
12
+ using System . IO ;
13
+ using System . Linq ;
14
+ using System . Reflection ;
15
+ using System . Text ;
16
+ using System . Threading ;
17
+ using System . Threading . Tasks ;
18
+
19
+ namespace Analogy . LogViewer . LiteDB . IAnalogy
20
+ {
21
+ public class LiteDBDataProvider : Template . OfflineDataProvider
22
+ {
23
+ public override Guid Id { get ; set ; } = new Guid ( "25b2b926-47f8-4f13-8db8-0803f8829eba" ) ;
24
+ public override Image ? LargeImage { get ; set ; } = Resources . Analogy_image_32x32 ;
25
+ public override Image ? SmallImage { get ; set ; } = Resources . Analogy_image_16x16 ;
26
+
27
+ public override string ? OptionalTitle { get ; set ; } = "LiteDB db browser" ;
28
+ public override string FileOpenDialogFilters { get ; set ; } = "LiteDB db file (*.db)|*.db" ;
29
+ public override IEnumerable < string > SupportFormats { get ; set ; } = new [ ] { "*.db" } ;
30
+ public override string ? InitialFolderFullPath { get ; set ; } = Environment . CurrentDirectory ;
31
+ public override IEnumerable < ( string OriginalHeader , string ReplacementHeader ) > GetReplacementHeaders ( )
32
+ => Array . Empty < ( string , string ) > ( ) ;
33
+ public string Collection { get ; set ; } = "" ;
34
+ public string Sql { get ; set ; } = "" ;
35
+ public const int RESULTLIMIT = 1000 ;
36
+ public bool LimitExceeded { get ; set ; }
37
+ public override Task InitializeDataProvider ( ILogger logger )
38
+ {
39
+ //do some initialization for this provider
40
+ return base . InitializeDataProvider ( logger ) ;
41
+ }
42
+
43
+ public override IEnumerable < AnalogyLogMessagePropertyName > HideExistingColumns ( )
44
+ {
45
+ yield return AnalogyLogMessagePropertyName . Date ;
46
+ yield return AnalogyLogMessagePropertyName . Text ;
47
+ yield return AnalogyLogMessagePropertyName . Level ;
48
+ yield return AnalogyLogMessagePropertyName . Class ;
49
+ yield return AnalogyLogMessagePropertyName . Source ;
50
+ yield return AnalogyLogMessagePropertyName . User ;
51
+ yield return AnalogyLogMessagePropertyName . Class ;
52
+ yield return AnalogyLogMessagePropertyName . ProcessId ;
53
+ yield return AnalogyLogMessagePropertyName . ThreadId ;
54
+ yield return AnalogyLogMessagePropertyName . MachineName ;
55
+ yield return AnalogyLogMessagePropertyName . MethodName ;
56
+ yield return AnalogyLogMessagePropertyName . LineNumber ;
57
+ yield return AnalogyLogMessagePropertyName . RawText ;
58
+ yield return AnalogyLogMessagePropertyName . RawTextType ;
59
+ yield return AnalogyLogMessagePropertyName . Id ;
60
+ }
61
+
62
+ public override void MessageOpened ( IAnalogyLogMessage message )
63
+ {
64
+ //nop
65
+ }
66
+
67
+ public override async Task < IEnumerable < IAnalogyLogMessage > > Process ( string fileName , CancellationToken token , ILogMessageCreatedHandler messagesHandler )
68
+ {
69
+ var messages = new List < IAnalogyLogMessage > ( ) ;
70
+ ConnectionString connection = new ConnectionString ( ) ;
71
+ connection . Connection = ConnectionType . Direct ;
72
+
73
+ connection . Filename = fileName ;
74
+ connection . ReadOnly = true ;
75
+ connection . Upgrade = false ;
76
+ connection . Password = null ;
77
+ connection . InitialSize = 0 ;
78
+ var _db = new LiteDatabase ( connection ) ;
79
+ try
80
+ {
81
+ // force open database
82
+ var uv = _db . UserVersion ;
83
+ foreach ( var col in _db . GetCollectionNames ( ) )
84
+ {
85
+ var bd = new BsonDocument ( ) ;
86
+ Sql = $ "SELECT $ FROM { col } ;";
87
+ var sql = new StringReader ( Sql . Trim ( ) ) ;
88
+
89
+ while ( sql . Peek ( ) >= 0 && _db != null )
90
+ {
91
+ using var reader = _db . Execute ( sql , bd ) ;
92
+ var items = ReadResult ( reader ) ;
93
+ var sb = new StringBuilder ( ) ;
94
+ using ( var writer = new StringWriter ( sb ) )
95
+ {
96
+ var json = new JsonWriter ( writer ) { Pretty = true , Indent = 2 , } ;
97
+ AnalogyLogMessage m = new AnalogyLogMessage ( ) ;
98
+ m . Source = $ "Table: { col } ";
99
+ foreach ( var item in items )
100
+ {
101
+ var keys = ( ( BsonDocument ) item ) . Keys . ToList ( ) ;
102
+ var values = ( ( BsonDocument ) item ) . Values . ToList ( ) ;
103
+
104
+ for ( var i = 0 ; i < keys . Count ; i ++ )
105
+ {
106
+ var key = keys [ i ] ;
107
+ var itm = values [ i ] ;
108
+ sb . AppendLine ( $ "{ key } : { itm } ") ;
109
+ m . AddOrReplaceAdditionalProperty ( key , itm . ToString ( ) ) ;
110
+ }
111
+ json . Serialize ( item ) ;
112
+ m . Text = sb . ToString ( ) ;
113
+ messages . Add ( m ) ;
114
+ messagesHandler . AppendMessage ( m , fileName ) ;
115
+ }
116
+
117
+ m . RawText = json . ToString ( ) ;
118
+ m . RawTextType = AnalogyRowTextType . JSON ;
119
+ sb . AppendLine ( ) ;
120
+ }
121
+ }
122
+ }
123
+ }
124
+ catch ( Exception ex )
125
+ {
126
+ _db ? . Dispose ( ) ;
127
+ }
128
+ return messages ;
129
+ }
130
+ public List < BsonValue > ReadResult ( IBsonDataReader reader )
131
+ {
132
+ var result = new List < BsonValue > ( ) ;
133
+ this . LimitExceeded = false ;
134
+ this . Collection = reader . Collection ;
135
+
136
+ var index = 0 ;
137
+ var hasLimit = this . Sql . IndexOf ( "LIMIT " , StringComparison . OrdinalIgnoreCase ) >= 0 ;
138
+
139
+ while ( reader . Read ( ) )
140
+ {
141
+ if ( index ++ >= RESULTLIMIT && hasLimit == false )
142
+ {
143
+ this . LimitExceeded = true ;
144
+ break ;
145
+ }
146
+
147
+ result . Add ( reader . Current ) ;
148
+ }
149
+
150
+ return result ;
151
+ }
152
+ }
153
+ }
0 commit comments