public async Task InitializeSessionExists() { // Setup: Create an edit data service with a session already defined var eds = new EditDataService(null, null, null); var session = await GetDefaultSession(); eds.ActiveSessions[Constants.OwnerUri] = session; // If: I request to init a session for an owner URI that already exists var initParams = new EditInitializeParams { ObjectName = "testTable", OwnerUri = Constants.OwnerUri, ObjectType = "Table", Filters = new EditInitializeFiltering() }; var efv = new EventFlowValidator <EditInitializeResult>() .AddStandardErrorValidation() .Complete(); await eds.HandleInitializeRequest(initParams, efv.Object); // Then: // ... An error event should have been sent efv.Validate(); // ... The original session should still be there Assert.Equal(1, eds.ActiveSessions.Count); Assert.Equal(session, eds.ActiveSessions[Constants.OwnerUri]); }
private async Task InitializeInternal(EditInitializeParams initParams, Connector connector, QueryRunner queryRunner, Func <Task> successHandler, Func <Exception, Task> failureHandler) { try { // Step 1) Look up the SMO metadata string[] namedParts = GetEditTargetName(initParams); objectMetadata = metadataFactory.GetObjectMetadata(await connector(), namedParts, initParams.ObjectType); // Step 2) Get and execute a query for the rows in the object we're looking up EditSessionQueryExecutionState state = await queryRunner(ConstructInitializeQuery(objectMetadata, initParams.Filters)); if (state.Query == null) { string message = state.Message ?? SR.EditDataQueryFailed; throw new Exception(message); } // Step 3) Setup the internal state associatedResultSet = ValidateQueryForSession(state.Query); NextRowId = associatedResultSet.RowCount; EditCache = new ConcurrentDictionary <long, RowEditBase>(); IsInitialized = true; objectMetadata.Extend(associatedResultSet.Columns); // Step 4) Return our success await successHandler(); } catch (Exception e) { await failureHandler(e); } }
[InlineData(Common.OwnerUri, "table", null)] // Null object type public async Task InitializeNullParams(string ownerUri, string objName, string objType) { // Setup: Create an edit data service without a session var eds = new EditDataService(null, null, null); // If: // ... I have init params with a null parameter var initParams = new EditInitializeParams { ObjectName = objName, OwnerUri = ownerUri, ObjectType = objType }; // ... And I initialize an edit session with that var efv = new EventFlowValidator <EditInitializeResult>() .AddStandardErrorValidation() .Complete(); await eds.HandleInitializeRequest(initParams, efv.Object); // Then: // ... An error event should have been raised efv.Validate(); // ... There should not be a session Assert.Empty(eds.ActiveSessions); }
internal async Task HandleInitializeRequest(EditInitializeParams initParams, RequestContext <EditInitializeResult> requestContext) { Func <Exception, Task> executionFailureHandler = (e) => SendSessionReadyEvent(requestContext, initParams.OwnerUri, false, e.Message); Func <Task> executionSuccessHandler = () => SendSessionReadyEvent(requestContext, initParams.OwnerUri, true, null); EditSession.Connector connector = () => connectionService.GetOrOpenConnection(initParams.OwnerUri, ConnectionType.Edit, alwaysPersistSecurity: true); EditSession.QueryRunner queryRunner = q => SessionInitializeQueryRunner(initParams.OwnerUri, requestContext, q); try { // Make sure we have info to process this request Validate.IsNotNullOrWhitespaceString(nameof(initParams.OwnerUri), initParams.OwnerUri); Validate.IsNotNullOrWhitespaceString(nameof(initParams.ObjectName), initParams.ObjectName); Validate.IsNotNullOrWhitespaceString(nameof(initParams.ObjectType), initParams.ObjectType); // Create a session and add it to the session list EditSession session = new EditSession(metadataFactory); if (!ActiveSessions.TryAdd(initParams.OwnerUri, session)) { throw new InvalidOperationException(SR.EditDataSessionAlreadyExists); } // Initialize the session session.Initialize(initParams, connector, queryRunner, executionSuccessHandler, executionFailureHandler); // Send the result await requestContext.SendResult(new EditInitializeResult()); } catch (Exception e) { await requestContext.SendError(e.Message); } }
public static string[] GetEditTargetName(EditInitializeParams initParams) { // Step 1) Look up the SMO metadata if (initParams.SchemaName != null) { return(new [] { initParams.SchemaName, initParams.ObjectName }); } return(SqlScriptFormatter.DecodeMultipartIdenfitier(initParams.ObjectName)); }
public void InitializeNullParams(EditInitializeParams initParams, EditSession.Connector c, EditSession.QueryRunner qr, Func <Task> sh, Func <Exception, Task> fh) { // Setup: // ... Create a session that hasn't been initialized Mock <IEditMetadataFactory> emf = new Mock <IEditMetadataFactory>(); EditSession s = new EditSession(emf.Object); // If: I initialize it with a missing parameter // Then: It should throw an exception Assert.ThrowsAny <ArgumentException>(() => s.Initialize(initParams, c, qr, sh, fh)); }
[InlineData("schema.table", null, new [] { "schema", "table" })] // Split object name into schema public void ShouldUseSchemaNameIfDefined(string objName, string schemaName, string[] expectedNameParts) { // Setup: Create an edit data service without a session var eds = new EditDataService(null, null, null); // If: // ... I have init params with an object and schema parameter var initParams = new EditInitializeParams { ObjectName = objName, SchemaName = schemaName, OwnerUri = Common.OwnerUri, ObjectType = "table" }; // ... And I get named parts for that string[] nameParts = EditSession.GetEditTargetName(initParams); // Then: Assert.Equal(expectedNameParts, nameParts); }
/// <summary> /// Initializes the edit session, asynchronously, by retrieving metadata about the table to /// edit and querying the table for the rows of the table. /// </summary> /// <param name="initParams">Parameters for initializing the edit session</param> /// <param name="connector">Delegate that will return a DbConnection when executed</param> /// <param name="queryRunner"> /// Delegate that will run the requested query and return a /// <see cref="EditSessionQueryExecutionState"/> object on execution /// </param> /// <param name="successHandler">Func to call when initialization has completed successfully</param> /// <param name="errorHandler">Func to call when initialization has completed with errors</param> /// <exception cref="InvalidOperationException"> /// When session is already initialized or in progress of initializing /// </exception> public void Initialize(EditInitializeParams initParams, Connector connector, QueryRunner queryRunner, Func <Task> successHandler, Func <Exception, Task> errorHandler) { if (IsInitialized) { throw new InvalidOperationException(SR.EditDataSessionAlreadyInitialized); } if (InitializeTask != null) { throw new InvalidOperationException(SR.EditDataSessionAlreadyInitializing); } Validate.IsNotNullOrWhitespaceString(nameof(initParams.ObjectName), initParams.ObjectName); Validate.IsNotNullOrWhitespaceString(nameof(initParams.ObjectType), initParams.ObjectType); Validate.IsNotNull(nameof(initParams.Filters), initParams.Filters); Validate.IsNotNull(nameof(connector), connector); Validate.IsNotNull(nameof(queryRunner), queryRunner); Validate.IsNotNull(nameof(successHandler), successHandler); Validate.IsNotNull(nameof(errorHandler), errorHandler); // Start up the initialize process InitializeTask = InitializeInternal(initParams, connector, queryRunner, successHandler, errorHandler); }
public static string[] GetEditTargetName(EditInitializeParams initParams) { return(initParams.SchemaName != null ? new [] { initParams.SchemaName, initParams.ObjectName } : FromSqlScript.DecodeMultipartIdentifier(initParams.ObjectName)); }
public async Task InitializeSessionSuccess() { // Setup: // .. Create a mock query var mockQueryResults = QueryExecution.Common.StandardTestDataSet; var cols = mockQueryResults[0].Columns; // ... Create a metadata factory that will return some generic column information var etm = Common.GetStandardMetadata(cols.ToArray()); Mock <IEditMetadataFactory> emf = new Mock <IEditMetadataFactory>(); emf.Setup(f => f.GetObjectMetadata(It.IsAny <DbConnection>(), It.IsAny <string[]>(), It.IsAny <string>())) .Returns(etm); // ... Create a query execution service that will return a successful query var qes = QueryExecution.Common.GetPrimedExecutionService(mockQueryResults, true, false, false, null); // ... Create a connection service that doesn't throw when asked for a connection var cs = new Mock <ConnectionService>(); cs.Setup(s => s.GetOrOpenConnection(It.IsAny <string>(), It.IsAny <string>(), It.IsAny <bool>())) .Returns(Task.FromResult <DbConnection>(null)); // ... Create an edit data service that has mock providers var eds = new EditDataService(qes, cs.Object, emf.Object); // If: I request to initialize an edit data session var initParams = new EditInitializeParams { ObjectName = "testTable", OwnerUri = Constants.OwnerUri, ObjectType = "Table", Filters = new EditInitializeFiltering() }; var efv = new EventFlowValidator <EditInitializeResult>() .AddResultValidation(Assert.NotNull) .AddEventValidation(BatchStartEvent.Type, Assert.NotNull) .AddEventValidation(ResultSetCompleteEvent.Type, Assert.NotNull) .AddEventValidation(MessageEvent.Type, Assert.NotNull) .AddEventValidation(BatchCompleteEvent.Type, Assert.NotNull) .AddEventValidation(QueryCompleteEvent.Type, Assert.NotNull) .AddEventValidation(EditSessionReadyEvent.Type, esrp => { Assert.NotNull(esrp); Assert.Equal(Constants.OwnerUri, esrp.OwnerUri); Assert.True(esrp.Success); Assert.Null(esrp.Message); }) .Complete(); await eds.HandleInitializeRequest(initParams, efv.Object); await eds.ActiveSessions[Constants.OwnerUri].InitializeTask; // Then: // ... The event should have been received successfully efv.Validate(); // ... The session should have been created Assert.Equal(1, eds.ActiveSessions.Count); Assert.True(eds.ActiveSessions.Keys.Contains(Constants.OwnerUri)); }