Tutorial_06_Collections() { //---------------------------------------------------------------------------------------------------------- // Create a Stash Client StashClient <EmployeeSkills> client = StashConfiguration.GetClient <EmployeeSkills>(); client.CreateTableIfNotExist(); //---------------------------------------------------------------------------------------------------------- // Lets create an instance of the class we what to 'stash' const string departmentDev = "Dev"; const string ssn = "123456789"; EmployeeSkills dataWritten = new EmployeeSkills { Department = departmentDev, EmployeeId = Guid.NewGuid().ToString(), Name = "John Doe", SkillLevel = 8, DateOfBirth = new DateTime(1990, 1, 1), SSN = ssn, Salutation = Salutation.Ms }; // update the private field dataWritten.SetAnnualSalary(); // Populate Languages, certification and salary history dataWritten.Languages = new List <ProgramingLanguages> { ProgramingLanguages.Assembly, ProgramingLanguages.VisualBasic }; const string cert0 = "MSSQL", cert1 = "MSCPP", cert2 = "MSRP"; dataWritten.Certifications = new ArrayList { cert0, cert1, cert2 }; dataWritten.SalaryHistory = new SalaryInfo[] { new SalaryInfo { DateStart = new DateTime(2009, 1, 1), DateEnd = new DateTime(2010, 1, 1), Salary = 100000 }, new SalaryInfo { DateStart = new DateTime(2010, 1, 1), DateEnd = new DateTime(2012, 1, 1), Salary = 110000 }, }; dataWritten.MysteryNumbers = new int[] { 3, 2, 1, 0 }; //---------------------------------------------------------------------------------------------------------- // Stash it client.Insert(dataWritten); //---------------------------------------------------------------------------------------------------------- // Read back the data EmployeeSkills dataRead = client.Get(dataWritten.Department, dataWritten.EmployeeId); //---------------------------------------------------------------------------------------------------------- // Verify we got back what we put in Assert.IsTrue(dataWritten.Equals(dataRead)); //---------------------------------------------------------------------------------------------------------- // Verify exactly what was written to table storage by using the Generic Pool class we wrote // earlier. // set this up to target the correct table storage entity set StashClient <GenericPool> clientGenericPool = StashConfiguration.GetClient <GenericPool>( new StashClientOptions { OverrideEntitySetName = o => "EmployeeSkills", OverrideEntitySetNameIsDynamic = false, Feedback = StashConfiguration.TraceFeedback, }); GenericPool dataPool = clientGenericPool.Get( dataRead.Department, dataRead.EmployeeId); // All collection items are suffixed with the index base 0, in the format "_000". // Because the "_" is used for demarcating collection indexes, explicit defined members are not allowed // to have the embedded "_" character in the table property name. // Test for languages Assert.IsTrue( dataPool.Pool.Where( kv => kv.Key == "Languages_000" && ((ProgramingLanguages)kv.Value == ProgramingLanguages.Assembly)).ToList().Count == 1); Assert.IsTrue( dataPool.Pool.Where( kv => kv.Key == "Languages_001" && ((ProgramingLanguages)kv.Value == ProgramingLanguages.VisualBasic)).ToList().Count == 1); // Test for certification Assert.IsTrue( dataPool.Pool.Where( kv => kv.Key == "Certifications_000" && ((string)kv.Value == cert0)).ToList().Count == 1); Assert.IsTrue( dataPool.Pool.Where( kv => kv.Key == "Certifications_001" && ((string)kv.Value == cert1)).ToList().Count == 1); Assert.IsTrue( dataPool.Pool.Where( kv => kv.Key == "Certifications_002" && ((string)kv.Value == cert2)).ToList().Count == 1); // Test salary history - key only Assert.IsTrue( dataPool.Pool.Where( kv => kv.Key == "SalaryHistory_000").ToList().Count == 1); Assert.IsTrue( dataPool.Pool.Where( kv => kv.Key == "SalaryHistory_001").ToList().Count == 1); // Mystery numbers ... well they were persisted using the DataContract Serializer // and persisted as XML as a single table property. Assert.IsTrue( dataPool.Pool.Where( kv => kv.Key == "MysteryNumbers").ToList().Count == 1); //---------------------------------------------------------------------------------------------------------- // now delete the entity client.Delete( departmentDev, dataWritten.EmployeeId); //---------------------------------------------------------------------------------------------------------- // And verify that it was actually deleted // by attempting to read back the data var queryable = from imp in client.CreateQuery() where imp.Department == dataWritten.Department && imp.EmployeeId == dataWritten.EmployeeId select imp; Assert.IsTrue(queryable.ToList().Count == 0); //---------------------------------------------------------------------------------------------------------- // So far so good. This concludes this part of the tutorial. Go Stash! }
Tutorial_07_LargeData() { //---------------------------------------------------------------------------------------------------------- // Create Stash Client StashClient <EmployeeResume> client = StashConfiguration.GetClient <EmployeeResume>(); client.CreateTableIfNotExist(); //---------------------------------------------------------------------------------------------------------- // Lets create an instance of the class we what to 'stash' const string departmentDev = "Dev"; EmployeeResume dataWritten = new EmployeeResume { Department = departmentDev, EmployeeId = Guid.NewGuid().ToString(), // 1 char = 2 bytes so this random string is 2.5 time the size of a table property Text = BuildString((int)(32 * 1024 * 2.5)), // almost 2 time the size of a table property Photograph = new byte[(int)(64 * 1024 * 1.9)], }; // generate random bytes for the photograph (new Random()).NextBytes(dataWritten.Photograph); //---------------------------------------------------------------------------------------------------------- // Stash it client.Insert(dataWritten); //---------------------------------------------------------------------------------------------------------- // Read back the data EmployeeResume dataRead = client.Get(dataWritten.Department, dataWritten.EmployeeId); //---------------------------------------------------------------------------------------------------------- // Verify we got back what we put in Assert.IsTrue(dataWritten.Equals(dataRead)); //---------------------------------------------------------------------------------------------------------- // Verify exactly what was written to table storage by using the Generic Pool class we wrote // earlier. // set this up to target the correct table storage entity set StashClient <GenericPool> clientGenericPool = StashConfiguration.GetClient <GenericPool>( new StashClientOptions { OverrideEntitySetName = o => typeof(EmployeeResume).Name, OverrideEntitySetNameIsDynamic = false, Feedback = StashConfiguration.TraceFeedback, }); GenericPool dataPool = clientGenericPool.Get( dataRead.Department, dataRead.EmployeeId); // All split items are suffixed with the index base A, in the format "_A". // Because the "_" is used for demarcating collection indexes, explicit defined members are not allowed // to have the embedded "_" character in the table property name. // Test for Text Assert.IsTrue( dataPool.Pool.Where( kv => kv.Key.IndexOf("Text_") == 0).ToList().Count == 3); Assert.IsTrue( dataPool.Pool.Where( kv => kv.Key.IndexOf("Photograph_") == 0).ToList().Count == 2); //---------------------------------------------------------------------------------------------------------- // now delete the entity client.Delete( departmentDev, dataWritten.EmployeeId); //---------------------------------------------------------------------------------------------------------- // And verify that it was actually deleted // by attempting to read back the data var queryable = from imp in client.CreateQuery() where imp.Department == dataWritten.Department && imp.EmployeeId == dataWritten.EmployeeId select imp; Assert.IsTrue(queryable.ToList().Count == 0); //---------------------------------------------------------------------------------------------------------- // So far so good. This concludes this part of the tutorial. Go Stash! }
Tutorial_04_DictionaryPool() { //---------------------------------------------------------------------------------------------------------- // Create a Stash Client for the Employee class StashClient <Employee> clientEmployee = StashConfiguration.GetClient <Employee>(); clientEmployee.CreateTableIfNotExist(); //---------------------------------------------------------------------------------------------------------- // Create an StashClient for the generic pool class, // Since we want to read and write to the Employee table, notice how we setup the correct EntityName in // the StashClientOptions. Otherwise the azure table implied would be "GenericPool". // // The call back method of naming the table has flexible capabilities. It can be used to determine // the table name dynamically based on the data in the object instance. // In this case it is used statically and called only once. StashClient <GenericPool> clientGenericPool = StashConfiguration.GetClient <GenericPool>( new StashClientOptions { OverrideEntitySetName = o => "Employee", OverrideEntitySetNameIsDynamic = false, Feedback = StashConfiguration.TraceFeedback, }); //---------------------------------------------------------------------------------------------------------- // Stash an Employee const string departmentDev = "Dev"; Employee dataEmployee = new Employee { Department = departmentDev, EmployeeId = Guid.NewGuid().ToString(), Name = "John Doe", SkillLevel = 8, DateOfBirth = new DateTime(1990, 1, 1) }; dataEmployee.SetAnnualSalary(); clientEmployee.Insert(dataEmployee); //---------------------------------------------------------------------------------------------------------- // and read it back thru the GenericPool GenericPool dataPool = clientGenericPool.Get( dataEmployee.Department, dataEmployee.EmployeeId); //---------------------------------------------------------------------------------------------------------- // Verify we got back what we put in via the Employee type. Assert.IsTrue( dataPool.PrimaryKey == dataEmployee.Department && dataPool.SecondaryKey == dataEmployee.EmployeeId && dataPool.Pool["AnnualSalary"].Equals(dataEmployee.GetAnnualSalary()) && dataPool.Pool["Birthday"].Equals(dataEmployee.DateOfBirth) && dataPool.Pool["SkillLevel"].Equals(dataEmployee.SkillLevel) && dataPool.Pool["Name"].Equals(dataEmployee.Name) && dataPool.Pool.Count == 4 + 1); // + 1 to the ETag //---------------------------------------------------------------------------------------------------------- // Make a few changes and update dataPool.Pool["Name"] = "Lucifure"; // name change dataPool.Pool["Unique"] = Guid.NewGuid(); // new field clientGenericPool.Update(dataPool); // Note: Updates, Merges etc keep the original objects in sync with the latest ETags. // Even if an ETag is not specified for the type, if the type supports a Pool, // the ETag is maintained and synched in the pool //---------------------------------------------------------------------------------------------------------- // Read back the data GenericPool dataPoolRead = clientGenericPool.CreateQuery() .Where(imp => imp.PrimaryKey == dataEmployee.Department && imp.SecondaryKey == dataEmployee.EmployeeId) .FirstOrDefault(); //---------------------------------------------------------------------------------------------------------- // and verify that we got back what we put in Assert.IsTrue( dataPool.PrimaryKey == dataPoolRead.PrimaryKey && dataPool.SecondaryKey == dataPoolRead.SecondaryKey && StashHelper.DictionaryEquals( dataPool.Pool, dataPoolRead.Pool)); //---------------------------------------------------------------------------------------------------------- // Merge can be performed very efficiently with a StashPool. Only include the tables properties // to be merge in the dictionary. No need to null out members or defined nullable value type members. // Create a new pool with just the objects of interest Dictionary <string, object> pool = new Dictionary <string, object>(); // save the current etag (for now and later) string etagPreMerge = dataPoolRead.Pool[Literal.ETag].ToString(); pool["Name"] = "Stash"; // new value to merge pool[Literal.ETag] = etagPreMerge; // get the ETag too // create a new pool object for merging. GenericPool dataPoolMerged = new GenericPool { PrimaryKey = dataPoolRead.PrimaryKey, SecondaryKey = dataPoolRead.SecondaryKey, Pool = pool }; clientGenericPool.Merge(dataPoolMerged, ETagMatch.Must); // force ETag matching. // read back and verify GenericPool dataPoolMergedRead = clientGenericPool.Get( dataPoolMerged.PrimaryKey, dataPoolMerged.SecondaryKey); // validate Assert.IsTrue(dataPoolMergedRead.Pool.Count == dataPoolRead.Pool.Count && dataPoolMergedRead.Pool["Name"] as String == "Stash"); //---------------------------------------------------------------------------------------------------------- // attempt to merge again, replacing the current ETag with the old one. bool isSuccess; try { // use the defunct etag to exhibit this dataPoolMerged.Pool[Literal.ETag] = etagPreMerge; clientGenericPool.Merge(dataPoolMerged); isSuccess = false; } catch (Exception ex) { // Merge fails because the ETag was old and did not match. Assert.IsTrue((ex as StashException).Error == StashError.ETagMatchFailed); isSuccess = true; } Assert.IsTrue(isSuccess); //---------------------------------------------------------------------------------------------------------- // attempt to merge yet again, this time by disabling ETag matching. clientGenericPool.Merge(dataPoolMerged, ETagMatch.Unconditional); //---------------------------------------------------------------------------------------------------------- // now attempt to delete the entity try { clientGenericPool.Delete(dataPoolMergedRead); // Implicit ETag matching, will make this fail too // because the last update changed the ETag isSuccess = false; } catch (Exception ex) { Assert.IsTrue((ex as StashException).Error == StashError.ETagMatchFailed); isSuccess = true; } Assert.IsTrue(isSuccess); //---------------------------------------------------------------------------------------------------------- // Do an unconditional delete clientGenericPool.DeleteUnconditional(dataPoolMergedRead); //---------------------------------------------------------------------------------------------------------- // And verify that it was actually deleted // by attempting to read back the data var queryable = from emp in clientEmployee.CreateQuery() where emp.Department == dataEmployee.Department && emp.EmployeeId == dataEmployee.EmployeeId select emp; Assert.IsTrue(queryable.ToList().Count == 0); //---------------------------------------------------------------------------------------------------------- // So far so good. This concludes this part of the tutorial. Go Stash! }
Tutorial_05_Morphing_EmployeeInfo() { //---------------------------------------------------------------------------------------------------------- // Create a Stash Client StashClient <EmployeeInfo> client = StashConfiguration.GetClient <EmployeeInfo>(); client.CreateTableIfNotExist(); //---------------------------------------------------------------------------------------------------------- // Create an instance of the class we what to Stash const string departmentDev = "Dev"; const string ssn = "123456789"; EmployeeInfo dataWritten = new EmployeeInfo { Department = departmentDev, EmployeeId = Guid.NewGuid().ToString(), Name = "John Doe", SkillLevel = 8, DateOfBirth = new DateTime(1990, 1, 1), SSN = ssn, Salutation = Salutation.Dr }; // update the private field dataWritten.SetAnnualSalary(); //---------------------------------------------------------------------------------------------------------- // Stash it client.Insert(dataWritten); //---------------------------------------------------------------------------------------------------------- // Read back the data EmployeeInfo dataRead = client.Get(dataWritten.Department, dataWritten.EmployeeId); //---------------------------------------------------------------------------------------------------------- // Verify we got back what we put in Assert.IsTrue(dataWritten.Equals(dataRead)); //---------------------------------------------------------------------------------------------------------- // Now let us verify exactly what was written to table storage by using the Generic Pool class we wrote // earlier. // set this up to target the correct table storage entity set StashClient <GenericPool> clientGenericPool = StashConfiguration.GetClient <GenericPool>( new StashClientOptions { OverrideEntitySetName = o => "EmployeeInfo", OverrideEntitySetNameIsDynamic = false, Feedback = StashConfiguration.TraceFeedback, }); GenericPool dataPool = clientGenericPool.Get( dataRead.Department, dataRead.EmployeeId); // validate that the SSN value got morphed in to a byte[] Assert.IsTrue(dataPool.Pool["SSN"].GetType() == typeof(byte[])); //---------------------------------------------------------------------------------------------------------- // Change the Skill level and update the Stash dataWritten.SkillLevel += 1; dataWritten.SetAnnualSalary(); // force an unconditional update since, dataWritten does not have a ETag. // Optionally copy over the ETag from dataRead. client.Update(dataWritten, ETagMatch.Unconditional); //---------------------------------------------------------------------------------------------------------- // Read back the data but this time lets use LINQ dataRead = client.CreateQuery() .Where(imp => imp.Department == departmentDev && imp.EmployeeId == dataWritten.EmployeeId) .FirstOrDefault(); //---------------------------------------------------------------------------------------------------------- // Again verify that we got back what we put in Assert.IsTrue(dataWritten.Equals(dataRead)); //---------------------------------------------------------------------------------------------------------- // now delete the entity client.Delete( departmentDev, dataWritten.EmployeeId); //---------------------------------------------------------------------------------------------------------- // And verify that it was actually deleted // by attempting to read back the data var queryable = from imp in client.CreateQuery() where imp.Department == dataWritten.Department && imp.EmployeeId == dataWritten.EmployeeId select imp; Assert.IsTrue(queryable.ToList().Count == 0); //---------------------------------------------------------------------------------------------------------- // So far so good. This concludes this part of the tutorial. Go Stash! }