/// <summary> /// End enqueuing messages with transaction style. Currently, total size of queued messages must be less than 4 G bytes /// </summary> /// <param name="rollback">true for rollback, and false for committing</param> /// <param name="qt">A callback for tracking returning error code, which can be one of QUEUE_OK, QUEUE_TRANS_NOT_STARTED_YET, and so on</param> /// <param name="discarded">a callback for tracking cancel or socket closed event</param> /// <returns>true for sending the request successfully, and false for failure</returns> public virtual bool EndQueueTrans(bool rollback, DQueueTrans qt, DDiscarded discarded) { bool ok = SendRequest(idEndTrans, rollback, (ar) => { if (qt != null) { int errCode; ar.UQueue.Load(out errCode); qt((CAsyncQueue)ar.AsyncServiceHandler, errCode); } else { ar.UQueue.SetSize(0); } }, discarded, (DOnExceptionFromServer)null); IClientQueue cq = AttachedClientSocket.ClientQueue; if (cq.Available) { if (rollback) { cq.AbortJob(); } else { cq.EndJob(); } } return(ok); }
public bool EndJob() { IClientQueue src = SourceQueue; if (src == null || !src.Available) { return(false); } bool ok = src.EndJob(); if (ok && Replicable) { ok = src.AppendTo(TargetQueues); } return(ok); }
private bool Transfer() { int index = 0; DAsyncResultHandler rh = null; DOnExceptionFromServer se = null; CClientSocket cs = AttachedClientSocket; if (!cs.Sendable) { return(false); } uint sent_buffer_size = cs.BytesInSendingBuffer; if (sent_buffer_size > 3 * STREAM_CHUNK_SIZE) { return(true); } while (index < m_vContext.Count) { CContext context = m_vContext[index]; if (context.Sent) { ++index; continue; } if (context.Uploading && context.Tried && context.File == null) { if (index == 0) { if (context.Upload != null) { context.Upload(this, CANNOT_OPEN_LOCAL_FILE_FOR_READING, context.ErrMsg); } m_vContext.RemoveFromFront(); } else { ++index; } continue; } if (context.Uploading) { if (!context.Tried) { context.Tried = true; try { FileShare fs = FileShare.None; if ((context.Flags & FILE_OPEN_SHARE_READ) == FILE_OPEN_SHARE_READ) { fs = FileShare.Read; } context.File = new FileStream(context.LocalFile, FileMode.Open, FileAccess.Read, fs); context.FileSize = context.File.Length; IClientQueue cq = AttachedClientSocket.ClientQueue; if (cq.Available) { if (!cq.StartJob()) { context.File.Close(); context.File = null; throw new Exception("Cannot start queue job"); } } if (!SendRequest(idUpload, context.FilePath, context.Flags, context.FileSize, rh, context.Discarded, se)) { return(false); } } catch (Exception err) { context.ErrMsg = err.Message; } finally { } } if (context.File == null) { if (index == 0) { if (context.Upload != null) { context.Upload(this, CANNOT_OPEN_LOCAL_FILE_FOR_READING, context.ErrMsg); } m_vContext.RemoveFromFront(); } else { ++index; } continue; } else { using (CScopeUQueue sb = new CScopeUQueue()) { if (sb.UQueue.MaxBufferSize < STREAM_CHUNK_SIZE) { sb.UQueue.Realloc(STREAM_CHUNK_SIZE); } byte[] buffer = sb.UQueue.IntenalBuffer; int ret = context.File.Read(buffer, 0, (int)STREAM_CHUNK_SIZE); while (ret > 0) { if (!SendRequest(idUploading, buffer, (uint)ret, rh, context.Discarded, se)) { return(false); } sent_buffer_size = cs.BytesInSendingBuffer; if (ret < (int)STREAM_CHUNK_SIZE) { break; } if (sent_buffer_size >= 5 * STREAM_CHUNK_SIZE) { break; } ret = context.File.Read(buffer, 0, (int)STREAM_CHUNK_SIZE); } if (ret < (int)STREAM_CHUNK_SIZE) { context.Sent = true; if (!SendRequest(idUploadCompleted, rh, context.Discarded, se)) { return(false); } IClientQueue cq = AttachedClientSocket.ClientQueue; if (cq.Available) { cq.EndJob(); } } if (sent_buffer_size >= 4 * STREAM_CHUNK_SIZE) { break; } } } } else { if (!SendRequest(idDownload, context.FilePath, context.Flags, rh, context.Discarded, se)) { return(false); } context.Sent = true; context.Tried = true; sent_buffer_size = cs.BytesInSendingBuffer; if (sent_buffer_size > 3 * STREAM_CHUNK_SIZE) { break; } } ++index; } return(true); }
/// <summary> /// Send affected record set from a trigger for table update, delete or insert onto one or more remote SocketPro servers with auto replication if required. /// </summary> /// <param name="tableName">A valid table name</param> /// <param name="param">An extra info data. For example, a trigger name</param> /// <param name="batchSize">The size of a set of records in byte. It defaults to CAsyncAdoSerializationHelper.DEFAULT_BATCH_SIZE</param> /// <returns>True for success; and false for failure</returns> public virtual bool SendDmlTrigger(string tableName, object param, uint batchSize) { bool jobing = false; bool ok = true; if (tableName == null) { throw new ArgumentNullException("A valid table name required"); } if (tableName.Length == 0) { throw new ArgumentException("A valid table name required"); } IClientQueue srcQueue = SourceQueue; if (!srcQueue.Available) { srcQueue = null; } TriggerAction ta = SqlContext.TriggerContext.TriggerAction; using (SqlConnection conn = new SqlConnection("context connection=true")) { CAsyncServiceHandler.DAsyncResultHandler arh = null; SqlDataReader dr = null; try { conn.Open(); lock (m_csSs) { if (srcQueue != null) { jobing = (srcQueue.JobSize != 0); } THandler h = SourceHandler; try { if (srcQueue != null && !jobing) { ok = srcQueue.StartJob(); } switch (ta) { case TriggerAction.Update: case TriggerAction.Delete: case TriggerAction.Insert: ok = h.SendRequest(CAsyncAdoSerializationHelper.idDmlTriggerMessage, (int)ta, Utilities.GetObjectFullName(conn, tableName, "U"), param, arh); break; default: throw new InvalidOperationException("SendDmlTrigger for table update, insert and delete events only"); } if (ta == TriggerAction.Update || ta == TriggerAction.Delete) { SqlCommand cmd = new SqlCommand("select * from deleted", conn); dr = cmd.ExecuteReader(); ok = h.Send(dr, batchSize); dr.Close(); } if (ta == TriggerAction.Update || ta == TriggerAction.Insert) { SqlCommand cmd = new SqlCommand("select * from inserted", conn); dr = cmd.ExecuteReader(); ok = h.Send(dr, batchSize); dr.Close(); } if (srcQueue != null && !jobing) { ok = srcQueue.EndJob(); } ok = true; } catch { if (dr != null) { dr.Close(); } if (srcQueue != null && !jobing) { ok = srcQueue.AbortJob(); } ok = false; } } } finally { conn.Close(); if (Replicable && ok && !jobing) { ok = DoReplication(); } } } return(ok); }
/// <summary> /// Send a record set from a given query statement onto one or more remote SocketPro servers with auto replication if required /// </summary> /// <param name="sqlQuery">A statement creating a set of records</param> /// <param name="recordsetName">An string name for this record set</param> /// <param name="batchSize">The size of a set of records in byte. It defaults to CAsyncAdoSerializationHelper.DEFAULT_BATCH_SIZE</param> public virtual bool Send(string sqlQuery, string recordsetName, uint batchSize) { bool jobing = false; bool ok = false; if (sqlQuery == null) { throw new ArgumentNullException("A valid sql select query required"); } if (sqlQuery.Length == 0) { throw new ArgumentException("A valid sql select query required"); } IClientQueue srcQueue = SourceQueue; if (!srcQueue.Available) { srcQueue = null; } using (SqlConnection conn = new SqlConnection("context connection=true")) { CAsyncServiceHandler.DAsyncResultHandler arh = null; SqlDataReader dr = null; try { conn.Open(); lock (m_csSs) { if (srcQueue != null) { jobing = (srcQueue.JobSize != 0); } THandler h = SourceHandler; try { if (srcQueue != null && !jobing) { ok = srcQueue.StartJob(); } ok = h.SendRequest(CAsyncAdoSerializationHelper.idRecordsetName, recordsetName, arh); SqlCommand cmd = new SqlCommand(sqlQuery, conn); dr = cmd.ExecuteReader(); do { ok = h.Send(dr, batchSize); } while (dr.NextResult()); dr.Close(); if (srcQueue != null && !jobing) { ok = srcQueue.EndJob(); } ok = true; } catch { if (dr != null) { dr.Close(); } if (srcQueue != null && !jobing) { ok = srcQueue.AbortJob(); } ok = false; } } } finally { conn.Close(); if (!jobing && Replicable && ok) { ok = DoReplication(); } } } return(ok); }