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