Subversion Repositories Projects

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2498 - 1

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