1// tstore4.cpp -- Regression test program, storage tests, part 4
2// $Id: tstore4.cpp 1230 2007-03-09 15:58:53Z jcw $
3// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
4
5#include "regress.h"
6
7void TestStores4() {
8  B(s30, Memo storage, 0)W(s30a);
9   {
10    c4_Bytes hi("hi", 2);
11    c4_Bytes gday("gday", 4);
12    c4_Bytes hello("hello", 5);
13
14    c4_MemoProp p1("p1");
15    c4_Storage s1("s30a", 1);
16    s1.SetStructure("a[p1:B]");
17    c4_View v1 = s1.View("a");
18
19    v1.Add(p1[hi]);
20    A(p1(v1[0]) == hi);
21    v1.Add(p1[hello]);
22    A(p1(v1[0]) == hi);
23    A(p1(v1[1]) == hello);
24    v1.InsertAt(1, p1[gday]);
25    A(p1(v1[0]) == hi);
26    A(p1(v1[1]) == gday);
27    A(p1(v1[2]) == hello);
28    s1.Commit();
29    A(p1(v1[0]) == hi);
30    A(p1(v1[1]) == gday);
31    A(p1(v1[2]) == hello);
32
33  }
34  D(s30a);
35  R(s30a);
36  E;
37
38  // this failed in the unbuffered 1.8.5a interim release in Mk4tcl 1.0.5
39  B(s31, Check sort buffer use, 0)W(s31a);
40   {
41    c4_IntProp p1("p1");
42    c4_Storage s1("s31a", 1);
43    s1.SetStructure("a[p1:I]");
44    c4_View v1 = s1.View("a");
45    v1.Add(p1[3]);
46    v1.Add(p1[1]);
47    v1.Add(p1[2]);
48    s1.Commit();
49
50    c4_View v2 = v1.SortOn(p1);
51    A(v2.GetSize() == 3);
52    A(p1(v2[0]) == 1);
53    A(p1(v2[1]) == 2);
54    A(p1(v2[2]) == 3);
55
56  }
57  D(s31a);
58  R(s31a);
59  E;
60
61  // this failed in 1.8.6, fixed 19990828
62  B(s32, Set memo empty or same size, 0)W(s32a);
63   {
64    c4_Bytes empty;
65    c4_Bytes full("full", 4);
66    c4_Bytes more("more", 4);
67
68    c4_MemoProp p1("p1");
69    c4_Storage s1("s32a", 1);
70    s1.SetStructure("a[p1:B]");
71    c4_View v1 = s1.View("a");
72
73    v1.Add(p1[full]);
74    A(p1(v1[0]) == full);
75    s1.Commit();
76    A(p1(v1[0]) == full);
77
78    p1(v1[0]) = empty;
79    A(p1(v1[0]) == empty);
80    s1.Commit();
81    A(p1(v1[0]) == empty);
82
83    p1(v1[0]) = more;
84    A(p1(v1[0]) == more);
85    s1.Commit();
86    A(p1(v1[0]) == more);
87
88    p1(v1[0]) = full;
89    A(p1(v1[0]) == full);
90    s1.Commit();
91    A(p1(v1[0]) == full);
92
93  }
94  D(s32a);
95  R(s32a);
96  E;
97
98  // this failed in 1.8.6, fixed 19990828
99  B(s33, Serialize memo fields, 0)W(s33a);
100  W(s33b);
101  W(s33c);
102   {
103    c4_Bytes hi("hi", 2);
104    c4_Bytes gday("gday", 4);
105    c4_Bytes hello("hello", 5);
106
107    c4_MemoProp p1("p1");
108
109    c4_Storage s1("s33a", 1);
110    s1.SetStructure("a[p1:B]");
111    c4_View v1 = s1.View("a");
112
113    v1.Add(p1[hi]);
114    v1.Add(p1[gday]);
115    v1.Add(p1[hello]);
116    A(p1(v1[0]) == hi);
117    A(p1(v1[1]) == gday);
118    A(p1(v1[2]) == hello);
119    s1.Commit();
120    A(p1(v1[0]) == hi);
121    A(p1(v1[1]) == gday);
122    A(p1(v1[2]) == hello);
123
124     {
125      c4_FileStream fs1(fopen("s33b", "wb"), true);
126      s1.SaveTo(fs1);
127    }
128
129    c4_Storage s2("s33c", 1);
130
131    c4_FileStream fs2(fopen("s33b", "rb"), true);
132    s2.LoadFrom(fs2);
133
134    c4_View v2 = s2.View("a");
135    A(p1(v2[0]) == hi);
136    A(p1(v2[1]) == gday);
137    A(p1(v2[2]) == hello);
138    s2.Commit();
139    A(p1(v2[0]) == hi);
140    A(p1(v2[1]) == gday);
141    A(p1(v2[2]) == hello);
142    s2.Commit();
143    A(p1(v2[0]) == hi);
144    A(p1(v2[1]) == gday);
145    A(p1(v2[2]) == hello);
146
147  }
148  D(s33a);
149  D(s33b);
150  D(s33c);
151  R(s33a);
152  R(s33b);
153  R(s33c);
154  E;
155
156  // check smarter commit and commit failure on r/o
157  B(s34, Smart and failed commits, 0)W(s34a);
158   {
159    c4_IntProp p1("p1");
160     {
161      c4_Storage s1("s34a", 1);
162      s1.SetStructure("a[p1:I]");
163      c4_View v1 = s1.View("a");
164      v1.Add(p1[111]);
165      A(v1.GetSize() == 1);
166      A(p1(v1[0]) == 111);
167      bool f1 = s1.Commit();
168      A(f1);
169      A(v1.GetSize() == 1);
170      A(p1(v1[0]) == 111);
171      bool f2 = s1.Commit();
172      A(f2); // succeeds, but should not write anything
173      A(v1.GetSize() == 1);
174      A(p1(v1[0]) == 111);
175    }
176     {
177      c4_Storage s1("s34a", 0);
178      c4_View v1 = s1.View("a");
179      v1.Add(p1[222]);
180      A(v1.GetSize() == 2);
181      A(p1(v1[0]) == 111);
182      A(p1(v1[1]) == 222);
183      bool f1 = s1.Commit();
184      A(!f1);
185      A(v1.GetSize() == 2);
186      A(p1(v1[0]) == 111);
187      A(p1(v1[1]) == 222);
188    }
189  }
190  D(s34a);
191  R(s34a);
192  E;
193
194  B(s35, Datafile with preamble, 0)W(s35a);
195   {
196     {
197      c4_FileStream fs1(fopen("s35a", "wb"), true);
198      fs1.Write("abc", 3);
199    }
200    c4_IntProp p1("p1");
201     {
202      c4_Storage s1("s35a", 1);
203      s1.SetStructure("a[p1:I]");
204      c4_View v1 = s1.View("a");
205      v1.Add(p1[111]);
206      A(v1.GetSize() == 1);
207      A(p1(v1[0]) == 111);
208      bool f1 = s1.Commit();
209      A(f1);
210      A(v1.GetSize() == 1);
211      A(p1(v1[0]) == 111);
212      bool f2 = s1.Commit();
213      A(f2); // succeeds, but should not write anything
214      A(v1.GetSize() == 1);
215      A(p1(v1[0]) == 111);
216    }
217     {
218      c4_FileStream fs1(fopen("s35a", "rb"), true);
219      char buffer[10];
220      int n1 = fs1.Read(buffer, 3);
221      A(n1 == 3);
222      A(c4_String(buffer, 3) == "abc");
223    }
224     {
225      c4_Storage s1("s35a", 0);
226      c4_View v1 = s1.View("a");
227      A(v1.GetSize() == 1);
228      A(p1(v1[0]) == 111);
229      v1.Add(p1[222]);
230      A(v1.GetSize() == 2);
231      A(p1(v1[0]) == 111);
232      A(p1(v1[1]) == 222);
233      bool f1 = s1.Commit();
234      A(!f1);
235      A(v1.GetSize() == 2);
236      A(p1(v1[0]) == 111);
237      A(p1(v1[1]) == 222);
238    }
239  }
240  D(s35a);
241  R(s35a);
242  E;
243
244  B(s36, Commit after load, 0)W(s36a);
245  W(s36b);
246   {
247    c4_IntProp p1("p1");
248
249    c4_Storage s1("s36a", 1);
250    s1.SetStructure("a[p1:I]");
251    c4_View v1 = s1.View("a");
252    v1.Add(p1[111]);
253    A(v1.GetSize() == 1);
254    A(p1(v1[0]) == 111);
255
256     {
257      c4_FileStream fs1(fopen("s36b", "wb"), true);
258      s1.SaveTo(fs1);
259    }
260
261    p1(v1[0]) = 222;
262    v1.Add(p1[333]);
263    bool f1 = s1.Commit();
264    A(f1);
265    A(v1.GetSize() == 2);
266    A(p1(v1[0]) == 222);
267    A(p1(v1[1]) == 333);
268
269    c4_FileStream fs2(fopen("s36b", "rb"), true);
270    s1.LoadFrom(fs2);
271    //A(v1.GetSize() == 0); // should be detached, but it's still 2
272
273    c4_View v2 = s1.View("a");
274    A(v2.GetSize() == 1);
275    A(p1(v2[0]) == 111);
276
277    // this fails in 2.4.0, reported by James Lupo, August 2001
278    bool f2 = s1.Commit();
279    A(f2);
280  }
281  D(s36a);
282  D(s36b);
283  R(s36a);
284  R(s36b);
285  E;
286
287  // fails in 2.4.1, reported Oct 31. 2001 by Steve Baxter
288  B(s37, Change short partial fields, 0)W(s37a);
289   {
290    c4_BytesProp p1("p1");
291    c4_Storage s1("s37a", true);
292    c4_View v1 = s1.GetAs("v1[key:I,p1:B]");
293
294    v1.Add(p1[c4_Bytes("12345", 6)]);
295    A(v1.GetSize() == 1);
296    s1.Commit();
297
298    c4_Bytes buf = p1(v1[0]);
299    A(buf.Size() == 6);
300    A(buf == c4_Bytes("12345", 6));
301    buf = p1(v1[0]).Access(1, 3);
302    A(buf == c4_Bytes("234", 3));
303    p1(v1[0]).Modify(c4_Bytes("ab", 2), 2, 0);
304    s1.Commit();
305
306    buf = p1(v1[0]);
307    A(buf == c4_Bytes("12ab5", 6));
308  }
309  D(s37a);
310  R(s37a);
311  E;
312
313  // Gross memory use (but no leaks), January 2002, Murat Berk
314  B(s38, Lots of empty subviews, 0)W(s38a);
315   {
316    c4_BytesProp p1("p1");
317     {
318      c4_Storage s1("s38a", true);
319      c4_View v = s1.GetAs("v[v1[p1:S]]");
320
321      v.SetSize(100000);
322      s1.Commit();
323    }
324     {
325      c4_Storage s2("s38a", true);
326      c4_View v2 = s2.View("v");
327      // this should not materialize all the empty subviews
328      v2.SetSize(v2.GetSize() + 1);
329      // nor should this
330      s2.Commit();
331    }
332     {
333      c4_Storage s3("s38a", true);
334      c4_View v3 = s3.View("v");
335      v3.RemoveAt(1, v3.GetSize() - 2);
336      A(v3.GetSize() == 2);
337      s3.Commit();
338    }
339  }
340  D(s38a);
341  R(s38a);
342  E;
343
344  // Fix bug introduced on 7-2-2002, as reported by M. Berk
345  B(s39, Do not detach empty top-level views, 0)W(s39a);
346   {
347    c4_IntProp p1("p1");
348    c4_Storage s1("s39a", true);
349    c4_View v1 = s1.GetAs("v1[p1:I]");
350    s1.Commit();
351    A(v1.GetSize() == 0);
352    v1.Add(p1[123]);
353    A(v1.GetSize() == 1);
354    s1.Commit();
355    c4_View v2 = s1.View("v1");
356    A(v2.GetSize() == 1); // fails with 0 due to recent bug
357  }
358  D(s39a);
359  R(s39a);
360  E;
361}
362