Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2498 - 1

2
namespace GMap.NET.CacheProviders
3
{
4
   using System;
5
   using System.Data.SqlClient;
6
   using System.Diagnostics;
7
   using System.IO;
8
   using GMap.NET.MapProviders;
9
 
10
   /// <summary>
11
   /// image cache for ms sql server
12
   /// optimized by mmurfinsimmons@gmail.com
13
   /// </summary>
14
   public class MsSQLPureImageCache : PureImageCache, IDisposable
15
   {
16
      string connectionString = string.Empty;
17
      public string ConnectionString
18
      {
19
         get
20
         {
21
            return connectionString;
22
         }
23
         set
24
         {
25
            if(connectionString != value)
26
            {
27
               connectionString = value;
28
 
29
               if(Initialized)
30
               {
31
                  Dispose();
32
                  Initialize();
33
               }
34
            }
35
         }
36
      }
37
 
38
      SqlCommand cmdInsert;
39
      SqlCommand cmdFetch;
40
      SqlConnection cnGet;
41
      SqlConnection cnSet;
42
 
43
      bool initialized = false;
44
 
45
      /// <summary>
46
      /// is cache initialized
47
      /// </summary>
48
      public bool Initialized
49
      {
50
         get
51
         {
52
            lock(this)
53
            {
54
               return initialized;
55
            }
56
         }
57
         private set
58
         {
59
            lock(this)
60
            {
61
               initialized = value;
62
            }
63
         }
64
      }
65
 
66
      /// <summary>
67
      /// inits connection to server
68
      /// </summary>
69
      /// <returns></returns>
70
      public bool Initialize()
71
      {
72
         lock(this)
73
         {
74
            if(!Initialized)
75
            {
76
               #region prepare mssql & cache table
77
               try
78
               {
79
                  // different connections so the multi-thread inserts and selects don't collide on open readers.
80
                  this.cnGet = new SqlConnection(connectionString);
81
                  this.cnGet.Open();
82
                  this.cnSet = new SqlConnection(connectionString);
83
                  this.cnSet.Open();
84
 
85
                  bool tableexists = false;
86
                  using(SqlCommand cmd = new SqlCommand("select object_id('GMapNETcache')", cnGet))
87
                  {
88
                     object objid = cmd.ExecuteScalar();
89
                     tableexists = (objid != null && objid != DBNull.Value);
90
                  }
91
                  if(!tableexists)
92
                  {
93
                     using(SqlCommand cmd = new SqlCommand(
94
                        "CREATE TABLE [GMapNETcache] ( \n"
95
                  + "   [Type] [int]   NOT NULL, \n"
96
                  + "   [Zoom] [int]   NOT NULL, \n"
97
                  + "   [X]    [int]   NOT NULL, \n"
98
                  + "   [Y]    [int]   NOT NULL, \n"
99
                  + "   [Tile] [image] NOT NULL, \n"
100
                  + "   CONSTRAINT [PK_GMapNETcache] PRIMARY KEY CLUSTERED (Type, Zoom, X, Y) \n"
101
                  + ")", cnGet))
102
                     {
103
                        cmd.ExecuteNonQuery();
104
                     }
105
                  }
106
 
107
                  this.cmdFetch = new SqlCommand("SELECT [Tile] FROM [GMapNETcache] WITH (NOLOCK) WHERE [X]=@x AND [Y]=@y AND [Zoom]=@zoom AND [Type]=@type", cnGet);
108
                  this.cmdFetch.Parameters.Add("@x", System.Data.SqlDbType.Int);
109
                  this.cmdFetch.Parameters.Add("@y", System.Data.SqlDbType.Int);
110
                  this.cmdFetch.Parameters.Add("@zoom", System.Data.SqlDbType.Int);
111
                  this.cmdFetch.Parameters.Add("@type", System.Data.SqlDbType.Int);
112
                  this.cmdFetch.Prepare();
113
 
114
                  this.cmdInsert = new SqlCommand("INSERT INTO [GMapNETcache] ( [X], [Y], [Zoom], [Type], [Tile] ) VALUES ( @x, @y, @zoom, @type, @tile )", cnSet);
115
                  this.cmdInsert.Parameters.Add("@x", System.Data.SqlDbType.Int);
116
                  this.cmdInsert.Parameters.Add("@y", System.Data.SqlDbType.Int);
117
                  this.cmdInsert.Parameters.Add("@zoom", System.Data.SqlDbType.Int);
118
                  this.cmdInsert.Parameters.Add("@type", System.Data.SqlDbType.Int);
119
                  this.cmdInsert.Parameters.Add("@tile", System.Data.SqlDbType.Image); //, calcmaximgsize);
120
                  //can't prepare insert because of the IMAGE field having a variable size.  Could set it to some 'maximum' size?
121
 
122
                  Initialized = true;
123
               }
124
               catch(Exception ex)
125
               {
126
                  this.initialized = false;
127
                  Debug.WriteLine(ex.Message);
128
               }
129
               #endregion
130
            }
131
            return Initialized;
132
         }
133
      }
134
 
135
      #region IDisposable Members
136
      public void Dispose()
137
      {
138
         lock(cmdInsert)
139
         {
140
            if(cmdInsert != null)
141
            {
142
               cmdInsert.Dispose();
143
               cmdInsert = null;
144
            }
145
 
146
            if(cnSet != null)
147
            {
148
               cnSet.Dispose();
149
               cnSet = null;
150
            }
151
         }
152
 
153
         lock(cmdFetch)
154
         {
155
            if(cmdFetch != null)
156
            {
157
               cmdFetch.Dispose();
158
               cmdFetch = null;
159
            }
160
 
161
            if(cnGet != null)
162
            {
163
               cnGet.Dispose();
164
               cnGet = null;
165
            }
166
         }
167
         Initialized = false;
168
      }
169
      #endregion
170
 
171
      #region PureImageCache Members
172
      public bool PutImageToCache(byte[] tile, int type, GPoint pos, int zoom)
173
      {
174
         bool ret = true;
175
         {
176
            if(Initialize())
177
            {
178
               try
179
               {
180
                  lock(cmdInsert)
181
                  {
182
                     cmdInsert.Parameters["@x"].Value = pos.X;
183
                     cmdInsert.Parameters["@y"].Value = pos.Y;
184
                     cmdInsert.Parameters["@zoom"].Value = zoom;
185
                     cmdInsert.Parameters["@type"].Value = type;
186
                     cmdInsert.Parameters["@tile"].Value = tile;
187
                     cmdInsert.ExecuteNonQuery();
188
                  }
189
               }
190
               catch(Exception ex)
191
               {
192
                  Debug.WriteLine(ex.ToString());
193
                  ret = false;
194
                  Dispose();
195
               }
196
            }
197
         }
198
         return ret;
199
      }
200
 
201
      public PureImage GetImageFromCache(int type, GPoint pos, int zoom)
202
      {
203
         PureImage ret = null;
204
         {
205
            if(Initialize())
206
            {
207
               try
208
               {
209
                  object odata = null;
210
                  lock(cmdFetch)
211
                  {
212
                     cmdFetch.Parameters["@x"].Value = pos.X;
213
                     cmdFetch.Parameters["@y"].Value = pos.Y;
214
                     cmdFetch.Parameters["@zoom"].Value = zoom;
215
                     cmdFetch.Parameters["@type"].Value = type;
216
                     odata = cmdFetch.ExecuteScalar();
217
                  }
218
 
219
                  if(odata != null && odata != DBNull.Value)
220
                  {
221
                     byte[] tile = (byte[])odata;
222
                     if(tile != null && tile.Length > 0)
223
                     {
224
                        if(GMapProvider.TileImageProxy != null)
225
                        {
226
                           ret = GMapProvider.TileImageProxy.FromArray(tile);
227
                        }
228
                     }
229
                     tile = null;
230
                  }
231
               }
232
               catch(Exception ex)
233
               {
234
                  Debug.WriteLine(ex.ToString());
235
                  ret = null;
236
                  Dispose();
237
               }
238
            }
239
         }
240
         return ret;
241
      }
242
 
243
      /// <summary>
244
      /// NotImplemented
245
      /// </summary>
246
      /// <param name="date"></param>
247
      /// <param name="type"></param>
248
      /// <returns></returns>
249
      int PureImageCache.DeleteOlderThan(DateTime date, int ? type)
250
      {
251
         throw new NotImplementedException();
252
      }
253
      #endregion
254
   }
255
}