public static string Copy(Program program, TableNode sourceTable, TableNode targetTable, GenerateStatementHandler generateStatement) { Statement targetStatement = generateStatement ( sourceTable, targetTable, (Expression)targetTable.EmitStatement(Alphora.Dataphor.DAE.Language.D4.EmitMode.ForCopy) ); Schema.Key displaySourceKey = program.FindClusteringKey(sourceTable.TableVar); StringBuilder result = new StringBuilder(); long succeededUpdateCount = 0; long failedUpdateCount = 0; bool maxResultLengthMessageWritten = false; // Start a new process so that we don't mess with the transaction context of this one ProcessInfo info = new ProcessInfo(program.ServerProcess.ServerSession.SessionInfo); info.UseImplicitTransactions = false; IServerProcess targetProcess = ((IServerSession)program.ServerProcess.ServerSession).StartProcess(info); try { Program targetProgram = new Program((ServerProcess)targetProcess); targetProgram.Code = targetTable; targetProgram.Start(null); try { // Have the target program use the main program's context Stack oldTargetContext = targetProgram.SwitchContext(program.Stack); try { info.DefaultIsolationLevel = IsolationLevel.Browse; IServerProcess sourceProcess = ((IServerSession)program.ServerProcess.ServerSession).StartProcess(info); try { Program sourceProgram = new Program((ServerProcess)sourceProcess); sourceProgram.Code = sourceTable; sourceProgram.Start(null); try { // Have the source program use the main program's context Stack oldSourceContext = sourceProgram.SwitchContext(program.Stack); try { ITable source = (ITable)sourceTable.Execute(sourceProgram); try { source.Open(); // TODO: IBAS Project #26790 - allow cross-process row copies for streamed types // There is a MarshalRow call in the LocalProcess, would that solve this problem? using (Row row = new Row(targetProcess.ValueManager, sourceTable.DataType.CreateRowType())) { DataParams paramsValue = new DataParams(); paramsValue.Add(new DataParam("ASourceRow", row.DataType, DAE.Language.Modifier.Const, row)); IServerStatementPlan target = targetProcess.PrepareStatement(new D4TextEmitter().Emit(targetStatement), paramsValue); try { target.CheckCompiled(); while (source.Next()) { row.ClearValues(); targetProcess.BeginTransaction(IsolationLevel.Isolated); try { source.Select(row); target.Execute(paramsValue); targetProcess.CommitTransaction(); succeededUpdateCount++; } catch (Exception exception) { failedUpdateCount++; targetProcess.RollbackTransaction(); if (result.Length < 100000) { result.Append(KeyValuesToString(displaySourceKey, row) + " - " + exception.Message + "\r\n"); } else { if (!maxResultLengthMessageWritten) { result.Append(Strings.Get("MaxResultLengthExceeded")); maxResultLengthMessageWritten = true; } } } // Yield in case our process is aborted. program.CheckAborted(); } } finally { targetProcess.UnprepareStatement(target); } } } finally { source.Close(); } } finally { sourceProgram.SwitchContext(oldSourceContext); // Don't let the source program cleanup the main context } } finally { sourceProgram.Stop(null); } } finally { ((IServerSession)program.ServerProcess.ServerSession).StopProcess(sourceProcess); } result.AppendFormat(Strings.Get("Results"), succeededUpdateCount, failedUpdateCount); return(result.ToString()); } finally { targetProgram.SwitchContext(oldTargetContext); // Don't let the target program cleanup the main context } } finally { targetProgram.Stop(null); } } finally { ((IServerSession)program.ServerProcess.ServerSession).StopProcess(targetProcess); } }
/// <summary> /// Close the supplied table in Mapinfo. /// </summary> /// <param name="table">The table that will be closed.</param> public static void CloseTable(ITable table) { table.Close(); }