public static async Task <string> Run(GeotabDataOnlyPlanAPI api, string deviceId, string userId) { ConsoleUtility.LogExampleStarted(typeof(AddDriverChangeAsyncExample).Name); string addedDriverChangeId = ""; try { // Set parameter values to apply when adding driver change. DateTime dateTime = DateTime.Now; List <Device> deviceCache = await ExampleUtility.GetAllDevicesAsync(api); List <User> userCache = await ExampleUtility.GetAllUsersAsync(api); Device device = deviceCache.Where(targetDevice => targetDevice.Id.ToString() == deviceId).First(); Driver driver = userCache.Where(targetUser => targetUser.Id.ToString() == userId).First() as Driver; DriverChangeType driverChangeType = DriverChangeType.Driver; ConsoleUtility.LogInfoStart($"Adding driverChange of type '{driverChangeType.ToString()}' for driver '{driver.Id.ToString()}' and device '{device.Id.ToString()}' to database '{api.Credentials.Database}'..."); addedDriverChangeId = await api.AddDriverChangeAsync(dateTime, device, driver, driverChangeType); ConsoleUtility.LogComplete(); ConsoleUtility.LogInfo($"Added driverChange Id: {addedDriverChangeId}"); } catch (Exception ex) { ConsoleUtility.LogError(ex); } ConsoleUtility.LogExampleFinished(typeof(AddDriverChangeAsyncExample).Name); return(addedDriverChangeId); }
private static void CompileInsertUpdateClauses( IStorageDriver storageDriver, DataContainerDescriptor containerDescriptor, RequestExecutionContextCacheInfo cacheInfo, DriverChangeType changeType) { var updates = cacheInfo.ParsedRequest.Modify.UpdateAssignments; var clauses = cacheInfo.ParsedRequest.Modify.InsertUpdateSetClauses; var fields = cacheInfo.ParsedRequest.Modify.ModifiedFields; if (clauses.Count != fields.Count) { throw new Exception(string.Format("Internal error: insert/update clauses count ({0}) does not match count of modified fields ({1})", clauses.Count, fields.Count)); } // compile field assignment clauses (SET clauses or value inserts) for (var ordinal = 0; ordinal < clauses.Count; ordinal++) { var clause = clauses[ordinal]; var field = fields[ordinal]; // for bulk requests, primary key is there but it is only used to lookup the record // for non-bulk requests, primary key should not be in the list of UPDATE clauses if (changeType == DriverChangeType.Update && !cacheInfo.ParsedRequest.IsBulk) { if (!storageDriver.CanUpdateField(field.FieldId)) { throw new Exception(string.Format("Cannot update field {0}/{1} on entity {2}", field.FieldId, field.Name, cacheInfo.ParsedRequest.TargetEntity.Name)); } } // prepare Action compilation context var compilerState = QueryParser.PrepareCompilerState(containerDescriptor, cacheInfo, null); compilerState.CompileToAction = true; // extractor has signature like Func<ClauseEvaluationContext, T> var extractor = clause == null ? QueryParser.CompileFieldValueExtractorClause(compilerState, field, containerDescriptor, cacheInfo, MakeNullableType(field.DbType)) : QueryParser.CompileClause(compilerState, clause, containerDescriptor, cacheInfo, MakeNullableType(field.DbType)); // get the value into local variable, to prevent multiple invokations when row writer checks for null var extractedValue = Expression.Variable(extractor.Type); // now take the extractor and create another method, that will take the value and then put it into the changebuffer's data var changeBufferData = Expression.Field(Expression.Field(compilerState.Context, "ChangeBuffer"), "Data"); var blockBody = Expression.Block( new[] {extractedValue}, Expression.Assign(extractedValue, extractor), DriverRowData.CreateWriteAccessor(extractedValue, changeBufferData, field.DbType, ordinal)); updates.Add( new ParsedRequest.FieldAssignment { Field = field, CompiledExpression = (Action<ClauseEvaluationContext>)QueryParser.CompileClause(blockBody, compilerState) }); } }
private void ExecuteInsertUpdateStatement(RequestExecutionContext context, RequestExecutionBuffer buffer, IDriverDataEnumerator sourceEnumerator, DriverChangeType changeType) { if (sourceEnumerator == null) { return; } buffer.RowsOutput = 0; var cts = context.CancellationTokenSource; var updates = context.ParsedRequest.Modify.UpdateAssignments; context.ClauseEvaluationContext.RowNumber = 0; context.ClauseEvaluationContext.RowNumberInOutput = context.ClauseEvaluationContext.RowNumber; var changeBuffer = context.ClauseEvaluationContext.ChangeBuffer; var changeset = m_storageDriver.CreateChangeset(changeBuffer, context.ParsedRequest.IsBulk); try { changeBuffer.ChangeType = changeType; while (!cts.IsCancellationRequested && sourceEnumerator.MoveNext()) { // if record satisfies WHERE criteria, compute updated values and give them to driver if (ApplyWhereClause(context)) { // make sure we have values for fields in SET expressions sourceEnumerator.FetchAdditionalFields(); BitVector.SetAll(changeBuffer.Data.NotNulls, false); for (var ordinal = 0; ordinal < updates.Count; ordinal++) { if (updates[ordinal].CompiledExpression != null) { updates[ordinal].CompiledExpression(context.ClauseEvaluationContext); } } // this will either take internal entity id from current data row // or from the computed change buffer data (for non-bulk inserts) sourceEnumerator.FetchInternalEntityIdIntoChangeBuffer(changeBuffer, context); m_storageDriver.AddChange(changeset); } // row number is needed for "rownum()" Pql function context.ClauseEvaluationContext.RowNumber++; // output row number is needed for "rownumoutput()" Pql function context.ClauseEvaluationContext.RowNumberInOutput = context.ClauseEvaluationContext.RowNumber; } if (!cts.IsCancellationRequested) { context.RecordsAffected = m_storageDriver.Apply(changeset); } } catch { m_storageDriver.Discard(changeset); throw; } }
private static void CompileInsertUpdateClauses( IStorageDriver storageDriver, DataContainerDescriptor containerDescriptor, RequestExecutionContextCacheInfo cacheInfo, DriverChangeType changeType) { var updates = cacheInfo.ParsedRequest.Modify.UpdateAssignments; var clauses = cacheInfo.ParsedRequest.Modify.InsertUpdateSetClauses; var fields = cacheInfo.ParsedRequest.Modify.ModifiedFields; if (clauses.Count != fields.Count) { throw new Exception(string.Format("Internal error: insert/update clauses count ({0}) does not match count of modified fields ({1})", clauses.Count, fields.Count)); } // compile field assignment clauses (SET clauses or value inserts) for (var ordinal = 0; ordinal < clauses.Count; ordinal++) { var clause = clauses[ordinal]; var field = fields[ordinal]; // for bulk requests, primary key is there but it is only used to lookup the record // for non-bulk requests, primary key should not be in the list of UPDATE clauses if (changeType == DriverChangeType.Update && !cacheInfo.ParsedRequest.IsBulk) { if (!storageDriver.CanUpdateField(field.FieldId)) { throw new Exception(string.Format("Cannot update field {0}/{1} on entity {2}", field.FieldId, field.Name, cacheInfo.ParsedRequest.TargetEntity.Name)); } } // prepare Action compilation context var compilerState = QueryParser.PrepareCompilerState(containerDescriptor, cacheInfo, null); compilerState.CompileToAction = true; // extractor has signature like Func<ClauseEvaluationContext, T> var extractor = clause == null ? QueryParser.CompileFieldValueExtractorClause(compilerState, field, containerDescriptor, cacheInfo, MakeNullableType(field.DbType)) : QueryParser.CompileClause(compilerState, clause, containerDescriptor, cacheInfo, MakeNullableType(field.DbType)); // get the value into local variable, to prevent multiple invokations when row writer checks for null var extractedValue = Expression.Variable(extractor.Type); // now take the extractor and create another method, that will take the value and then put it into the changebuffer's data var changeBufferData = Expression.Field(Expression.Field(compilerState.Context, "ChangeBuffer"), "Data"); var blockBody = Expression.Block( new[] { extractedValue }, Expression.Assign(extractedValue, extractor), DriverRowData.CreateWriteAccessor(extractedValue, changeBufferData, field.DbType, ordinal)); updates.Add( new ParsedRequest.FieldAssignment { Field = field, CompiledExpression = (Action <ClauseEvaluationContext>)QueryParser.CompileClause(blockBody, compilerState) }); } }