apache beam: accessing metrics during pipeline processing - apache-beam

Using the WordCount.java example to test metrics. The PrintMetricsFn function (see below) prints the metrics correctly once the pipeline is finished, but fails when called while the pipeline is processing. DirectRunner and FlinkRunner both throw exceptions (null input), while SparkRunner prints only the header line (similar to "* Metric Values *").
private static void PrintMetricsFn(final MetricsFilter inputFilter) {
final MetricResults metrics = result.metrics();
final MetricQueryResults returns = metrics.queryMetrics(inputFilter);
final Iterable<MetricResult<Long>> counters = returns.getCounters();
System.out.println("*** Metric Values ***");
for(final MetricResult<Long> s: counters){
System.out.println(s.getName().getNamespace() + ":" +
s.getName().getName() + ":" + s.getStep() + ": count=" +
s.getAttempted()) ;
}
final Iterable<MetricResult<DistributionResult>> dist = returns.getDistributions();
for (final MetricResult<DistributionResult> d: dist) {
System.out.println(d.getName().getNamespace() + ":" +
d.getName().getName() + ":" + d.getStep() + ": sum=" +
d.getAttempted().getSum() + ", count=" +
d.getAttempted().getCount() + ", min=" +
d.getAttempted().getMin() + ", max=" +
d.getAttempted().getMax() + ", mean=" +
d.getAttempted().getMean());
}
final Iterable<MetricResult<GaugeResult>> gauge = returns.getGauges();
for (final MetricResult<GaugeResult> g: gauge) {
System.out.println(g.getName().getNamespace() + ":" +
g.getName().getName() + ":" + g.getStep() + ": gauge=" +
g.getAttempted().getValue());
}
return;
}
Here are the declarations for the external variables:
private static PipelineResult result;
private static MetricQueryResults returns;
private static MetricsFilter mFilter;
And here's where the mFilter and result variables are set:
mFilter = MetricsFilter.builder()
.addNameFilter(MetricNameFilter.named("ExtractWordsFn", "emptyLines"))
.addNameFilter(MetricNameFilter.named("ExtractWordsFn", "lineLenDistro"))
.addNameFilter(MetricNameFilter.named("ExtractWordsFn", "maxLineLen"))
.build();
result = p.run();
Finally, here's the function that calls PrintMetricsFN without success:
#ProcessElement
public void processElement(#Element final String element, final OutputReceiver<String> receiver) {
lineLen = element.length();
lineLenDist.update(lineLen);
if (element.trim().isEmpty()) {
emptyLines.inc();
}
if (lineLen > localMax) {
localMax = lineLen;
maxLineLen.set(localMax);
}
if((lineCnt++ % 10) == 0) {
PrintMetricsFn(mFilter);
}
// Split the line into words.
final String[] words = element.split(ExampleUtils.TOKENIZER_PATTERN, -1);
// Output each word encountered into the output PCollection.
for (final String word : words) {
if (!word.isEmpty()) {
receiver.output(word);
}
}
}
And for completeness, here's the error I get from DirectRunner:
Caused by: java.lang.NullPointerException
at org.apache.beam.examples.WordCount.PrintMetricsFn(WordCount.java:158)
at org.apache.beam.examples.WordCount.access$1(WordCount.java:157)
at org.apache.beam.examples.WordCount$ExtractWordsFn.processElement(WordCount.java:132)

Related

android display arraylist items in dialog

I am having an arraylist fetching name and status of a person. Arraylist is storing the status and name. Its displaying one name at a time. How can I be able to display multiple names at once in alert dialog?
private ArrayList getunfiledRogspDoctorList() {
SqlDataStore sd = new SqlDataStore(this);
sd.open();
String gspQuery = " SELECT * FROM "+ TABLE_DOCTOR + " WHERE " + Queryclass.DOCTOR_ROGSP_STATUS + " == " + 0 + " AND " + Queryclass.DOCTOR_DATE_ID + " = '" + selectionID + "'";
Cursor gspCu = sd.getData(gspQuery);
if(gspCu.moveToFirst()){
do {
rogspname = gspCu.getString(gspCu.getColumnIndex(Queryclass.DOCTOR_CONTACTNAME));
unfiledrogspDoctorList.add(gspCu.getString(gspCu.getColumnIndex(Queryclass.DOCTOR_ROGSP_STATUS)) + rogspname);
}while (gspCu.moveToNext());
}
gspCu.close();
sd.close();
System.out.println("unfiledrogspDoctorList "+unfiledrogspDoctorList);
return unfiledrogspDoctorList;
}
From the code, you are having an ArrayList of your target display String in unfiledrogspDoctorList:
// Suggest to also define the type of your returning ArrayList
private ArrayList<String> getunfiledRogspDoctorList() {
// Define a local ArrayList
ArrayList<String> unfiledrogspDoctorList = new ArrayList<>();
SqlDataStore sd = new SqlDataStore(this);
sd.open();
String gspQuery = " SELECT * FROM "+ TABLE_DOCTOR + " WHERE " + Queryclass.DOCTOR_ROGSP_STATUS + " == " + 0 + " AND " + Queryclass.DOCTOR_DATE_ID + " = '" + selectionID + "'";
Cursor gspCu = sd.getData(gspQuery);
if(gspCu.moveToFirst()){
do {
rogspname = gspCu.getString(gspCu.getColumnIndex(Queryclass.DOCTOR_CONTACTNAME));
unfiledrogspDoctorList.add(gspCu.getString(gspCu.getColumnIndex(Queryclass.DOCTOR_ROGSP_STATUS)) + rogspname);
}while (gspCu.moveToNext());
}
gspCu.close();
sd.close();
System.out.println("unfiledrogspDoctorList "+unfiledrogspDoctorList);
return unfiledrogspDoctorList;
}
You can consider to convert your ArrayList of String into just a String.
private String concat(ArrayList<String> unfiledrogspDoctorList) {
StringBuilder sb = new StringBuilder();
for (String item : unfiledrogspDoctorList) {
sb.append(item);
sb.append(","); // Or change into other separate you would like to display
}
sb.setLength(Math.max(0, sb.length() - 1)); // Remove the appending character
return sb.toString();
}
Then you can make use of an AlertDialog to display that concatenated String.
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder
.setMessage(concat(getunfiledRogspDoctorList()))
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Do anything upon pressing OK button
}
);
AlertDialog alert = builder.create();
alert.show();
You could use :-
SELECT group_concat(name) FROM ....
or to place each on a line you could change the default comma separator to a line feed using
SELECT group_concat(name,'\n') FROM ....
.... representing the rest of the SQL in the question
See https://www.sqlite.org/lang_aggfunc.html#group_concat
note that the GROUP as no GROUP BY clause is provided is a single group (and therefore output row) made up of ALL extracted rows.

Exception: (Index -1 requested, with a size of 2) while retrieving data from a Cursor

Hey I have a problem with accessing the data from a Cursor in Android Studio.
I have two tables in the database events and messages. So each event in the events table may have multiple messages in the messages table. The event and its messages share a common event_id.
I am using LoaderCallbacks to get a Cursor from a ContentProvider. In the ContentProvider query method, I am using a rawQuery to INNER JOIN these two tables.
In this example I query for an event which shares its event_id with two messages from the message table. In the ContentProvider the rawQuery() method with the INNER JOIN was performed.
At this state I can see in the Debugger that the variable mCount from the Cursor is -1. I am not sure what this means but anyways, back in the onLoadFinish() method the Cursor now contains a variable mCursor and this variable again contains a variable mCount which is 2. Which makes sense, since the query should return a Cursor with two rows and since there are two messages. But now I try to get a String with the getString() method and the CursorIndexOutOfBoundsException: Index -1 requested, with a size of 2 is thrown.
I realy don't understand what this means. And I don't find any hint in die Cursor docs, what it means when mCount is -1.
Furthermore in the onLoadFinished method the variable mEditTable is null. And in other queries where I don't join anything it always contains a table.
I am quite sure that the issue somwhere lays with the INNER JOIN, since everything works fine if I use just a query method inside the ContentProvider.query method. But I don't know what I should do differently. I hope you might help me with this. I am aware that, if there is no message related to an event, this query will return an empty cursor with mCount = 0 and then again an exception will be thrown. But this is not the case in this example.
EventProvider class:
public class EventProvider extends ContentProvider {
private static final String LOG_TAG = EventProvider.class.getSimpleName();
private static final int EVENTS = 100;
private static final int EVENT_ID = 101;
private static final int EVENT_MESSAGE_ID = 102;
private static UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private EventDbHelper mEventDbHelper;
static {
sUriMatcher.addURI(EventContract.CONTENT_AUTHORITY, EventContract.PATH_EVENTS, EVENTS);
sUriMatcher.addURI(EventContract.CONTENT_AUTHORITY, EventContract.PATH_EVENTS + "/#", EVENT_ID);
sUriMatcher.addURI(EventContract.CONTENT_AUTHORITY, EventContract.PATH_EVENT_AND_ITS_MESSAGES + "/#", EVENT_MESSAGE_ID);
}
#Override
public boolean onCreate() {
mEventDbHelper = new EventDbHelper(getContext());
return true;
}
#Nullable
#Override
public Cursor query(#NonNull Uri uri, #Nullable String[] projection, #Nullable String selection, #Nullable String[] selectionArgs, #Nullable String sortOrder) {
SQLiteDatabase database = mEventDbHelper.getReadableDatabase();
Cursor retCursor;
final int match = sUriMatcher.match(uri);
switch (match) {
case EVENTS:
retCursor = database.query(EventEntry.TABLE_NAME, projection, selection, selectionArgs, null, null, sortOrder);
break;
case EVENT_ID:
selection = EventEntry.COLUMN_EVENT_ID + "=?";
selectionArgs = new String[] {String.valueOf(ContentUris.parseId(uri))};
retCursor = database.query(EventEntry.TABLE_NAME, projection,selection, selectionArgs, null, null, sortOrder);
break;
case EVENT_MESSAGE_ID:
selection = MessageEntry.TABLE_NAME + "." + MessageEntry.COLUMN_EVENT_ID + "=?";
selectionArgs = new String[] {String.valueOf(ContentUris.parseId(uri))};
StringBuilder sqlQuery = new StringBuilder();
sqlQuery.append("SELECT ");
if(projection != null && projection.length > 0) {
for(String s: projection) {
sqlQuery.append(s).append(", ");
}
}
sqlQuery.replace(sqlQuery.length()-2, sqlQuery.length(), " FROM ").append(MessageEntry.TABLE_NAME);
sqlQuery.append(" INNER JOIN ").append(EventEntry.TABLE_NAME).append(" ON ");
sqlQuery.append(EventEntry.TABLE_NAME).append(".").append(EventEntry.COLUMN_EVENT_ID).append("=");
sqlQuery.append(MessageEntry.TABLE_NAME).append(".").append(MessageEntry.COLUMN_EVENT_ID);
sqlQuery.append(" WHERE ").append(selection).append(" ORDER BY ").append(sortOrder).append(";");
Log.v(LOG_TAG, "SQL command for: " + uri.toString());
Log.v(LOG_TAG, sqlQuery.toString());
retCursor = database.rawQuery(sqlQuery.toString(), selectionArgs);
break;
default:
throw new IllegalArgumentException("Cannot query unknown URI: " + uri);
}
retCursor.setNotificationUri(getContext().getContentResolver(), uri);
return retCursor;
}
EventActivity:
#NonNull
#Override
public Loader<Cursor> onCreateLoader(int id, #Nullable Bundle args) {
String[] projection = {
MessageEntry.TABLE_NAME + "." + MessageEntry.COLUMN_EVENT_ID,
MessageEntry.TABLE_NAME + "." + MessageEntry.COLUMN_SENDER,
MessageEntry.TABLE_NAME + "." + MessageEntry.COLUMN_DATE,
MessageEntry.TABLE_NAME + "." + MessageEntry.COLUMN_MESSAGE,
EventEntry.TABLE_NAME + "." + EventEntry._ID,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_NAME,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_DATE,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_DATE_ADDENDUM,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_CONTACT,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_STATUS,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_PICTURE_NAME,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_DESCRIPTION,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_STREET,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_HOUSE_NUMBER,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_POST_CODE,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_CITY,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_EMAIL,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_LOCATION,
EventEntry.TABLE_NAME + "." + EventEntry.COLUMN_SIGNED_UP
};
String sortOrder = MessageEntry.COLUMN_DATE + " DESC";
return new CursorLoader(this, mCurrentEventUri, projection, null, null, sortOrder);
}
#Override
public void onLoadFinished(#NonNull Loader<Cursor> loader, Cursor cursor) {
int indexName = cursor.getColumnIndex(EventEntry.COLUMN_NAME);
int indexImage = cursor.getColumnIndex(EventEntry.COLUMN_PICTURE_NAME);
String imageName = cursor.getString(indexImage); //Here the Exception is thrown
mEventName.setText(cursor.getString(indexName));
mEventAdapter.swapCursor(cursor);
}
If you need something else, I will upload it.
Thanks.
CursorIndexOutOfBoundsException: Index -1 requested, with a size of 2
-1 with Cursors will generally be 1 of 2 issues :-
that the column name passed to getColumnIndex is not a name of a column in the output.
that the Cursor is at the beginning that is at the position that is "before the first row", as is the case when a Cursor is returned.
I suspect that your issue is due to 2 as I believe the message indicates the row of the column.
2 can happen if a move???? (e.g. moveToFirst, moveToNext) method was not actioned (I cannot see any such move in your code) or that the result was not checked (the move methods return true or false to indicate whether or not the move request could be satisfied).
see (probably moveToFirst)
https://developer.android.com/reference/android/database/Cursor#move(int)
https://developer.android.com/reference/android/database/Cursor#moveToFirst()
https://developer.android.com/reference/android/database/Cursor#moveToLast()
https://developer.android.com/reference/android/database/Cursor#moveToNext()
https://developer.android.com/reference/android/database/Cursor#moveToPosition(int)
https://developer.android.com/reference/android/database/Cursor#moveToPrevious()
The fix would be to move the Cursor to a row, checking if the move was actually successful and to then extract the data.
e.g.
String imageName = "No Image"
if (cursor.moveToFirst() && indexImage > -1) {
imageName = cursor.getString(indexImage); //Here the Exception is thrown
}
The above, && indexImage > -1, would also weed out the situation where the column name does not exist in the Cursor.

#AspectJ pointcut for execute methods of a package that contains keyword service

I'm trying to intercept all classes that contains a specific word in their package name... something as below:
#Pointcut("execution(* *..service..*.*(..))")
I have all the classes in the packages to intercept:
com.domain.model.user.service.save(User user);
com.domain.model.user.service.impl.save(XPTO xpto);
com.domain.model.foo.service.HelloWorld.getMessage(Foo foo);
In short, i would like to intercept all the methods in the classes that belong to the
package *service*
I am trying to get this working from past many days.
Try this. Perhaps you have to exclude your aspect classes to avoid endless loops. This example catch all methods with com..login..* in package
#Aspect
#SuppressAjWarnings({ "adviceDidNotMatch" })
public class AllMethodsAspect {
private static Map<String, Long> beforeTimestamps = new HashMap<>();
#Pointcut("!within(aspects..*)"
+ " && (!execution(* org..* (..)) && !within(org..*) && !call(* org..* (..)) )"
+ " && (!execution(* java..* (..)) && !within(java..*) && !call(* java..* (..)) )"
+ " && (!execution(* javax..* (..)) && !within(javax..*) && !call(* javax..* (..)) )"
+ " && (!execution(* sun..* (..)) && !within(sun..*) && !call(* sun..* (..)) )"
+ " && execution(* com..login..*(..))")
public void methodCall() {
}
#Before("methodCall()")
public void before(JoinPoint joinPoint) {
beforeMethodCall(joinPoint);
}
#AfterReturning(pointcut = "methodCall()", returning = "returnObject")
public void after(JoinPoint joinPoint, Object returnObject) {
afterMethodCall(joinPoint, returnObject);
}
#AfterThrowing(pointcut = "methodCall()", throwing = "throwable")
public void throwing(JoinPoint joinPoint, Throwable throwable) {
afterThrowingMethodCall(joinPoint, throwable);
}
void beforeMethodCall(JoinPoint joinPoint) {
try {
long start = System.currentTimeMillis();
beforeTimestamps.put(joinPoint.toString() + " - " + Thread.currentThread().getName(), Long.valueOf(start));
LOG.info(".before " + joinPoint);
} catch (Exception e) {
LOG.error(".before Exception " + e);
}
}
void afterMethodCall(JoinPoint joinPoint, Object returnObject) {
afterMethodCall(joinPoint, returnObject, 0);
}
void afterMethodCall(JoinPoint joinPoint, Object returnObject, int depth) {
try {
long start = beforeTimestamps.get(joinPoint.toString() + " - " + Thread.currentThread().getName()).longValue();
beforeTimestamps.remove(joinPoint.toString() + " - " + Thread.currentThread().getName());
long duration = System.currentTimeMillis() - start;
Signature signature = joinPoint.getSignature();
if (signature instanceof MethodSignature) {
Class<?> returnType = ((MethodSignature) signature).getReturnType();
LOG.info(".after " + joinPoint + " " + duration + "ms" + (void.class == returnType ? "" : " [" + returnObject + "]"));
} else if (signature instanceof ConstructorSignature) {
LOG.info(".after " + joinPoint + " " + duration + "ms Constructor");
} else if (signature instanceof FieldSignature) {
LOG.info(".after " + joinPoint + " " + duration + "ms Field");
} else {
LOG.info(".after " + joinPoint + " " + duration + "ms unknown");
}
} catch (Exception e) {
LOG.error(".after Exception " + e);
}
}
void afterThrowingMethodCall(JoinPoint joinPoint, Throwable throwable) {
try {
Long startAsLong = beforeTimestamps.get(joinPoint.toString() + " - " + Thread.currentThread().getName());
long start = startAsLong == null ? 0 : startAsLong.longValue();
beforeTimestamps.remove(joinPoint.toString() + " - " + Thread.currentThread().getName());
long duration = System.currentTimeMillis() - start;
LOG.info(".fail " + joinPoint.toString() + " " + duration + " ms - " + throwable.getMessage());
} catch (NullPointerException e) {
LOG.info(".fail NullPointerException " + "unknown - " + throwable.getMessage());
}
}
static final class LOG {
static void info(String loggingData) {
System.err.println(new Date() + " " + loggingData);
}
static void error(String loggingData) {
System.err.println(new Date() + " " + loggingData);
}
}
}
I think you can capture what you need with a pointcut like this:
before(): execution(* *(..)) &&
(within(*..service..*.*) || within(service..*.*) || within(*..service.*)) {}
The three within clauses capture the three alternatives:
within(*..service..*.*): 'service' is somewhere in the package name but not at the start or end
within(service..*.*): 'service' is at the start of the package name (maybe this can't happen in your scenario)
within(*..service.*)): 'service' is at the end of the package name
If you need to capture serviceFoo variants you could add further wildcards around service (I think): within(*..*service*.*)
You should use a pointcut expression like this:
within(your.base.package..service..*)
restrict to at least your base package (typically this is not an issue)
match 'service' keyword in your package name at any level
for example, this will match those classes :
your.base.package.service.ServiceClass
your.base.package.service.customer.ServiceClass
your.base.package.internal.service.ServiceClass
your.base.package.internal.service.customer.ServiceClass

GWT upload error FileNotFoundException

I'm uploading the files on the server like this: I create folder on the server and then I put all my uploading files in this folder
#Override
public String executeAction(HttpServletRequest request,
List<FileItem> sessionFiles) throws UploadActionException {
String response = "";
int cont = 0;
userNumber = request.getParameter("userNumber");
File f = new File(ConfAppServer.getRealContextPath() + "/edoc/"
+ userNumber);
for (FileItem item : sessionFiles) {
if (false == item.isFormField()) {
cont++;
try {
String extension = item.getName().substring(
item.getName().length() - 3);
File file = null;
file = new File(ConfAppServer.getRealContextPath()
+ "/edoc/"
+ userNumber
+ System.getProperty("file.separator")
+ item.getName().substring(0,
item.getName().length() - 4) + "."
+ extension);
item.write(file);
receivedFiles.put(item.getFieldName(), file);
receivedContentTypes.put(item.getFieldName(),
item.getContentType());
response += "<file-" + cont + "-field>"
+ item.getFieldName() + "</file-" + cont
+ "-field>\n";
response += "<file-" + cont + "-name>" + item.getName()
+ "</file-" + cont + "-name>\n";
response += "<file-" + cont + "-size>" + item.getSize()
+ "</file-" + cont + "-size>\n";
response += "<file-" + cont + "-type>"
+ item.getContentType() + "</file-" + cont
+ "type>\n";
} catch (Exception e) {
throw new UploadActionException(e);
}
}
}
removeSessionFileItems(request);
return "<response>\n" + response + "</response>\n";
}
It works ver well on my colleague computer, but on my computer I get an error
There is an error in file name. Help me please fix my problem. Thanks.
As you can see the file name is not displaying correcly. So the problem is the encoding of the Request/Response. You need to add a filter servlet. Here is a tutorial.

On Maintaining Unique Scope between server and client. Still it reflect same data on sync with another client as i syn with first one. Why?

I have create Scope different between each client and one server in scope_info table in DB. Once i sync with first client on filter condition it work correct but on changing filter condition with another client still it sync same data as i get previously. My code as given below :
Here Value is Unique Identity of Client.
Code:
ArrayList UnSyncTable = new ArrayList();
SqlConnection clientConn = new SqlConnection(ClientString);
SqlConnection serverConn = new SqlConnection(ServerString);
for (int i = 0; i < ClientDs.Tables[0].Rows.Count; i++)
{
#region Start Sync
//////////////////////////////////////////////////////////////////////////////////
if (serverConn.State == ConnectionState.Closed)
{
serverConn.Open();
}
if (clientConn.State == ConnectionState.Closed)
{
clientConn.Open();
}
try
{
#region Step1 for ServerSide
DbSyncScopeDescription scopeDesc = new DbSyncScopeDescription(ClientDs.Tables[0].Rows[i][0].ToString() + "_SyncScope" + Value);
DbSyncTableDescription tableDesc = SqlSyncDescriptionBuilder.GetDescriptionForTable(ClientDs.Tables[0].Rows[i][0].ToString(), serverConn);
scopeDesc.Tables.Add(tableDesc);
SqlSyncScopeProvisioning serverProvision = new SqlSyncScopeProvisioning(serverConn, scopeDesc);
serverProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);
#region Filter Condition
if (DBFilteredTables.Contains(ClientDs.Tables[0].Rows[i][0].ToString()))
{
serverProvision.SetCreateTableDefault(DbSyncCreationOption.Skip);
serverProvision.Tables[ClientDs.Tables[0].Rows[i][0].ToString()].AddFilterColumn(AttributeName);
serverProvision.Tables[ClientDs.Tables[0].Rows[i][0].ToString()].FilterClause = "[side].[" + AttributeName + "] =" + Value;
}
#endregion
// start the provisioning process
serverProvision.Apply();
#endregion
}
catch
{
}
try
{
#region Step2 for ClientSide
DbSyncScopeDescription scopeDesc1 = SqlSyncDescriptionBuilder.GetDescriptionForScope(ClientDs.Tables[0].Rows[i][0].ToString() + "_SyncScope" + Value, serverConn);
SqlSyncScopeProvisioning clientProvision = new SqlSyncScopeProvisioning(clientConn, scopeDesc1);
clientProvision.Apply();
#endregion
}
catch
{
}
try
{
#region Step3
SyncOrchestrator syncOrchestrator = new SyncOrchestrator();
syncOrchestrator.LocalProvider = new SqlSyncProvider(ClientDs.Tables[0].Rows[i][0].ToString() + "_SyncScope" + Value, clientConn);
syncOrchestrator.RemoteProvider = new SqlSyncProvider(ClientDs.Tables[0].Rows[i][0].ToString() + "_SyncScope" + Value, serverConn);
if (SyncCondition == 1)
syncOrchestrator.Direction = SyncDirectionOrder.Download;
else if (SyncCondition == 2)
syncOrchestrator.Direction = SyncDirectionOrder.DownloadAndUpload;
else if (SyncCondition == 3)
syncOrchestrator.Direction = SyncDirectionOrder.Upload;
else if (SyncCondition == 4)
syncOrchestrator.Direction = SyncDirectionOrder.UploadAndDownload;
((SqlSyncProvider)syncOrchestrator.LocalProvider).ApplyChangeFailed += new EventHandler<DbApplyChangeFailedEventArgs>(Program_ApplyChangeFailed);
SyncOperationStatistics syncStats = syncOrchestrator.Synchronize();
//print statistics
string Msg = "Start Time : " + syncStats.SyncStartTime + "\n";
Msg += "Table Name : " + ClientDs.Tables[0].Rows[i][0].ToString() + "\n";
Msg += "Total Changes Uploaded : " + syncStats.UploadChangesTotal + "\n";
Msg += "Total Changes Downloaded : " + syncStats.DownloadChangesTotal + "\n";
Msg += "Complete Time : " + syncStats.SyncEndTime + "\n";
#endregion
}
catch
{
UnSyncTable.Add(ClientDs.Tables[0].Rows[i][0].ToString());
}
#endregion
}