// tstore5.cpp -- Regression test program, storage tests, part 5 // $Id$ // This is part of Metakit, see http://www.equi4.com/metakit/ #include "regress.h" void TestStores5() { B(s40, LoadFrom after commit, 0) W(s40a); { c4_IntProp p1 ("p1"); { // create datafile by streaming out c4_Storage s1; s1.SetStructure("a[p1:I]"); c4_View v1 = s1.View("a"); v1.Add(p1 [123]); A(p1 (v1[0]) == 123); A(v1.GetSize() == 1); c4_FileStream fs1 (fopen("s40a", "wb"), true); s1.SaveTo(fs1); } { // it should load just fine c4_Storage s2; c4_FileStream fs1 (fopen("s40a", "rb"), true); bool ok = s2.LoadFrom(fs1); A(ok); c4_View v1 = s2.View("a"); A(p1 (v1[0]) == 123); A(v1.GetSize() == 1); } { // open the datafile and commit a change c4_Storage s3 ("s40a", true); c4_View v1 = s3.View("a"); A(p1 (v1[0]) == 123); A(v1.GetSize() == 1); p1 (v1[0]) = 456; s3.Commit(); A(p1 (v1[0]) == 456); A(v1.GetSize() == 1); } { // it should load fine and show the last changes c4_Storage s4; c4_FileStream fs1 (fopen("s40a", "rb"), true); bool ok = s4.LoadFrom(fs1); A(ok); c4_View v1 = s4.View("a"); A(p1 (v1[0]) == 456); A(v1.GetSize() == 1); } { // it should open just fine in the normal way as well c4_Storage s5 ("s40a", false); c4_View v1 = s5.View("a"); A(p1 (v1[0]) == 456); A(v1.GetSize() == 1); } } D(s40a); R(s40a); E; // 2002-03-13: failure on Win32, Modify calls base class GetNthMemoCol B(s41, Partial modify blocked, 0) W(s41a); { c4_BytesProp p1 ("p1"); c4_Storage s1 ("s41a", true); c4_View v1 = s1.GetAs("a[_B[p1:B]]"); // custom viewers did not support partial access in 2.4.3 c4_View v2 = v1.Blocked(); s1.Commit(); v2.SetSize(1); c4_BytesRef m = p1 (v2[0]); m.Modify(c4_Bytes ("abcdefgh", 8), 0); s1.Commit(); } D(s41a); R(s41a); E; B(s42, Get descriptions, 0) { c4_Storage s1; s1.SetStructure("a[p1:I],b[p2:S]"); c4_String x1 = s1.Description(); A(x1 == "a[p1:I],b[p2:S]"); c4_String x2 = s1.Description("b"); A(x2 == "p2:S"); const char* cp = s1.Description("c"); A(cp == 0); } E; // 2002-04-24: VPI subview ints clobbered B(s43, View reuse after sub-byte ints, 0) W(s43a); { c4_IntProp p1 ("p1"); c4_Storage s1 ("s43a", true); c4_View v1 = s1.GetAs("a[p1:I]"); v1.Add(p1 [0]); v1.Add(p1 [1]); s1.Commit(); v1.SetSize(1); // 1 is an even trickier bug than 0 s1.Commit(); // adding the following two lines works around the 2.4.4 bug //s1.Rollback(); //v1 = s1.GetAs("a[p1:I]"); v1.Add(p1 [12345]); s1.Commit(); //int n = p1 (v1[1]); A(p1 (v1[1]) == 12345); } D(s43a); R(s43a); E; B(s44, Bad memo free space, 0) W(s44a); { c4_IntProp p1 ("p1"); c4_BytesProp p2 ("p2"); c4_Storage s1 ("s44a", true); c4_View v1 = s1.GetAs("a[p1:I,p2:B]"); c4_Bytes data; t4_byte* p = data.SetBuffer(12345); for (int i = 0; i < data.Size(); ++i) p[i] = (t4_byte) i; v1.Add(p2 [data]); s1.Commit(); p1 (v1[0]) = 1; s1.Commit(); p1 (v1[0]) = 0; s1.Commit(); c4_Bytes temp = p2 (v1[0]); A(temp == data); // this failed in 2.4.5 } D(s44a); R(s44a); E; B(s45, Bad subview memo free space, 0) W(s45a); { c4_IntProp p1 ("p1"); c4_ViewProp p2 ("p2"); c4_BytesProp p3 ("p3"); c4_Storage s1 ("s45a", true); c4_View v1 = s1.GetAs("a[p1:I,p2[p3:B]]"); c4_Bytes data; t4_byte* p = data.SetBuffer(12345); for (int i = 0; i < data.Size(); ++i) p[i] = (t4_byte) i; v1.SetSize(1); c4_View v2 = p2 (v1[0]); v2.Add(p3 [data]); s1.Commit(); p1 (v1[0]) = 1; s1.Commit(); p1 (v1[0]) = 0; s1.Commit(); c4_View v3 = p2 (v1[0]); c4_Bytes temp = p3 (v3[0]); A(temp == data); // this failed in 2.4.5 } D(s45a); R(s45a); E; B(s46, LoadFrom after commit, 0) W(s46a); { c4_IntProp p1 ("p1"); { c4_Storage s1 ("s46a", true); s1.SetStructure("a[p1:I]"); c4_View v1 = s1.View("a"); v1.Add(p1 [11]); v1.Add(p1 [22]); v1.Add(p1 [33]); v1.Add(p1 [44]); v1.Add(p1 [55]); v1.Add(p1 [66]); v1.Add(p1 [77]); v1.Add(p1 [88]); v1.Add(p1 [99]); s1.Commit(); } { c4_Storage s2 ("s46a", true); c4_View v2 = s2.View("a"); v2.Add(p1 [1000]); // force 1->2 byte ints v2.InsertAt(7, c4_Row ()); v2.InsertAt(4, c4_Row ()); //for (int i = 6; i <= 9; ++i) printf("%d\n", (int) p1 (v2[i])); A(p1 (v2[6]) == 66); A(p1 (v2[8]) == 0); A(p1 (v2[9]) == 88); A(p1 (v2[7]) == 77); // this failed in 2.4.6 s2.Commit(); } } D(s46a); R(s46a); E; // 2004-01-16 bad property type crashes MK 2.4.9.2 and before // this hits an assertion in debug mode, so then it has to be disabled B(s47, Defining bad property type, 0) { c4_IntProp p1 ("p2"); c4_Storage s1; #if defined(NDEBUG) c4_View v1 = s1.GetAs("v1[p1:A]"); #else // assertions are enabled, turn this into a dummy test instead c4_View v1 = s1.GetAs("v1[p1:I]"); #endif v1.Add(p1 [123]); A(v1.GetSize() == 1); A(p1 (v1 [0]) == 123); } E; // 2004-01-18 file damaging bug, when resizing a comitted subview // to empty, committing, and then resizing back to containing data. // Fortunately this usage pattern never happened in blocked views! B(s48, Resize subview to zero and back, 0) W(s48a); W(s48b); { { c4_Storage s1 ("s48a", true); c4_View v1 = s1.GetAs("v1[v2[p1:I]]"); v1.SetSize(1); s1.Commit(); } { c4_Storage s1 ("s48a", true); c4_View v1 = s1.View("v1"); v1.SetSize(0); s1.Commit(); // the problem is that the in-memory copy has forgotten that it // has nothing left on disk, and a comparison is done later on to // avoid saving unmodified data - the bad decision is that data has // not changed, but actually it has and must be reallocated! // (fixes are in c4_FormatV::Insert and c4_FormatV::Remove) v1.SetSize(1); s1.Commit(); // at this point, the 2.4.9.2 file is corrupt! c4_FileStream fs1 (fopen("s48b", "wb"), true); s1.SaveTo(fs1); } { // using this damaged datafile will then crash c4_Storage s1 ("s48a", false); c4_View v1 = s1.View("v1"); v1.SetSize(2); } } D(s48a); D(s48b); R(s48a); R(s48b); E; // 2004-01-20 better handling of bad input: ignore repeated props B(s49, Specify conflicting properties, 0) W(s49a); { c4_Storage s1 ("s49a", true); c4_View v1 = s1.GetAs("v1[p1:I,p1:S]"); c4_View v2 = s1.GetAs("v2[p1:I,P1:S]"); c4_View v3 = s1.GetAs("v3[v3[^]]"); c4_String x1 = s1.Description(); A(x1 == "v1[p1:I],v2[p1:I],v3[v3[^]]"); s1.Commit(); } D(s49a); E; }