18 using System.Collections.Generic;
30 namespace Deveel.Data.Protocol {
40 DatabaseHandler = databaseHandler;
42 resultMap =
new Dictionary<int, QueryResult>();
55 GC.SuppressFinalize(
this);
59 protected virtual void Dispose(
bool disposing) {
65 DatabaseHandler = null;
76 protected IDictionary<string, object> Metadata {
get;
private set; }
82 throw new ObjectDisposedException(GetType().AssemblyQualifiedName);
87 throw new InvalidOperationException(
"The connector is not authenticated.");
90 throw new InvalidOperationException(
"The connector is authenticated but no user is set.");
98 this.parameterStyle = parameterStyle;
102 ignoreIdentifiersCase = value;
107 foreach (var result
in resultMap.Values) {
118 CurrentState = newState;
123 RemoteEndPoint = remoteEndPoint;
124 Database = DatabaseHandler.GetDatabase(databaseName);
126 throw new InvalidOperationException();
130 }
catch (Exception) {
139 public abstract ConnectionEndPoint MakeEndPoint(IDictionary<string, object> properties);
144 }
catch (Exception) {
158 protected virtual bool Authenticate(
string defaultSchema,
string username,
string password) {
160 throw new InvalidOperationException(
"Already authenticated.");
163 if (
String.IsNullOrEmpty(defaultSchema))
164 defaultSchema =
"SA";
171 var user =
Database.Authenticate(username, password);
175 if (!OnAuthenticated(user))
181 Metadata =
new Dictionary<string, object> {
182 {
"IgnoreIdentifiersCase", ignoreIdentifiersCase },
183 {
"ParameterStyle", parameterStyle },
184 {
"DefaultSchema", defaultSchema }
190 }
catch (Exception) {
239 if (transaction == null)
240 throw new InvalidOperationException();
243 return session.CreateQuery();
250 session.AutoCommit(
true);
251 return session.CreateQuery();
255 AssertAuthenticated();
259 queryContext = OpenQueryContext(commitId);
261 queryContext = CreateQueryContext();
264 return ExecuteQuery(queryContext, text, parameters);
274 response = CoreExecuteQuery(context, text, parameters);
284 if (context.AutoCommit()) {
286 if (response == null) {
293 }
catch (Exception) {
296 DisposeResult(queryResponse.
ResultId);
317 if (parameters != null) {
321 var stopwatch =
new Stopwatch();
324 var results = context.ExecuteQuery(query);
328 foreach (var result
in results) {
332 resultId = AddResult(queryResult);
333 }
catch (Exception) {
335 DisposeResult(resultId);
340 var taken = stopwatch.ElapsedMilliseconds;
343 responses[j] =
new QueryResponse(resultId, queryResult, (
int)taken,
"");
356 if (resultMap.TryGetValue(resultId, out result))
357 resultMap.Remove(resultId);
360 if (result != null) {
373 resultId = ++uniqueResultId;
374 resultMap[resultId] = result;
381 AssertAuthenticated();
384 if (transaction == null)
385 throw new InvalidOperationException();
387 return transaction.CommitId;
397 return CreateEnvelope(metadata, message);
402 throw new NotImplementedException();
406 throw new NotImplementedException();
410 if (envelope == null)
422 if (transaction == null)
423 throw new InvalidOperationException();
425 using (var session =
new Session(transaction,
User)) {
434 if (transaction == null)
435 throw new InvalidOperationException();
437 using (var session =
new Session(transaction,
User)) {
445 var table = GetResult(resultId);
447 throw new InvalidOperationException();
449 int rowEnd = startRow + countRows;
451 if (startRow < 0 || startRow >= table.RowCount || rowEnd > table.RowCount) {
452 throw new InvalidOperationException(
"Result part out of range.");
456 int colCount = table.ColumnCount;
458 for (
int r = startRow; r < rowEnd; ++r) {
460 var sizes =
new int[colCount];
462 for (
int c = 0; c < colCount; ++c) {
463 var value = table.GetValue(r, c);
467 var reference = (IObjectRef)value.Value;
470 clientOb = value.Value;
474 sizes[c] = value.Size;
480 }
catch (Exception) {
489 if (!resultMap.TryGetValue(resultId, out result))
497 throw new NotImplementedException();
500 #region QueryResponse
506 QueryTimeMillis = millis;
510 public int ResultId {
get;
private set; }
514 public int QueryTimeMillis {
get;
private set; }
516 public int RowCount {
520 public int ColumnCount {
528 public string Warnings {
get;
private set; }
533 #region ServerMessageProcessor
539 this.connector = connector;
547 IDictionary<string, object> metadata = null;
548 if (sourceMessage != null)
551 return CreateErrorResponse(metadata, error);
556 envelope.SetError(error);
565 response.SetError(
new Exception(
"Unable to authenticate."));
573 }
catch (Exception ex) {
574 return CreateErrorResponse(metadata, ex);
580 var message = connector.GetMessage(envelope);
582 return CreateErrorResponse(metadata,
new Exception(
"No message found in the envelope."));
585 return ProcessConnect(metadata, (ConnectRequest)message);
588 return ProcessAuthenticate(metadata, (AuthenticateRequest)message);
591 return ProcessQuery(metadata, (QueryExecuteRequest)message);
593 return ProcessQueryPart(metadata, (QueryResultPartRequest)message);
595 return ProcessDisposeResult(metadata, (DisposeResultRequest)message);
598 return ProcessCreateLargeObject(metadata, (LargeObjectCreateRequest)message);
601 return ProcessBegin(metadata);
603 return ProcessCommit(metadata, (CommitRequest)message);
605 return ProcessRollback(metadata, (RollbackRequest)message);
608 return ProcessClose(metadata);
610 return CreateErrorResponse(envelope,
"Message not supported");
614 Exception error = null;
625 var encryptionData = connector.GetEncryptionData();
627 var serverVersion = connector.Database.
Version.ToString(2);
628 response =
new ConnectResponse(
true, serverVersion, encryptionData != null, encryptionData);
629 }
catch (Exception ex) {
635 var envelope = connector.CreateEnvelope(metadata, response);
637 envelope.SetError(error);
639 return connector.CreateEnvelope(metadata, response);
644 connector.AssertNotDisposed();
645 connector.AssertAuthenticated();
647 connector.CloseConnector();
649 }
catch (Exception ex) {
651 return CreateErrorResponse(metadata, ex);
657 connector.AssertNotDisposed();
658 connector.AssertAuthenticated();
663 }
catch (Exception ex) {
665 return CreateErrorResponse(metadata, ex);
671 connector.AssertNotDisposed();
672 connector.AssertAuthenticated();
676 }
catch (Exception ex) {
678 return CreateErrorResponse(metadata, ex);
684 connector.AssertNotDisposed();
685 connector.AssertAuthenticated();
687 connector.DisposeResult(request.
ResultId);
689 }
catch (Exception ex) {
691 return CreateErrorResponse(metadata, ex);
698 connector.AssertNotDisposed();
699 connector.AssertAuthenticated();
701 var objRef = connector.CreateLargeObject(request.
ObjectLength);
703 }
catch (Exception ex) {
705 return CreateErrorResponse(metadata, ex);
711 connector.AssertNotDisposed();
712 connector.AssertAuthenticated();
714 var
id = connector.BeginTransaction();
715 return connector.CreateEnvelope(metadata,
new BeginResponse(
id));
716 }
catch (Exception ex) {
718 return CreateErrorResponse(metadata, ex);
724 connector.AssertNotDisposed();
725 connector.AssertAuthenticated();
729 }
catch (Exception ex) {
731 return CreateErrorResponse(metadata, ex);
737 connector.AssertNotDisposed();
738 connector.AssertAuthenticated();
742 }
catch (Exception ex) {
744 return CreateErrorResponse(metadata, ex);
IMessageProcessor CreateProcessor()
IMessageEnvelope CreateErrorResponse(IDictionary< string, object > metadata, Exception error)
IMessageEnvelope ProcessQueryPart(IDictionary< string, object > metadata, QueryResultPartRequest request)
int ColumnCount
Returns the column count.
void CommitTransaction(int commitId)
void DisposeResult(int resultId)
A long string in the system.
IMessageEnvelope ProcessCommit(IDictionary< string, object > metadata, CommitRequest request)
TriggerEventType
The different types of high layer trigger events.
Dictionary< int, QueryResult > resultMap
ITransaction FindById(int commitId)
ServerMessageProcessor(ServerConnector connector)
IMessageEnvelope CreateErrorResponse(IMessageEnvelope sourceMessage, Exception error)
void AssertAuthenticated()
IMessageEnvelope ProcessAuthenticate(IDictionary< string, object > metadata, AuthenticateRequest request)
QueryResultPart GetResultPart(int resultId, int startRow, int countRows)
virtual void OnConnectorOpen()
ConnectionEndPoint RemoteEndPoint
IMessageEnvelope ProcessBegin(IDictionary< string, object > metadata)
The response to a command executed via the IDatabaseInterface.ExecuteQuery method in the IDatabaseInt...
QueryParameterStyle ParameterStyle
int AddResult(QueryResult result)
The default implementation of a database in a system.
IMessageEnvelope CreateErrorResponse(IMessageEnvelope sourceMessage, string message)
void SetAutoCommit(bool value)
int RowCount
Returns the row count.
IDictionary< string, object > Metadata
bool IgnoreIdentifiersCase
The representation of a single database in the system.
QueryResultColumn GetColumn(int columnOffset)
IMessageEnvelope CreateEnvelope(IDictionary< string, object > metadata, IMessage message)
This is a session that is constructed around a given user and a transaction, to the given database...
IMessageEnvelope ProcessCreateLargeObject(IDictionary< string, object > metadata, LargeObjectCreateRequest request)
bool ignoreIdentifiersCase
void OpenConnector(ConnectionEndPoint remoteEndPoint, string databaseName)
ITriggerChannel CreateTriggerChannel(string triggerName, string objectName, TriggerEventType eventType)
Defines the contract for a valid SQL Object
virtual bool OnAuthenticated(User user)
virtual void OnCloseConnector()
QueryResult GetResult(int resultId)
ObjectId CreateLargeObject(long objectLength)
IMessageEnvelope ProcessRollback(IDictionary< string, object > metadata, RollbackRequest request)
IMessageEnvelope ProcessConnect(IDictionary< string, object > metadata, ConnectRequest request)
IQueryResponse[] CoreExecuteQuery(IQuery context, string text, IEnumerable< QueryParameter > parameters)
IMessageEnvelope ProcessDisposeResult(IDictionary< string, object > metadata, DisposeResultRequest request)
ITransactionFactory TransactionFactory
Gets an object that is used to create new transactions to this database
QueryParameterStyle
In a SQL query object, this is the form of parameters passed from the client side to the server side...
readonly ServerConnector connector
A unique identifier of an object within a database system, that is composed by a reference to the sto...
IMessageEnvelope ProcessMessage(IMessageEnvelope envelope)
void SetParameterStyle(QueryParameterStyle parameterStyle)
ServerConnector(IDatabaseHandler databaseHandler)
IQuery CreateQueryContext()
virtual void Dispose(bool disposing)
IQueryResponse[] ExecuteQuery(long commitId, string text, IEnumerable< QueryParameter > parameters)
void ChangeState(ConnectorState newState)
QueryResponse(int resultId, QueryResult queryResult, int millis, string warnings)
QueryParameterStyle parameterStyle
IMessageEnvelope ProcessQuery(IDictionary< string, object > metadata, QueryExecuteRequest request)
virtual IMessage GetMessage(IMessageEnvelope envelope)
IMessageEnvelope ProcessClose(IDictionary< string, object > metadata)
ILargeObjectChannel CreateObjectChannel(long objectId)
QueryResultColumn GetColumn(int column)
IQuery OpenQueryContext(long commitId)
Provides the information for a user in a database system
void RollbackTransaction(int commitId)
ICollection< QueryParameter > Parameters
virtual EncryptionData GetEncryptionData()
virtual IQueryResponse[] ExecuteQuery(IQuery context, string text, IEnumerable< QueryParameter > parameters)
virtual bool Authenticate(string defaultSchema, string username, string password)
void SetIgnoreIdentifiersCase(bool value)
int ResultId
Returns a number that identifies this command within the set of queries executed on the connection...
TransactionCollection OpenTransactions
Gets the collection of currently open transactions.