2 // System.Web.SessionState.SessionSQLServerHandler
5 // Jackson Harper (jackson@ximian.com)
7 // (C) 2003 Novell, Inc. (http://www.novell.com), All rights reserved
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System
.Reflection
;
35 using System
.Configuration
;
36 using System
.Collections
.Specialized
;
38 namespace System
.Web
.SessionState
{
40 internal class SessionSQLServerHandler
: ISessionHandler
42 const int DefTimeout
= 600;
44 private Type cncType
= null;
45 private IDbConnection cnc
= null;
46 private SessionConfig config
;
48 public void Dispose ()
56 public void Init (SessionStateModule module
, HttpApplication context
, SessionConfig config
)
58 string connectionTypeName
;
59 string providerAssemblyName
;
64 GetConnectionData (out providerAssemblyName
, out connectionTypeName
, out cncString
);
65 if (cncType
== null) {
66 Assembly dbAssembly
= Assembly
.Load (providerAssemblyName
);
67 cncType
= dbAssembly
.GetType (connectionTypeName
, true);
68 if (!typeof (IDbConnection
).IsAssignableFrom (cncType
))
69 throw new ApplicationException ("The type '" + cncType
+
70 "' does not implement IDB Connection.\n" +
71 "Check 'DbConnectionType' in server.exe.config.");
74 cnc
= (IDbConnection
) Activator
.CreateInstance (cncType
);
75 cnc
.ConnectionString
= cncString
;
78 } catch (Exception exc
) {
84 public void UpdateHandler (HttpContext context
, SessionStateModule module
)
86 if (context
.Session
== null || context
.Session
.IsReadOnly
)
89 string id
= context
.Session
.SessionID
;
90 SessionDictionary dict
= context
.Session
.SessionDictionary
;
92 UpdateSession (id
, dict
);
95 public HttpSessionState
UpdateContext (HttpContext context
, SessionStateModule module
,
96 bool required
, bool read_only
, ref bool isNew
)
101 HttpSessionState session
= null;
102 string id
= SessionId
.Lookup (context
.Request
, config
.CookieLess
);
105 session
= SelectSession (id
, read_only
);
110 id
= SessionId
.Create (module
.Rng
);
111 session
= new HttpSessionState (id
, new SessionDictionary (),
112 HttpApplicationFactory
.ApplicationState
.SessionObjects
, config
.Timeout
,
113 true, config
.CookieLess
, SessionStateMode
.SQLServer
, read_only
);
115 InsertSession (session
, config
.Timeout
);
120 private void GetConnectionData (out string providerAssembly
,
121 out string cncTypeName
, out string cncString
)
123 providerAssembly
= null;
127 NameValueCollection config
= ConfigurationSettings
.AppSettings
as NameValueCollection
;
128 if (config
!= null) {
129 foreach (string s
in config
.Keys
) {
130 if (0 == String
.Compare ("StateDBProviderAssembly", s
, true)) {
131 providerAssembly
= config
[s
];
132 } else if (0 == String
.Compare ("StateDBConnectionType", s
, true)) {
133 cncTypeName
= config
[s
];
138 cncString
= this.config
.SqlConnectionString
;
140 if (providerAssembly
== null || providerAssembly
== String
.Empty
)
141 providerAssembly
= "Npgsql.dll";
143 if (cncTypeName
== null || cncTypeName
== String
.Empty
)
144 cncTypeName
= "Npgsql.NpgsqlConnection";
146 if (cncString
== null || cncString
== String
.Empty
)
147 cncString
= "SERVER=127.0.0.1;USER ID=monostate;PASSWORD=monostate;dbname=monostate";
150 private HttpSessionState
SelectSession (string id
, bool read_only
)
152 HttpSessionState session
= null;
153 IDbCommand command
= cnc
.CreateCommand();
156 string select = "SELECT * from aspstatetempsessions WHERE SessionID = :SessionID";
158 command
.CommandText
= select;
160 command
.Parameters
.Add (CreateParam (command
, DbType
.String
, ":SessionID", id
));
163 reader
= command
.ExecuteReader ();
168 SessionDictionary dict
;
169 HttpStaticObjectsCollection sobjs
;
171 dict
= SessionDictionary
.FromByteArray (ReadBytes (reader
, reader
.FieldCount
-1));
172 sobjs
= HttpStaticObjectsCollection
.FromByteArray (ReadBytes (reader
, reader
.FieldCount
-2));
174 session
= new HttpSessionState (id
, dict
, sobjs
, 100, false, config
.CookieLess
,
175 SessionStateMode
.SQLServer
, read_only
);
182 private void InsertSession (HttpSessionState session
, int timeout
)
184 IDbCommand command
= cnc
.CreateCommand ();
185 IDataParameterCollection param
;
187 string insert
= "INSERT INTO ASPStateTempSessions VALUES " +
188 "(:SessionID, :Created, :Expires, :Timeout, :StaticObjectsData, :SessionData)";
190 command
.CommandText
= insert
;
192 param
= command
.Parameters
;
193 param
.Add (CreateParam (command
, DbType
.String
, ":SessionID", session
.SessionID
));
194 param
.Add (CreateParam (command
, DbType
.DateTime
, ":Created", DateTime
.Now
));
195 param
.Add (CreateParam (command
, DbType
.DateTime
, ":Expires", Tommorow ()));
196 param
.Add (CreateParam (command
, DbType
.Int32
, ":Timeout", timeout
));
197 param
.Add (CreateParam (command
, DbType
.Binary
, ":StaticObjectsData",
198 session
.StaticObjects
.ToByteArray ()));
199 param
.Add (CreateParam (command
, DbType
.Binary
, ":SessionData",
200 session
.SessionDictionary
.ToByteArray ()));
202 command
.ExecuteNonQuery ();
205 private void UpdateSession (string id
, SessionDictionary dict
)
207 IDbCommand command
= cnc
.CreateCommand ();
208 IDataParameterCollection param
;
210 string update
= "UPDATE ASPStateTempSessions SET " +
211 "SessionData = :SessionData WHERE SessionId = :SessionID";
213 command
.CommandText
= update
;
215 param
= command
.Parameters
;
216 param
.Add (CreateParam (command
, DbType
.String
, ":SessionID", id
));
217 param
.Add (CreateParam (command
, DbType
.Binary
, ":SessionData",
218 dict
.ToByteArray ()));
220 command
.ExecuteNonQuery ();
223 private IDataParameter
CreateParam (IDbCommand command
, DbType type
,
224 string name
, object value)
226 IDataParameter result
= command
.CreateParameter ();
227 result
.DbType
= type
;
228 result
.ParameterName
= name
;
229 result
.Value
= value;
233 private DateTime
Tommorow ()
235 return DateTime
.Now
.AddDays (1);
238 private byte [] ReadBytes (IDataReader reader
, int index
)
240 int len
= (int) reader
.GetBytes (reader
.FieldCount
-1, 0, null, 0, 0);
241 byte [] data
= new byte [len
];
242 reader
.GetBytes (index
, 0, data
, 0, len
);