1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1999
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 * Blake Ross (blake@blakeross.com)
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
36 *
37 * ***** END LICENSE BLOCK ***** */
38
39 #ifndef _MDB_
40 #define _MDB_ 1
41
42 #include "mozilla/Path.h"
43 #include "nscore.h"
44 #include "nsISupports.h"
45 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
46
47 // { %%%%% begin scalar typedefs %%%%%
48 typedef unsigned char mdb_u1; // make sure this is one byte
49 typedef unsigned short mdb_u2; // make sure this is two bytes
50 typedef short mdb_i2; // make sure this is two bytes
51 typedef uint32_t mdb_u4; // make sure this is four bytes
52 typedef int32_t mdb_i4; // make sure this is four bytes
53 typedef PRWord mdb_ip; // make sure sizeof(mdb_ip) == sizeof(void*)
54
55 typedef mdb_u1 mdb_bool; // unsigned byte with zero=false, nonzero=true
56
57 /* canonical boolean constants provided only for code clarity: */
58 #define mdbBool_kTrue ((mdb_bool)1) /* actually any nonzero means true */
59 #define mdbBool_kFalse ((mdb_bool)0) /* only zero means false */
60
61 typedef mdb_u4 mdb_id; // unsigned object identity in a scope
62 typedef mdb_id mdb_rid; // unsigned row identity inside scope
63 typedef mdb_id mdb_tid; // unsigned table identity inside scope
64 typedef mdb_u4 mdb_token; // unsigned token for atomized string
65 typedef mdb_token mdb_scope; // token used to id scope for rows
66 typedef mdb_token mdb_kind; // token used to id kind for tables
67 typedef mdb_token mdb_column; // token used to id columns for rows
68 typedef mdb_token mdb_cscode; // token used to id charset names
69 typedef mdb_u4 mdb_seed; // unsigned collection change counter
70 typedef mdb_u4 mdb_count; // unsigned collection member count
71 typedef mdb_u4 mdb_size; // unsigned physical media size
72 typedef mdb_u4 mdb_fill; // unsigned logical content size
73 typedef mdb_u4 mdb_more; // more available bytes for larger buffer
74
75 typedef mdb_u2 mork_uses; // 2-byte strong uses count
76 typedef mdb_u2 mork_refs; // 2-byte actual reference count
77
78 #define mdbId_kNone ((mdb_id)-1) /* never a valid Mork object ID */
79
80 typedef mdb_u4 mdb_percent; // 0..100, with values >100 same as 100
81
82 typedef mdb_u1 mdb_priority; // 0..9, for a total of ten different values
83
84 // sequence position is signed; negative is useful to mean "before first":
85 typedef mdb_i4 mdb_pos; // signed zero-based ordinal collection position
86
87 #define mdbPos_kBeforeFirst ((mdb_pos)-1) /* any negative is before zero */
88
89 // order is also signed, so we can use three states for comparison order:
90 typedef mdb_i4 mdb_order; // neg:lessthan, zero:equalto, pos:greaterthan
91
92 typedef mdb_order (*mdbAny_Order)(const void* inA, const void* inB,
93 const void* inClosure);
94
95 // } %%%%% end scalar typedefs %%%%%
96
97 // { %%%%% begin C structs %%%%%
98
99 #ifndef mdbScopeStringSet_typedef
100 typedef struct mdbScopeStringSet mdbScopeStringSet;
101 # define mdbScopeStringSet_typedef 1
102 #endif
103
104 /*| mdbScopeStringSet: a set of null-terminated C strings that enumerate some
105 **| names of row scopes, so that row scopes intended for use by an application
106 **| can be declared by an app when trying to open or create a database file.
107 **| (We use strings and not tokens because we cannot know the tokens for any
108 **| particular db without having first opened the db.) The goal is to inform
109 **| a db runtime that scopes not appearing in this list can be given relatively
110 **| short shrift in runtime representation, with the expectation that other
111 **| scopes will not actually be used. However, a db should still be prepared
112 **| to handle accessing row scopes not in this list, rather than raising errors.
113 **| But it could be quite expensive to access a row scope not on the list.
114 **| Note a zero count for the string set means no such string set is being
115 **| specified, and that a db should handle all row scopes efficiently.
116 **| (It does NOT mean an app plans to use no content whatsoever.)
117 |*/
118 #ifndef mdbScopeStringSet_struct
119 # define mdbScopeStringSet_struct 1
120 struct mdbScopeStringSet { // vector of scopes for use in db opening policy
121 // when mScopeStringSet_Count is zero, this means no scope constraints
122 mdb_count mScopeStringSet_Count; // number of strings in vector below
123 const char** mScopeStringSet_Strings; // null-ended ascii scope strings
124 };
125 #endif /*mdbScopeStringSet_struct*/
126
127 #ifndef mdbOpenPolicy_typedef
128 typedef struct mdbOpenPolicy mdbOpenPolicy;
129 # define mdbOpenPolicy_typedef 1
130 #endif
131
132 #ifndef mdbOpenPolicy_struct
133 # define mdbOpenPolicy_struct 1
134 struct mdbOpenPolicy { // policies affecting db usage for ports and stores
135 mdbScopeStringSet mOpenPolicy_ScopePlan; // predeclare scope usage plan
136 mdb_bool mOpenPolicy_MaxLazy; // nonzero: do least work
137 mdb_bool mOpenPolicy_MinMemory; // nonzero: use least memory
138 };
139 #endif /*mdbOpenPolicy_struct*/
140
141 #ifndef mdbTokenSet_typedef
142 typedef struct mdbTokenSet mdbTokenSet;
143 # define mdbTokenSet_typedef 1
144 #endif
145
146 #ifndef mdbTokenSet_struct
147 # define mdbTokenSet_struct 1
148 struct mdbTokenSet { // array for a set of tokens, and actual slots used
149 mdb_count mTokenSet_Count; // number of token slots in the array
150 mdb_fill mTokenSet_Fill; // the subset of count slots actually used
151 mdb_more mTokenSet_More; // more tokens available for bigger array
152 mdb_token* mTokenSet_Tokens; // array of count mdb_token instances
153 };
154 #endif /*mdbTokenSet_struct*/
155
156 #ifndef mdbUsagePolicy_typedef
157 typedef struct mdbUsagePolicy mdbUsagePolicy;
158 # define mdbUsagePolicy_typedef 1
159 #endif
160
161 /*| mdbUsagePolicy: another version of mdbOpenPolicy which uses tokens instead
162 **| of scope strings, because usage policies can be constructed for use with a
163 **| db that is already open, while an open policy must be constructed before a
164 **| db has yet been opened.
165 |*/
166 #ifndef mdbUsagePolicy_struct
167 # define mdbUsagePolicy_struct 1
168 struct mdbUsagePolicy { // policies affecting db usage for ports and stores
169 mdbTokenSet mUsagePolicy_ScopePlan; // current scope usage plan
170 mdb_bool mUsagePolicy_MaxLazy; // nonzero: do least work
171 mdb_bool mUsagePolicy_MinMemory; // nonzero: use least memory
172 };
173 #endif /*mdbUsagePolicy_struct*/
174
175 #ifndef mdbOid_typedef
176 typedef struct mdbOid mdbOid;
177 # define mdbOid_typedef 1
178 #endif
179
180 #ifndef mdbOid_struct
181 # define mdbOid_struct 1
182 struct mdbOid { // identity of some row or table inside a database
183 mdb_scope mOid_Scope; // scope token for an id's namespace
184 mdb_id mOid_Id; // identity of object inside scope namespace
185 };
186 #endif /*mdbOid_struct*/
187
188 #ifndef mdbRange_typedef
189 typedef struct mdbRange mdbRange;
190 # define mdbRange_typedef 1
191 #endif
192
193 #ifndef mdbRange_struct
194 # define mdbRange_struct 1
195 struct mdbRange { // range of row positions in a table
196 mdb_pos mRange_FirstPos; // position of first row
197 mdb_pos mRange_LastPos; // position of last row
198 };
199 #endif /*mdbRange_struct*/
200
201 #ifndef mdbColumnSet_typedef
202 typedef struct mdbColumnSet mdbColumnSet;
203 # define mdbColumnSet_typedef 1
204 #endif
205
206 #ifndef mdbColumnSet_struct
207 # define mdbColumnSet_struct 1
208 struct mdbColumnSet { // array of column tokens (just the same as mdbTokenSet)
209 mdb_count mColumnSet_Count; // number of columns
210 mdb_column* mColumnSet_Columns; // count mdb_column instances
211 };
212 #endif /*mdbColumnSet_struct*/
213
214 #ifndef mdbYarn_typedef
215 typedef struct mdbYarn mdbYarn;
216 # define mdbYarn_typedef 1
217 #endif
218
219 #ifdef MDB_BEGIN_C_LINKAGE_define
220 # define MDB_BEGIN_C_LINKAGE_define 1
221 # define MDB_BEGIN_C_LINKAGE extern "C" {
222 # define MDB_END_C_LINKAGE }
223 #endif /*MDB_BEGIN_C_LINKAGE_define*/
224
225 /*| mdbYarn_mGrow: an abstract API for growing the size of a mdbYarn
226 **| instance. With respect to a specific API that requires a caller
227 **| to supply a string (mdbYarn) that a callee fills with content
228 **| that might exceed the specified size, mdbYarn_mGrow is a caller-
229 **| supplied means of letting a callee attempt to increase the string
230 **| size to become large enough to receive all content available.
231 **|
232 **|| Grow(): a method for requesting that a yarn instance be made
233 **| larger in size. Note that such requests need not be honored, and
234 **| need not be honored in full if only partial size growth is desired.
235 **| (Note that no nsIMdbEnv instance is passed as argument, although one
236 **| might be needed in some circumstances. So if an nsIMdbEnv is needed,
237 **| a reference to one might be held inside a mdbYarn member slot.)
238 **|
239 **|| self: a yarn instance to be grown. Presumably this yarn is
240 **| the instance which holds the mYarn_Grow method pointer. Yarn
241 **| instancesshould only be passed to grow methods which they were
242 **| specifically designed to fit, as indicated by the mYarn_Grow slot.
243 **|
244 **|| inNewSize: the new desired value for slot mYarn_Size in self.
245 **| If mYarn_Size is already this big, then nothing should be done.
246 **| If inNewSize is larger than seems feasible or desirable to honor,
247 **| then any size restriction policy can be used to grow to some size
248 **| greater than mYarn_Size. (Grow() might even grow to a size
249 **| greater than inNewSize in order to make the increase in size seem
250 **| worthwhile, rather than growing in many smaller steps over time.)
251 |*/
252 typedef void (*mdbYarn_mGrow)(mdbYarn* self, mdb_size inNewSize);
253 // mdbYarn_mGrow methods must be declared with C linkage in C++
254
255 /*| mdbYarn: a variable length "string" of arbitrary binary bytes,
256 **| whose length is mYarn_Fill, inside a buffer mYarn_Buf that has
257 **| at most mYarn_Size byte of physical space.
258 **|
259 **|| mYarn_Buf: a pointer to space containing content. This slot
260 **| might never be nil when mYarn_Size is nonzero, but checks for nil
261 **| are recommended anyway.
262 **| (Implementations of mdbYarn_mGrow methods should take care to
263 **| ensure the existence of a replacement before dropping old Bufs.)
264 **| Content in Buf can be anything in any format, but the mYarn_Form
265 **| implies the actual format by some caller-to-callee convention.
266 **| mYarn_Form==0 implies US-ASCII iso-8859-1 Latin1 string content.
267 **|
268 **|| mYarn_Size: the physical size of Buf in bytes. Note that if one
269 **| intends to terminate a string with a null byte, that it must not
270 **| be written at or after mYarn_Buf[mYarn_Size] because this is after
271 **| the last byte in the physical buffer space. Size can be zero,
272 **| which means the string has no content whatsoever; note that when
273 **| Size is zero, this is a suitable reason for Buf==nil as well.
274 **|
275 **|| mYarn_Fill: the logical content in Buf in bytes, where Fill must
276 **| never exceed mYarn_Size. Note that yarn strings might not have a
277 **| terminating null byte (since they might not even be C strings), but
278 **| when they do, such terminating nulls are considered part of content
279 **| and therefore Fill will count such null bytes. So an "empty" C
280 **| string will have Fill==1, because content includes one null byte.
281 **| Fill does not mean "length" when applied to C strings for this
282 **| reason. However, clients using yarns to hold C strings can infer
283 **| that length is equal to Fill-1 (but should take care to handle the
284 **| case where Fill==0). To be paranoid, one can always copy to a
285 **| destination with size exceeding Fill, and place a redundant null
286 **| byte in the Fill position when this simplifies matters.
287 **|
288 **|| mYarn_Form: a designation of content format within mYarn_Buf.
289 **| The semantics of this slot are the least well defined, since the
290 **| actual meaning is context dependent, to the extent that callers
291 **| and callees must agree on format encoding conventions when such
292 **| are not standardized in many computing contexts. However, in the
293 **| context of a specific mdb database, mYarn_Form is a token for an
294 **| atomized string in that database that typically names a preferred
295 **| mime type charset designation. If and when mdbYarn is used for
296 **| other purposes away from the mdb interface, folks can use another
297 **| convention system for encoding content formats. However, in all
298 **| contexts is it useful to maintain the convention that Form==0
299 **| implies Buf contains US-ASCII iso-8859-1 Latin1 string content.
300 **|
301 **|| mYarn_Grow: either a mdbYarn_mGrow method, or else nil. When
302 **| a mdbYarn_mGrow method is provided, this method can be used to
303 **| request a yarn buf size increase. A caller who constructs the
304 **| original mdbYarn instance decides whether a grow method is necessary
305 **| or desirable, and uses only grow methods suitable for the buffering
306 **| nature of a specific mdbYarn instance. (For example, Buf might be a
307 **| statically allocated string space which switches to something heap-based
308 **| when grown, and subsequent calls to grow the yarn must distinguish the
309 **| original static string from heap allocated space, etc.) Note that the
310 **| method stored in mYarn_Grow can change, and this might be a common way
311 **| to track memory managent changes in policy for mYarn_Buf.
312 |*/
313 #ifndef mdbYarn_struct
314 # define mdbYarn_struct 1
315 struct mdbYarn { // buffer with caller space allocation semantics
316 void* mYarn_Buf; // space for holding any binary content
317 mdb_fill mYarn_Fill; // logical content in Buf in bytes
318 mdb_size mYarn_Size; // physical size of Buf in bytes
319 mdb_more mYarn_More; // more available bytes if Buf is bigger
320 mdb_cscode mYarn_Form; // charset format encoding
321 mdbYarn_mGrow mYarn_Grow; // optional method to grow mYarn_Buf
322
323 // Subclasses might add further slots after mYarn_Grow in order to
324 // maintain bookkeeping needs, such as state info about mYarn_Buf.
325 };
326 #endif /*mdbYarn_struct*/
327
328 // } %%%%% end C structs %%%%%
329
330 // { %%%%% begin class forward defines %%%%%
331 class nsIMdbEnv;
332 class nsIMdbObject;
333 class nsIMdbErrorHook;
334 class nsIMdbThumb;
335 class nsIMdbFactory;
336 class nsIMdbFile;
337 class nsIMdbPort;
338 class nsIMdbStore;
339 class nsIMdbCursor;
340 class nsIMdbPortTableCursor;
341 class nsIMdbCollection;
342 class nsIMdbTable;
343 class nsIMdbTableRowCursor;
344 class nsIMdbRow;
345 class nsIMdbRowCellCursor;
346 class nsIMdbBlob;
347 class nsIMdbCell;
348 class nsIMdbSorting;
349 // } %%%%% end class forward defines %%%%%
350
351 // { %%%%% begin C++ abstract class interfaces %%%%%
352
353 /*| nsIMdbObject: base class for all message db class interfaces
354 **|
355 **|| factory: all nsIMdbObjects from the same code suite have the same factory
356 **|
357 **|| refcounting: both strong and weak references, to ensure strong refs are
358 **| acyclic, while weak refs can cause cycles. CloseMdbObject() is
359 **| called when (strong) use counts hit zero, but clients can call this close
360 **| method early for some reason, if absolutely necessary even though it will
361 **| thwart the other uses of the same object. Note that implementations must
362 **| cope with close methods being called arbitrary numbers of times. The COM
363 **| calls to AddRef() and release ref map directly to strong use ref calls,
364 **| but the total ref count for COM objects is the sum of weak & strong refs.
365 |*/
366
367 #define NS_IMDBOBJECT_IID_STR "5533ea4b-14c3-4bef-ac60-22f9e9a49084"
368
369 #define NS_IMDBOBJECT_IID \
370 { \
371 0x5533ea4b, 0x14c3, 0x4bef, { \
372 0xac, 0x60, 0x22, 0xf9, 0xe9, 0xa4, 0x90, 0x84 \
373 } \
374 }
375
376 class nsIMdbObject : public nsISupports { // msg db base class
377 public:
378 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBOBJECT_IID)
379 // { ===== begin nsIMdbObject methods =====
380
381 // { ----- begin attribute methods -----
382 NS_IMETHOD IsFrozenMdbObject(nsIMdbEnv* ev, mdb_bool* outIsReadonly) = 0;
383 // same as nsIMdbPort::GetIsPortReadonly() when this object is inside a port.
384 // } ----- end attribute methods -----
385
386 // { ----- begin factory methods -----
387 NS_IMETHOD GetMdbFactory(nsIMdbEnv* ev, nsIMdbFactory** acqFactory) = 0;
388 // } ----- end factory methods -----
389
390 // { ----- begin ref counting for well-behaved cyclic graphs -----
391 NS_IMETHOD GetWeakRefCount(nsIMdbEnv* ev, // weak refs
392 mdb_count* outCount) = 0;
393 NS_IMETHOD GetStrongRefCount(nsIMdbEnv* ev, // strong refs
394 mdb_count* outCount) = 0;
395
396 NS_IMETHOD AddWeakRef(nsIMdbEnv* ev) = 0;
397 NS_IMETHOD_(mork_uses) AddStrongRef(nsIMdbEnv* ev) = 0;
398
399 NS_IMETHOD CutWeakRef(nsIMdbEnv* ev) = 0;
400 NS_IMETHOD CutStrongRef(nsIMdbEnv* ev) = 0;
401
402 NS_IMETHOD CloseMdbObject(nsIMdbEnv* ev) = 0; // called at strong refs zero
403 NS_IMETHOD IsOpenMdbObject(nsIMdbEnv* ev, mdb_bool* outOpen) = 0;
404 // } ----- end ref counting -----
405
406 // } ===== end nsIMdbObject methods =====
407 };
408
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbObject,NS_IMDBOBJECT_IID)409 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbObject, NS_IMDBOBJECT_IID)
410
411 /*| nsIMdbErrorHook: a base class for clients of this API to subclass, in order
412 **| to provide a callback installable in nsIMdbEnv for error notifications. If
413 **| apps that subclass nsIMdbErrorHook wish to maintain a reference to the env
414 **| that contains the hook, then this should be a weak ref to avoid cycles.
415 **|
416 **|| OnError: when nsIMdbEnv has an error condition that causes the total count
417 **| of errors to increase, then nsIMdbEnv should call OnError() to report the
418 **| error in some fashion when an instance of nsIMdbErrorHook is installed. The
419 **| variety of string flavors is currently due to the uncertainty here in the
420 **| nsIMdbBlob and nsIMdbCell interfaces. (Note that overloading by using the
421 **| same method name is not necessary here, and potentially less clear.)
422 |*/
423 class nsIMdbErrorHook
424 : public nsISupports { // env callback handler to report errors
425 public:
426 // { ===== begin error methods =====
427 NS_IMETHOD OnErrorString(nsIMdbEnv* ev, const char* inAscii) = 0;
428 NS_IMETHOD OnErrorYarn(nsIMdbEnv* ev, const mdbYarn* inYarn) = 0;
429 // } ===== end error methods =====
430
431 // { ===== begin warning methods =====
432 NS_IMETHOD OnWarningString(nsIMdbEnv* ev, const char* inAscii) = 0;
433 NS_IMETHOD OnWarningYarn(nsIMdbEnv* ev, const mdbYarn* inYarn) = 0;
434 // } ===== end warning methods =====
435
436 // { ===== begin abort hint methods =====
437 NS_IMETHOD OnAbortHintString(nsIMdbEnv* ev, const char* inAscii) = 0;
438 NS_IMETHOD OnAbortHintYarn(nsIMdbEnv* ev, const mdbYarn* inYarn) = 0;
439 // } ===== end abort hint methods =====
440 };
441
442 /*| nsIMdbHeap: abstract memory allocation interface.
443 **|
444 **|| Alloc: return a block at least inSize bytes in size with alignment
445 **| suitable for any native type (such as long integers). When no such
446 **| block can be allocated, failure is indicated by a null address in
447 **| addition to reporting an error in the environment.
448 **|
449 **|| Free: deallocate a block allocated or resized earlier by the same
450 **| heap instance. If the inBlock parameter is nil, the heap should do
451 **| nothing (and crashing is strongly discouraged).
452 |*/
453 class nsIMdbHeap { // caller-supplied memory management interface
454 public:
455 // { ===== begin nsIMdbHeap methods =====
456 NS_IMETHOD Alloc(nsIMdbEnv* ev, // allocate a piece of memory
457 mdb_size inSize, // requested byte size of new memory block
458 void** outBlock) =
459 0; // memory block of inSize bytes, or nil
460
461 NS_IMETHOD Free(nsIMdbEnv* ev, // free block from Alloc or Resize()
462 void* ioBlock) = 0; // block to be destroyed/deallocated
463
464 virtual size_t GetUsedSize() = 0;
465
~nsIMdbHeap()466 virtual ~nsIMdbHeap(){};
467 // } ===== end nsIMdbHeap methods =====
468 };
469
470 /*| nsIMdbCPlusHeap: Alloc() with global ::new(), Free() with global ::delete().
471 **| Resize() is done by ::new() followed by ::delete().
472 |*/
473 class nsIMdbCPlusHeap { // caller-supplied memory management interface
474 public:
475 // { ===== begin nsIMdbHeap methods =====
476 NS_IMETHOD Alloc(nsIMdbEnv* ev, // allocate a piece of memory
477 mdb_size inSize, // requested size of new memory block
478 void** outBlock); // memory block of inSize bytes, or nil
479
480 NS_IMETHOD Free(nsIMdbEnv* ev, // free block allocated earlier by Alloc()
481 void* inBlock);
482
483 NS_IMETHOD HeapAddStrongRef(nsIMdbEnv* ev);
484 NS_IMETHOD HeapCutStrongRef(nsIMdbEnv* ev);
485 // } ===== end nsIMdbHeap methods =====
486 };
487
488 /*| nsIMdbThumb:
489 |*/
490
491 #define NS_IMDBTHUMB_IID_STR "6d3ad7c1-a809-4e74-8577-49fa9a4562fa"
492
493 #define NS_IMDBTHUMB_IID \
494 { \
495 0x6d3ad7c1, 0xa809, 0x4e74, { \
496 0x85, 0x77, 0x49, 0xfa, 0x9a, 0x45, 0x62, 0xfa \
497 } \
498 }
499
500 class nsIMdbThumb
501 : public nsISupports { // closure for repeating incremental method
502 public:
503 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBTHUMB_IID)
504
505 // { ===== begin nsIMdbThumb methods =====
506 NS_IMETHOD GetProgress(
507 nsIMdbEnv* ev,
508 mdb_count* outTotal, // total somethings to do in operation
509 mdb_count* outCurrent, // subportion of total completed so far
510 mdb_bool* outDone, // is operation finished?
511 mdb_bool* outBroken // is operation irreparably dead and broken?
512 ) = 0;
513
514 NS_IMETHOD DoMore(
515 nsIMdbEnv* ev,
516 mdb_count* outTotal, // total somethings to do in operation
517 mdb_count* outCurrent, // subportion of total completed so far
518 mdb_bool* outDone, // is operation finished?
519 mdb_bool* outBroken // is operation irreparably dead and broken?
520 ) = 0;
521
522 NS_IMETHOD CancelAndBreakThumb( // cancel pending operation
523 nsIMdbEnv* ev) = 0;
524 // } ===== end nsIMdbThumb methods =====
525 };
526
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbThumb,NS_IMDBTHUMB_IID)527 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbThumb, NS_IMDBTHUMB_IID)
528
529 /*| nsIMdbEnv: a context parameter used when calling most abstract db methods.
530 **| The main purpose of such an object is to permit a database implementation
531 **| to avoid the use of globals to share information between various parts of
532 **| the implementation behind the abstract db interface. An environment acts
533 **| like a session object for a given calling thread, and callers should use
534 **| at least one different nsIMdbEnv instance for each thread calling the API.
535 **| While the database implementation might not be threaded, it is highly
536 **| desirable that the db be thread-safe if calling threads use distinct
537 **| instances of nsIMdbEnv. Callers can stop at one nsIMdbEnv per thread, or
538 they
539 **| might decide to make on nsIMdbEnv instance for every nsIMdbPort opened, so
540 that
541 **| error information is segregated by database instance. Callers create
542 **| instances of nsIMdbEnv by calling the MakeEnv() method in nsIMdbFactory.
543 **|
544 **|| tracing: an environment might support some kind of tracing, and this
545 **| boolean attribute permits such activity to be enabled or disabled.
546 **|
547 **|| errors: when a call to the abstract db interface returns, a caller might
548 **| check the number of outstanding errors to see whether the operation did
549 **| actually succeed. Each nsIMdbEnv should have all its errors cleared by a
550 **| call to ClearErrors() before making each call to the abstract db API,
551 **| because outstanding errors might disable further database actions. (This
552 **| is not done inside the db interface, because the db cannot in general know
553 **| when a call originates from inside or outside -- only the app knows this.)
554 **|
555 **|| error hook: callers can install an instance of nsIMdbErrorHook to receive
556 **| error notifications whenever the error count increases. The hook can
557 **| be uninstalled by passing a null pointer.
558 **|
559 |*/
560
561 #define NS_IMDBENV_IID_STR "a765e46b-efb6-41e6-b75b-c5d6bd710594"
562
563 #define NS_IMDBENV_IID \
564 { \
565 0xa765e46b, 0xefb6, 0x41e6, { \
566 0xb7, 0x5b, 0xc5, 0xd6, 0xbd, 0x71, 0x05, 0x94 \
567 } \
568 }
569
570 class nsIMdbEnv : public nsISupports { // db specific context parameter
571 public:
572 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBENV_IID)
573 // { ===== begin nsIMdbEnv methods =====
574
575 // { ----- begin attribute methods -----
576 NS_IMETHOD GetErrorCount(mdb_count* outCount, mdb_bool* outShouldAbort) = 0;
577 NS_IMETHOD GetWarningCount(mdb_count* outCount, mdb_bool* outShouldAbort) = 0;
578
579 NS_IMETHOD GetEnvBeVerbose(mdb_bool* outBeVerbose) = 0;
580 NS_IMETHOD SetEnvBeVerbose(mdb_bool inBeVerbose) = 0;
581
582 NS_IMETHOD GetDoTrace(mdb_bool* outDoTrace) = 0;
583 NS_IMETHOD SetDoTrace(mdb_bool inDoTrace) = 0;
584
585 NS_IMETHOD GetAutoClear(mdb_bool* outAutoClear) = 0;
586 NS_IMETHOD SetAutoClear(mdb_bool inAutoClear) = 0;
587
588 NS_IMETHOD GetErrorHook(nsIMdbErrorHook** acqErrorHook) = 0;
589 NS_IMETHOD SetErrorHook(nsIMdbErrorHook* ioErrorHook) =
590 0; // becomes referenced
591
592 NS_IMETHOD GetHeap(nsIMdbHeap** acqHeap) = 0;
593 NS_IMETHOD SetHeap(nsIMdbHeap* ioHeap) = 0; // becomes referenced
594 // } ----- end attribute methods -----
595
596 NS_IMETHOD ClearErrors() = 0; // clear errors beore re-entering db API
597 NS_IMETHOD ClearWarnings() = 0; // clear warnings
598 NS_IMETHOD ClearErrorsAndWarnings() = 0; // clear both errors & warnings
599 // } ===== end nsIMdbEnv methods =====
600 };
601
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbEnv,NS_IMDBENV_IID)602 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbEnv, NS_IMDBENV_IID)
603
604 /*| nsIMdbFactory: the main entry points to the abstract db interface. A DLL
605 **| that supports this mdb interface need only have a single exported method
606 **| that will return an instance of nsIMdbFactory, so that further methods in
607 **| the suite can be accessed from objects returned by nsIMdbFactory methods.
608 **|
609 **|| mdbYarn: note all nsIMdbFactory subclasses must guarantee null
610 **| termination of all strings written into mdbYarn instances, as long as
611 **| mYarn_Size and mYarn_Buf are nonzero. Even truncated string values must
612 **| be null terminated. This is more strict behavior than mdbYarn requires,
613 **| but it is part of the nsIMdbFactory interface.
614 **|
615 **|| envs: an environment instance is required as per-thread context for
616 **| most of the db method calls, so nsIMdbFactory creates such instances.
617 **|
618 **|| rows: callers must be able to create row instances that are independent
619 **| of storage space that is part of the db content graph. Many interfaces
620 **| for data exchange have strictly copy semantics, so that a row instance
621 **| has no specific identity inside the db content model, and the text in
622 **| cells are an independenty copy of unexposed content inside the db model.
623 **| Callers are expected to maintain one or more row instances as a buffer
624 **| for staging cell content copied into or out of a table inside the db.
625 **| Callers are urged to use an instance of nsIMdbRow created by the
626 nsIMdbFactory
627 **| code suite, because reading and writing might be much more efficient than
628 **| when using a hand-rolled nsIMdbRow subclass with no relation to the suite.
629 **|
630 **|| ports: a port is a readonly interface to a specific database file. Most
631 **| of the methods to access a db file are suitable for a readonly interface,
632 **| so a port is the basic minimum for accessing content. This makes it
633 **| possible to read other external formats for import purposes, without
634 **| needing the code or competence necessary to write every such format. So
635 **| we can write generic import code just once, as long as every format can
636 **| show a face based on nsIMdbPort. (However, same suite import can be faster.)
637 **| Given a file name and the first 512 bytes of a file, a factory can say if
638 **| a port can be opened by this factory. Presumably an app maintains chains
639 **| of factories for different suites, and asks each in turn about opening a
640 **| a prospective file for reading (as a port) or writing (as a store). I'm
641 **| not ready to tackle issues of format fidelity and factory chain ordering.
642 **|
643 **|| stores: a store is a mutable interface to a specific database file, and
644 **| includes the port interface plus any methods particular to writing, which
645 **| are few in number. Presumably the set of files that can be opened as
646 **| stores is a subset of the set of files that can be opened as ports. A
647 **| new store can be created with CreateNewFileStore() by supplying a new
648 **| file name which does not yet exist (callers are always responsible for
649 **| destroying any existing files before calling this method).
650 |*/
651
652 #define NS_IMDBFACTORY_IID_STR "2b80395c-b91e-4990-b1a7-023e99ab14e9"
653
654 #define NS_IMDBFACTORY_IID \
655 { \
656 0xf04aa4ab, 0x1fe, 0x4115, { \
657 0xa4, 0xa5, 0x68, 0x19, 0xdf, 0xf1, 0x10, 0x3d \
658 } \
659 }
660
661 class nsIMdbFactory : public nsISupports { // suite entry points
662 using PathChar = mozilla::filesystem::Path::value_type;
663
664 public:
665 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBFACTORY_IID)
666 // { ===== begin nsIMdbFactory methods =====
667
668 // { ----- begin file methods -----
669 NS_IMETHOD OpenOldFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
670 const PathChar* inFilePath, mdb_bool inFrozen,
671 nsIMdbFile** acqFile) = 0;
672 // Choose some subclass of nsIMdbFile to instantiate, in order to read
673 // (and write if not frozen) the file known by inFilePath. The file
674 // returned should be open and ready for use, and presumably positioned
675 // at the first byte position of the file. The exact manner in which
676 // files must be opened is considered a subclass specific detail, and
677 // other portions or Mork source code don't want to know how it's done.
678
679 NS_IMETHOD CreateNewFile(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
680 const PathChar* inFilePath,
681 nsIMdbFile** acqFile) = 0;
682 // Choose some subclass of nsIMdbFile to instantiate, in order to read
683 // (and write if not frozen) the file known by inFilePath. The file
684 // returned should be created and ready for use, and presumably positioned
685 // at the first byte position of the file. The exact manner in which
686 // files must be opened is considered a subclass specific detail, and
687 // other portions or Mork source code don't want to know how it's done.
688 // } ----- end file methods -----
689
690 // { ----- begin env methods -----
691 NS_IMETHOD MakeEnv(nsIMdbHeap* ioHeap,
692 nsIMdbEnv** acqEnv) = 0; // acquire new env
693 // ioHeap can be nil, causing a MakeHeap() style heap instance to be used
694 // } ----- end env methods -----
695
696 // { ----- begin heap methods -----
697 NS_IMETHOD MakeHeap(nsIMdbEnv* ev,
698 nsIMdbHeap** acqHeap) = 0; // acquire new heap
699 // } ----- end heap methods -----
700
701 // { ----- begin row methods -----
702 NS_IMETHOD MakeRow(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
703 nsIMdbRow** acqRow) = 0; // new row
704 // ioHeap can be nil, causing the heap associated with ev to be used
705 // } ----- end row methods -----
706
707 // { ----- begin port methods -----
708 NS_IMETHOD CanOpenFilePort(
709 nsIMdbEnv* ev, // context
710 // const char* inFilePath, // the file to investigate
711 // const mdbYarn* inFirst512Bytes,
712 nsIMdbFile* ioFile, // db abstract file interface
713 mdb_bool* outCanOpen, // whether OpenFilePort() might succeed
714 mdbYarn* outFormatVersion) = 0; // informal file format description
715
716 NS_IMETHOD OpenFilePort(
717 nsIMdbEnv* ev, // context
718 nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
719 // const char* inFilePath, // the file to open for readonly import
720 nsIMdbFile* ioFile, // db abstract file interface
721 const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
722 nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental port open
723 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
724 // then call nsIMdbFactory::ThumbToOpenPort() to get the port instance.
725
726 NS_IMETHOD
727 ThumbToOpenPort( // redeeming a completed thumb from OpenFilePort()
728 nsIMdbEnv* ev, // context
729 nsIMdbThumb* ioThumb, // thumb from OpenFilePort() with done status
730 nsIMdbPort** acqPort) = 0; // acquire new port object
731 // } ----- end port methods -----
732
733 // { ----- begin store methods -----
734 NS_IMETHOD CanOpenFileStore(
735 nsIMdbEnv* ev, // context
736 // const char* inFilePath, // the file to investigate
737 // const mdbYarn* inFirst512Bytes,
738 nsIMdbFile* ioFile, // db abstract file interface
739 mdb_bool* outCanOpenAsStore, // whether OpenFileStore() might succeed
740 mdb_bool* outCanOpenAsPort, // whether OpenFilePort() might succeed
741 mdbYarn* outFormatVersion) = 0; // informal file format description
742
743 NS_IMETHOD OpenFileStore( // open an existing database
744 nsIMdbEnv* ev, // context
745 nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
746 // const char* inFilePath, // the file to open for general db usage
747 nsIMdbFile* ioFile, // db abstract file interface
748 const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
749 nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental store open
750 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
751 // then call nsIMdbFactory::ThumbToOpenStore() to get the store instance.
752
753 NS_IMETHOD
754 ThumbToOpenStore( // redeem completed thumb from OpenFileStore()
755 nsIMdbEnv* ev, // context
756 nsIMdbThumb* ioThumb, // thumb from OpenFileStore() with done status
757 nsIMdbStore** acqStore) = 0; // acquire new db store object
758
759 NS_IMETHOD CreateNewFileStore( // create a new db with minimal content
760 nsIMdbEnv* ev, // context
761 nsIMdbHeap* ioHeap, // can be nil to cause ev's heap attribute to be used
762 // const char* inFilePath, // name of file which should not yet exist
763 nsIMdbFile* ioFile, // db abstract file interface
764 const mdbOpenPolicy* inOpenPolicy, // runtime policies for using db
765 nsIMdbStore** acqStore) = 0; // acquire new db store object
766 // } ----- end store methods -----
767
768 // } ===== end nsIMdbFactory methods =====
769 };
770
771 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbFactory, NS_IMDBFACTORY_IID)
772
773 extern "C" nsIMdbFactory* MakeMdbFactory();
774
775 /*| nsIMdbFile: abstract file interface resembling the original morkFile
776 **| abstract interface (which was in turn modeled on the file interface
777 **| from public domain IronDoc). The design of this file interface is
778 **| complicated by the fact that some DB's will not find this interface
779 **| adequate for all runtime requirements (even though this file API is
780 **| enough to implement text-based DB's like Mork). For this reason,
781 **| more methods have been added to let a DB library force the file to
782 **| become closed so the DB can reopen the file in some other manner.
783 **| Folks are encouraged to suggest ways to tune this interface to suit
784 **| DB's that cannot manage to pull their maneuvers even given this API.
785 **|
786 **|| Tell: get the current i/o position in file
787 **|
788 **|| Seek: change the current i/o position in file
789 **|
790 **|| Eof: return file's total length in bytes
791 **|
792 **|| Read: input inSize bytes into outBuf, returning actual transfer size
793 **|
794 **|| Get: read starting at specific file offset (e.g. Seek(); Read();)
795 **|
796 **|| Write: output inSize bytes from inBuf, returning actual transfer size
797 **|
798 **|| Put: write starting at specific file offset (e.g. Seek(); Write();)
799 **|
800 **|| Flush: if written bytes are buffered, push them to final destination
801 **|
802 **|| Path: get file path in some string representation. This is intended
803 **| either to support the display of file name in a user presentation, or
804 **| to support the closing and reopening of the file when the DB needs more
805 **| exotic file access than is presented by the nsIMdbFile interface.
806 **|
807 **|| Steal: tell this file to close any associated i/o stream in the file
808 **| system, because the file ioThief intends to reopen the file in order
809 **| to provide the MDB implementation with more exotic file access than is
810 **| offered by the nsIMdbFile alone. Presumably the thief knows enough
811 **| from Path() in order to know which file to reopen. If Steal() is
812 **| successful, this file should probably delegate all future calls to
813 **| the nsIMdbFile interface down to the thief files, so that even after
814 **| the file has been stolen, it can still be read, written, or forcibly
815 **| closed (by a call to CloseMdbObject()).
816 **|
817 **|| Thief: acquire and return thief passed to an earlier call to Steal().
818 |*/
819
820 #define NS_IMDBFILE_IID_STR "f04aa4ab-1fe7-4115-a4a5-6819dff1103d"
821
822 #define NS_IMDBFILE_IID \
823 { \
824 0xf04aa4ab, 0x1fe, 0x4115, { \
825 0xa4, 0xa5, 0x68, 0x19, 0xdf, 0xf1, 0x10, 0x3d \
826 } \
827 }
828
829 class nsIMdbFile : public nsISupports { // minimal file interface
830 public:
831 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBFILE_IID)
832 // { ===== begin nsIMdbFile methods =====
833
834 // { ----- begin pos methods -----
835 NS_IMETHOD Tell(nsIMdbEnv* ev, mdb_pos* outPos) const = 0;
836 NS_IMETHOD Seek(nsIMdbEnv* ev, mdb_pos inPos, mdb_pos* outPos) = 0;
837 NS_IMETHOD Eof(nsIMdbEnv* ev, mdb_pos* outPos) = 0;
838 // } ----- end pos methods -----
839
840 // { ----- begin read methods -----
841 NS_IMETHOD Read(nsIMdbEnv* ev, void* outBuf, mdb_size inSize,
842 mdb_size* outActualSize) = 0;
843 NS_IMETHOD Get(nsIMdbEnv* ev, void* outBuf, mdb_size inSize, mdb_pos inPos,
844 mdb_size* outActualSize) = 0;
845 // } ----- end read methods -----
846
847 // { ----- begin write methods -----
848 NS_IMETHOD Write(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize,
849 mdb_size* outActualSize) = 0;
850 NS_IMETHOD Put(nsIMdbEnv* ev, const void* inBuf, mdb_size inSize,
851 mdb_pos inPos, mdb_size* outActualSize) = 0;
852 NS_IMETHOD Flush(nsIMdbEnv* ev) = 0;
853 // } ----- end attribute methods -----
854
855 // { ----- begin path methods -----
856 NS_IMETHOD Path(nsIMdbEnv* ev, mdbYarn* outFilePath) = 0;
857 // } ----- end path methods -----
858
859 // { ----- begin replacement methods -----
860 NS_IMETHOD Steal(nsIMdbEnv* ev, nsIMdbFile* ioThief) = 0;
861 NS_IMETHOD Thief(nsIMdbEnv* ev, nsIMdbFile** acqThief) = 0;
862 // } ----- end replacement methods -----
863
864 // { ----- begin versioning methods -----
865 NS_IMETHOD BecomeTrunk(nsIMdbEnv* ev) = 0;
866 // If this file is a file version branch created by calling AcquireBud(),
867 // BecomeTrunk() causes this file's content to replace the original
868 // file's content, typically by assuming the original file's identity.
869 // This default implementation of BecomeTrunk() does nothing, and this
870 // is appropriate behavior for files which are not branches, and is
871 // also the right behavior for files returned from AcquireBud() which are
872 // in fact the original file that has been truncated down to zero length.
873
874 NS_IMETHOD AcquireBud(nsIMdbEnv* ev, nsIMdbHeap* ioHeap,
875 nsIMdbFile** acqBud) =
876 0; // acquired file for new version of content
877 // AcquireBud() starts a new "branch" version of the file, empty of content,
878 // so that a new version of the file can be written. This new file
879 // can later be told to BecomeTrunk() the original file, so the branch
880 // created by budding the file will replace the original file. Some
881 // file subclasses might initially take the unsafe but expedient
882 // approach of simply truncating this file down to zero length, and
883 // then returning the same morkFile pointer as this, with an extra
884 // reference count increment. Note that the caller of AcquireBud() is
885 // expected to eventually call CutStrongRef() on the returned file
886 // in order to release the strong reference. High quality versions
887 // of morkFile subclasses will create entirely new files which later
888 // are renamed to become the old file, so that better transactional
889 // behavior is exhibited by the file, so crashes protect old files.
890 // Note that AcquireBud() is an illegal operation on readonly files.
891 // } ----- end versioning methods -----
892
893 // } ===== end nsIMdbFile methods =====
894 };
895
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbFile,NS_IMDBFILE_IID)896 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbFile, NS_IMDBFILE_IID)
897
898 /*| nsIMdbPort: a readonly interface to a specific database file. The mutable
899 **| nsIMdbStore interface is a subclass that includes writing behavior, but
900 **| most of the needed db methods appear in the readonly nsIMdbPort interface.
901 **|
902 **|| mdbYarn: note all nsIMdbPort and nsIMdbStore subclasses must guarantee null
903 **| termination of all strings written into mdbYarn instances, as long as
904 **| mYarn_Size and mYarn_Buf are nonzero. Even truncated string values must
905 **| be null terminated. This is more strict behavior than mdbYarn requires,
906 **| but it is part of the nsIMdbPort and nsIMdbStore interface.
907 **|
908 **|| attributes: methods are provided to distinguish a readonly port from a
909 **| mutable store, and whether a mutable store actually has any dirty content.
910 **|
911 **|| filepath: the file path used to open the port from the nsIMdbFactory can be
912 **| queried and discovered by GetPortFilePath(), which includes format info.
913 **|
914 **|| export: a port can write itself in other formats, with perhaps a typical
915 **| emphasis on text interchange formats used by other systems. A port can be
916 **| queried to determine its preferred export interchange format, and a port
917 **| can be queried to see whether a specific export format is supported. And
918 **| actually exporting a port requires a new destination file name and format.
919 **|
920 **|| tokens: a port supports queries about atomized strings to map tokens to
921 **| strings or strings to token integers. (All atomized strings must be in
922 **| US-ASCII iso-8859-1 Latin1 charset encoding.) When a port is actually a
923 **| mutable store and a string has not yet been atomized, then StringToToken()
924 **| will actually do so and modify the store. The QueryToken() method will not
925 **| atomize a string if it has not already been atomized yet, even in stores.
926 **|
927 **|| tables: other than string tokens, all port content is presented through
928 **| tables, which are ordered collections of rows. Tables are identified by
929 **| row scope and table kind, which might or might not be unique in a port,
930 **| depending on app convention. When tables are effectively unique, then
931 **| queries for specific scope and kind pairs will find those tables. To see
932 **| all tables that match specific row scope and table kind patterns, even in
933 **| the presence of duplicates, every port supports a GetPortTableCursor()
934 **| method that returns an iterator over all matching tables. Table kind is
935 **| considered scoped inside row scope, so passing a zero for table kind will
936 **| find all table kinds for some nonzero row scope. Passing a zero for row
937 **| scope will iterate over all tables in the port, in some undefined order.
938 **| (A new table can be added to a port using nsIMdbStore::NewTable(), even when
939 **| the requested scope and kind combination is already used by other tables.)
940 **|
941 **|| memory: callers can request that a database use less memory footprint in
942 **| several flavors, from an inconsequential idle flavor to a rather drastic
943 **| panic flavor. Callers might perform an idle purge very frequently if desired
944 **| with very little cost, since only normally scheduled memory management will
945 **| be conducted, such as freeing resources for objects scheduled to be dropped.
946 **| Callers should perform session memory purges infrequently because they might
947 **| involve costly scanning of data structures to removed cached content, and
948 **| session purges are recommended only when a caller experiences memory crunch.
949 **| Callers should only rarely perform a panic purge, in response to dire memory
950 **| straits, since this is likely to make db operations much more expensive
951 **| than they would be otherwise. A panic purge asks a database to free as much
952 **| memory as possible while staying effective and operational, because a caller
953 **| thinks application failure might otherwise occur. (Apps might better close
954 **| an open db, so panic purges only make sense when a db is urgently needed.)
955 |*/
956 class nsIMdbPort : public nsISupports {
957 public:
958 // { ===== begin nsIMdbPort methods =====
959
960 // { ----- begin attribute methods -----
961 NS_IMETHOD GetIsPortReadonly(nsIMdbEnv* ev, mdb_bool* outBool) = 0;
962 NS_IMETHOD GetIsStore(nsIMdbEnv* ev, mdb_bool* outBool) = 0;
963 NS_IMETHOD GetIsStoreAndDirty(nsIMdbEnv* ev, mdb_bool* outBool) = 0;
964
965 NS_IMETHOD GetUsagePolicy(nsIMdbEnv* ev, mdbUsagePolicy* ioUsagePolicy) = 0;
966
967 NS_IMETHOD SetUsagePolicy(nsIMdbEnv* ev,
968 const mdbUsagePolicy* inUsagePolicy) = 0;
969 // } ----- end attribute methods -----
970
971 // { ----- begin memory policy methods -----
972 NS_IMETHOD IdleMemoryPurge( // do memory management already scheduled
973 nsIMdbEnv* ev, // context
974 mdb_size* outEstimatedBytesFreed) =
975 0; // approximate bytes actually freed
976
977 NS_IMETHOD SessionMemoryPurge( // request specific footprint decrease
978 nsIMdbEnv* ev, // context
979 mdb_size inDesiredBytesFreed, // approximate number of bytes wanted
980 mdb_size* outEstimatedBytesFreed) =
981 0; // approximate bytes actually freed
982
983 NS_IMETHOD PanicMemoryPurge( // desperately free all possible memory
984 nsIMdbEnv* ev, // context
985 mdb_size* outEstimatedBytesFreed) =
986 0; // approximate bytes actually freed
987 // } ----- end memory policy methods -----
988
989 // { ----- begin filepath methods -----
990 NS_IMETHOD GetPortFilePath(
991 nsIMdbEnv* ev, // context
992 mdbYarn* outFilePath, // name of file holding port content
993 mdbYarn* outFormatVersion) = 0; // file format description
994
995 NS_IMETHOD GetPortFile(nsIMdbEnv* ev, // context
996 nsIMdbFile** acqFile) =
997 0; // acquire file used by port or store
998 // } ----- end filepath methods -----
999
1000 // { ----- begin export methods -----
1001 NS_IMETHOD BestExportFormat( // determine preferred export format
1002 nsIMdbEnv* ev, // context
1003 mdbYarn* outFormatVersion) = 0; // file format description
1004
1005 // some tentative suggested import/export formats
1006 // "ns:msg:db:port:format:ldif:ns4.0:passthrough" // necessary
1007 // "ns:msg:db:port:format:ldif:ns4.5:utf8" // necessary
1008 // "ns:msg:db:port:format:ldif:ns4.5:tabbed"
1009 // "ns:msg:db:port:format:ldif:ns4.5:binary" // necessary
1010 // "ns:msg:db:port:format:html:ns3.0:addressbook" // necessary
1011 // "ns:msg:db:port:format:html:display:verbose"
1012 // "ns:msg:db:port:format:html:display:concise"
1013 // "ns:msg:db:port:format:mork:zany:verbose" // necessary
1014 // "ns:msg:db:port:format:mork:zany:atomized" // necessary
1015 // "ns:msg:db:port:format:rdf:xml"
1016 // "ns:msg:db:port:format:xml:mork"
1017 // "ns:msg:db:port:format:xml:display:verbose"
1018 // "ns:msg:db:port:format:xml:display:concise"
1019 // "ns:msg:db:port:format:xml:print:verbose" // recommended
1020 // "ns:msg:db:port:format:xml:print:concise"
1021
1022 NS_IMETHOD
1023 CanExportToFormat( // can export content in given specific format?
1024 nsIMdbEnv* ev, // context
1025 const char* inFormatVersion, // file format description
1026 mdb_bool* outCanExport) = 0; // whether ExportSource() might succeed
1027
1028 NS_IMETHOD ExportToFormat( // export content in given specific format
1029 nsIMdbEnv* ev, // context
1030 // const char* inFilePath, // the file to receive exported content
1031 nsIMdbFile* ioFile, // destination abstract file interface
1032 const char* inFormatVersion, // file format description
1033 nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental export
1034 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
1035 // then the export will be finished.
1036
1037 // } ----- end export methods -----
1038
1039 // { ----- begin token methods -----
1040 NS_IMETHOD TokenToString( // return a string name for an integer token
1041 nsIMdbEnv* ev, // context
1042 mdb_token inToken, // token for inTokenName inside this port
1043 mdbYarn* outTokenName) = 0; // the type of table to access
1044
1045 NS_IMETHOD StringToToken( // return an integer token for scope name
1046 nsIMdbEnv* ev, // context
1047 const char* inTokenName, // Latin1 string to tokenize if possible
1048 mdb_token* outToken) = 0; // token for inTokenName inside this port
1049
1050 // String token zero is never used and never supported. If the port
1051 // is a mutable store, then StringToToken() to create a new
1052 // association of inTokenName with a new integer token if possible.
1053 // But a readonly port will return zero for an unknown scope name.
1054
1055 NS_IMETHOD QueryToken( // like StringToToken(), but without adding
1056 nsIMdbEnv* ev, // context
1057 const char* inTokenName, // Latin1 string to tokenize if possible
1058 mdb_token* outToken) = 0; // token for inTokenName inside this port
1059
1060 // QueryToken() will return a string token if one already exists,
1061 // but unlike StringToToken(), will not assign a new token if not
1062 // already in use.
1063
1064 // } ----- end token methods -----
1065
1066 // { ----- begin row methods -----
1067 NS_IMETHOD HasRow( // contains a row with the specified oid?
1068 nsIMdbEnv* ev, // context
1069 const mdbOid* inOid, // hypothetical row oid
1070 mdb_bool* outHasRow) = 0; // whether GetRow() might succeed
1071
1072 NS_IMETHOD GetRowRefCount( // get number of tables that contain a row
1073 nsIMdbEnv* ev, // context
1074 const mdbOid* inOid, // hypothetical row oid
1075 mdb_count* outRefCount) = 0; // number of tables containing inRowKey
1076
1077 NS_IMETHOD GetRow( // access one row with specific oid
1078 nsIMdbEnv* ev, // context
1079 const mdbOid* inOid, // hypothetical row oid
1080 nsIMdbRow** acqRow) = 0; // acquire specific row (or null)
1081
1082 // NS_IMETHOD
1083 // GetPortRowCursor( // get cursor for all rows in specific scope
1084 // nsIMdbEnv* ev, // context
1085 // mdb_scope inRowScope, // row scope for row ids
1086 // nsIMdbPortRowCursor** acqCursor) = 0; // all such rows in the port
1087
1088 NS_IMETHOD FindRow(
1089 nsIMdbEnv* ev, // search for row with matching cell
1090 mdb_scope inRowScope, // row scope for row ids
1091 mdb_column inColumn, // the column to search (and maintain an index)
1092 const mdbYarn* inTargetCellValue, // cell value for which to search
1093 mdbOid* outRowOid, // out row oid on match (or {0,-1} for no match)
1094 nsIMdbRow** acqRow) = 0; // acquire matching row (or nil for no match)
1095 // can be null if you only want the oid
1096 // FindRow() searches for one row that has a cell in column inColumn with
1097 // a contained value with the same form (i.e. charset) and is byte-wise
1098 // identical to the blob described by yarn inTargetCellValue. Both content
1099 // and form of the yarn must be an exact match to find a matching row.
1100 //
1101 // (In other words, both a yarn's blob bytes and form are significant. The
1102 // form is not expected to vary in columns used for identity anyway. This
1103 // is intended to make the cost of FindRow() cheaper for MDB implementors,
1104 // since any cell value atomization performed internally must necessarily
1105 // make yarn form significant in order to avoid data loss in atomization.)
1106 //
1107 // FindRow() can lazily create an index on attribute inColumn for all rows
1108 // with that attribute in row space scope inRowScope, so that subsequent
1109 // calls to FindRow() will perform faster. Such an index might or might
1110 // not be persistent (but this seems desirable if it is cheap to do so).
1111 // Note that lazy index creation in readonly DBs is not very feasible.
1112 //
1113 // This FindRow() interface assumes that attribute inColumn is effectively
1114 // an alternative means of unique identification for a row in a rowspace,
1115 // so correct behavior is only guaranteed when no duplicates for this col
1116 // appear in the given set of rows. (If more than one row has the same cell
1117 // value in this column, no more than one will be found; and cutting one of
1118 // two duplicate rows can cause the index to assume no other such row lives
1119 // in the row space, so future calls return nil for negative search results
1120 // even though some duplicate row might still live within the rowspace.)
1121 //
1122 // In other words, the FindRow() implementation is allowed to assume simple
1123 // hash tables mapping unique column keys to associated row values will be
1124 // sufficient, where any duplication is not recorded because only one copy
1125 // of a given key need be remembered. Implementors are not required to sort
1126 // all rows by the specified column.
1127 // } ----- end row methods -----
1128
1129 // { ----- begin table methods -----
1130 NS_IMETHOD HasTable( // supports a table with the specified oid?
1131 nsIMdbEnv* ev, // context
1132 const mdbOid* inOid, // hypothetical table oid
1133 mdb_bool* outHasTable) = 0; // whether GetTable() might succeed
1134
1135 NS_IMETHOD GetTable( // access one table with specific oid
1136 nsIMdbEnv* ev, // context
1137 const mdbOid* inOid, // hypothetical table oid
1138 nsIMdbTable** acqTable) = 0; // acquire specific table (or null)
1139
1140 NS_IMETHOD HasTableKind( // supports a table of the specified type?
1141 nsIMdbEnv* ev, // context
1142 mdb_scope inRowScope, // rid scope for row ids
1143 mdb_kind inTableKind, // the type of table to access
1144 mdb_count* outTableCount, // current number of such tables
1145 mdb_bool* outSupportsTable) = 0; // whether GetTableKind() might succeed
1146
1147 // row scopes to be supported include the following suggestions:
1148 // "ns:msg:db:row:scope:address:cards:all"
1149 // "ns:msg:db:row:scope:mail:messages:all"
1150 // "ns:msg:db:row:scope:news:articles:all"
1151
1152 // table kinds to be supported include the following suggestions:
1153 // "ns:msg:db:table:kind:address:cards:main"
1154 // "ns:msg:db:table:kind:address:lists:all"
1155 // "ns:msg:db:table:kind:address:list"
1156 // "ns:msg:db:table:kind:news:threads:all"
1157 // "ns:msg:db:table:kind:news:thread"
1158 // "ns:msg:db:table:kind:mail:threads:all"
1159 // "ns:msg:db:table:kind:mail:thread"
1160
1161 NS_IMETHOD GetTableKind( // access one (random) table of specific type
1162 nsIMdbEnv* ev, // context
1163 mdb_scope inRowScope, // row scope for row ids
1164 mdb_kind inTableKind, // the type of table to access
1165 mdb_count* outTableCount, // current number of such tables
1166 mdb_bool* outMustBeUnique, // whether port can hold only one of these
1167 nsIMdbTable** acqTable) = 0; // acquire scoped collection of rows
1168
1169 NS_IMETHOD
1170 GetPortTableCursor( // get cursor for all tables of specific type
1171 nsIMdbEnv* ev, // context
1172 mdb_scope inRowScope, // row scope for row ids
1173 mdb_kind inTableKind, // the type of table to access
1174 nsIMdbPortTableCursor** acqCursor) = 0; // all such tables in the port
1175 // } ----- end table methods -----
1176
1177 // { ----- begin commit methods -----
1178
1179 NS_IMETHOD ShouldCompress( // store wastes at least inPercentWaste?
1180 nsIMdbEnv* ev, // context
1181 mdb_percent inPercentWaste, // 0..100 percent file size waste threshold
1182 mdb_percent* outActualWaste, // 0..100 percent of file actually wasted
1183 mdb_bool* outShould) = 0; // true when about inPercentWaste% is wasted
1184 // ShouldCompress() returns true if the store can determine that the file
1185 // will shrink by an estimated percentage of inPercentWaste% (or more) if
1186 // CompressCommit() is called, because that percentage of the file seems
1187 // to be recoverable free space. The granularity is only in terms of
1188 // percentage points, and any value over 100 is considered equal to 100.
1189 //
1190 // If a store only has an approximate idea how much space might be saved
1191 // during a compress, then a best guess should be made. For example, the
1192 // Mork implementation might keep track of how much file space began with
1193 // text content before the first updating transaction, and then consider
1194 // all content following the start of the first transaction as potentially
1195 // wasted space if it is all updates and not just new content. (This is
1196 // a safe assumption in the sense that behavior will stabilize on a low
1197 // estimate of wastage after a commit removes all transaction updates.)
1198 //
1199 // Some db formats might attempt to keep a very accurate reckoning of free
1200 // space size, so a very accurate determination can be made. But other db
1201 // formats might have difficulty determining size of free space, and might
1202 // require some lengthy calculation to answer. This is the reason for
1203 // passing in the percentage threshold of interest, so that such lengthy
1204 // computations can terminate early as soon as at least inPercentWaste is
1205 // found, so that the entire file need not be groveled when unnecessary.
1206 // However, we hope implementations will always favor fast but imprecise
1207 // heuristic answers instead of extremely slow but very precise answers.
1208 //
1209 // If the outActualWaste parameter is non-nil, it will be used to return
1210 // the actual estimated space wasted as a percentage of file size. (This
1211 // parameter is provided so callers need not call repeatedly with altered
1212 // inPercentWaste values to isolate the actual wastage figure.) Note the
1213 // actual wastage figure returned can exactly equal inPercentWaste even
1214 // when this grossly underestimates the real figure involved, if the db
1215 // finds it very expensive to determine the extent of wastage after it is
1216 // known to at least exceed inPercentWaste. Note we expect that whenever
1217 // outShould returns true, that outActualWaste returns >= inPercentWaste.
1218 //
1219 // The effect of different inPercentWaste values is not very uniform over
1220 // the permitted range. For example, 50 represents 50% wastage, or a file
1221 // that is about double what it should be ideally. But 99 represents 99%
1222 // wastage, or a file that is about ninety-nine times as big as it should
1223 // be ideally. In the smaller direction, 25 represents 25% wastage, or
1224 // a file that is only 33% larger than it should be ideally.
1225 //
1226 // Callers can determine what policy they want to use for considering when
1227 // a file holds too much wasted space, and express this as a percentage
1228 // of total file size to pass as in the inPercentWaste parameter. A zero
1229 // likely returns always trivially true, and 100 always trivially false.
1230 // The great majority of callers are expected to use values from 25 to 75,
1231 // since most plausible thresholds for compressing might fall between the
1232 // extremes of 133% of ideal size and 400% of ideal size. (Presumably the
1233 // larger a file gets, the more important the percentage waste involved, so
1234 // a sliding scale for compress thresholds might use smaller numbers for
1235 // much bigger file sizes.)
1236
1237 // } ----- end commit methods -----
1238
1239 // } ===== end nsIMdbPort methods =====
1240 };
1241
1242 /*| nsIMdbStore: a mutable interface to a specific database file.
1243 **|
1244 **|| tables: one can force a new table to exist in a store with NewTable()
1245 **| and nonzero values for both row scope and table kind. (If one wishes only
1246 **| one table of a certain kind, then one might look for it first using the
1247 **| GetTableKind() method). One can pass inMustBeUnique to force future
1248 **| users of this store to be unable to create other tables with the same pair
1249 **| of scope and kind attributes. When inMustBeUnique is true, and the table
1250 **| with the given scope and kind pair already exists, then the existing one
1251 **| is returned instead of making a new table. Similarly, if one passes false
1252 **| for inMustBeUnique, but the table kind has already been marked unique by a
1253 **| previous user of the store, then the existing unique table is returned.
1254 **|
1255 **|| import: all or some of another port's content can be imported by calling
1256 **| AddPortContent() with a row scope identifying the extent of content to
1257 **| be imported. A zero row scope will import everything. A nonzero row
1258 **| scope will only import tables with a matching row scope. Note that one
1259 **| must somehow find a way to negotiate possible conflicts between existing
1260 **| row content and imported row content, and this involves a specific kind of
1261 **| definition for row identity involving either row IDs or unique attributes,
1262 **| or some combination of these two. At the moment I am just going to wave
1263 **| my hands, and say the default behavior is to assign all new row identities
1264 **| to all imported content, which will result in no merging of content; this
1265 **| must change later because it is unacceptable in some contexts.
1266 **|
1267 **|| commits: to manage modifications in a mutable store, very few methods are
1268 **| really needed to indicate global policy choices that are independent of
1269 **| the actual modifications that happen in objects at the level of tables,
1270 **| rows, and cells, etc. The most important policy to specify is which sets
1271 **| of changes are considered associated in a manner such that they should be
1272 **| applied together atomically to a given store. We call each such group of
1273 **| changes a transaction. We handle three different grades of transaction,
1274 **| but they differ only in semantic significance to the application, and are
1275 **| not intended to nest. (If small transactions were nested inside large
1276 **| transactions, that would imply that a single large transaction must be
1277 **| atomic over all the contained small transactions; but actually we intend
1278 **| smalls transaction never be undone once committed due to, say, aborting a
1279 **| transaction of greater significance.) The small, large, and session level
1280 **| commits have equal granularity, and differ only in risk of loss from the
1281 **| perspective of an application. Small commits characterize changes that
1282 **| can be lost with relatively small risk, so small transactions can delay
1283 **| until later if they are expensive or impractical to commit. Large commits
1284 **| involve changes that would probably inconvenience users if lost, so the
1285 **| need to pay costs of writing is rather greater than with small commits.
1286 **| Session commits are last ditch attempts to save outstanding changes before
1287 **| stopping the use of a particular database, so there will be no later point
1288 **| in time to save changes that have been delayed due to possible high cost.
1289 **| If large commits are never delayed, then a session commit has about the
1290 **| same performance effect as another large commit; but if small and large
1291 **| commits are always delayed, then a session commit is likely to be rather
1292 **| expensive as a runtime cost compared to any earlier database usage.
1293 **|
1294 **|| aborts: the only way to abort changes to a store is by closing the store.
1295 **| So there is no specific method for causing any abort. Stores must discard
1296 **| all changes made that are uncommitted when a store is closed. This design
1297 **| choice makes the implementations of tables, rows, and cells much less
1298 **| complex because they need not maintain a record of undobable changes. When
1299 **| a store is closed, presumably this precipitates the closure of all tables,
1300 **| rows, and cells in the store as well. So an application can revert the
1301 **| state of a store in the user interface by quietly closing and reopening a
1302 **| store, because this will discard uncommitted changes and show old content.
1303 **| This implies an app that closes a store will need to send a "scramble"
1304 **| event notification to any views that depend on old discarded content.
1305 |*/
1306
1307 #define NS_IMDBSTORE_IID_STR "74d6218d-44b0-43b5-9ebe-69a17dfb562c"
1308 #define NS_IMDBSTORE_IID \
1309 { \
1310 0x74d6218d, 0x44b0, 0x43b5, { \
1311 0x9e, 0xbe, 0x69, 0xa1, 0x7d, 0xfb, 0x56, 0x2c \
1312 } \
1313 }
1314
1315 class nsIMdbStore : public nsIMdbPort {
1316 public:
1317 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBSTORE_IID)
1318
1319 // { ===== begin nsIMdbStore methods =====
1320
1321 // { ----- begin table methods -----
1322 NS_IMETHOD NewTable( // make one new table of specific type
1323 nsIMdbEnv* ev, // context
1324 mdb_scope inRowScope, // row scope for row ids
1325 mdb_kind inTableKind, // the type of table to access
1326 mdb_bool inMustBeUnique, // whether store can hold only one of these
1327 const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
1328 nsIMdbTable** acqTable) = 0; // acquire scoped collection of rows
1329
1330 NS_IMETHOD NewTableWithOid( // make one new table of specific type
1331 nsIMdbEnv* ev, // context
1332 const mdbOid* inOid, // caller assigned oid
1333 mdb_kind inTableKind, // the type of table to access
1334 mdb_bool inMustBeUnique, // whether store can hold only one of these
1335 const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
1336 nsIMdbTable** acqTable) = 0; // acquire scoped collection of rows
1337 // } ----- end table methods -----
1338
1339 // { ----- begin row scope methods -----
1340 NS_IMETHOD RowScopeHasAssignedIds(
1341 nsIMdbEnv* ev,
1342 mdb_scope inRowScope, // row scope for row ids
1343 mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
1344 mdb_bool* outStoreAssigned) =
1345 0; // nonzero if store db assigned specified
1346
1347 NS_IMETHOD SetCallerAssignedIds(
1348 nsIMdbEnv* ev,
1349 mdb_scope inRowScope, // row scope for row ids
1350 mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
1351 mdb_bool* outStoreAssigned) =
1352 0; // nonzero if store db assigned specified
1353
1354 NS_IMETHOD SetStoreAssignedIds(
1355 nsIMdbEnv* ev,
1356 mdb_scope inRowScope, // row scope for row ids
1357 mdb_bool* outCallerAssigned, // nonzero if caller assigned specified
1358 mdb_bool* outStoreAssigned) =
1359 0; // nonzero if store db assigned specified
1360 // } ----- end row scope methods -----
1361
1362 // { ----- begin row methods -----
1363 NS_IMETHOD NewRowWithOid(nsIMdbEnv* ev, // new row w/ caller assigned oid
1364 const mdbOid* inOid, // caller assigned oid
1365 nsIMdbRow** acqRow) = 0; // create new row
1366
1367 NS_IMETHOD NewRow(nsIMdbEnv* ev, // new row with db assigned oid
1368 mdb_scope inRowScope, // row scope for row ids
1369 nsIMdbRow** acqRow) = 0; // create new row
1370 // Note this row must be added to some table or cell child before the
1371 // store is closed in order to make this row persist across sessions.
1372
1373 // } ----- end row methods -----
1374
1375 // { ----- begin import/export methods -----
1376 NS_IMETHOD ImportContent( // import content from port
1377 nsIMdbEnv* ev, // context
1378 mdb_scope inRowScope, // scope for rows (or zero for all?)
1379 nsIMdbPort* ioPort, // the port with content to add to store
1380 nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental import
1381 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
1382 // then the import will be finished.
1383
1384 NS_IMETHOD ImportFile( // import content from port
1385 nsIMdbEnv* ev, // context
1386 nsIMdbFile* ioFile, // the file with content to add to store
1387 nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental import
1388 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
1389 // then the import will be finished.
1390 // } ----- end import/export methods -----
1391
1392 // { ----- begin hinting methods -----
1393 NS_IMETHOD
1394 ShareAtomColumnsHint( // advise re shared column content atomizing
1395 nsIMdbEnv* ev, // context
1396 mdb_scope inScopeHint, // zero, or suggested shared namespace
1397 const mdbColumnSet* inColumnSet) = 0; // cols desired tokenized together
1398
1399 NS_IMETHOD
1400 AvoidAtomColumnsHint( // advise column with poor atomizing prospects
1401 nsIMdbEnv* ev, // context
1402 const mdbColumnSet* inColumnSet) =
1403 0; // cols with poor atomizing prospects
1404 // } ----- end hinting methods -----
1405
1406 // { ----- begin commit methods -----
1407 NS_IMETHOD LargeCommit( // save important changes if at all possible
1408 nsIMdbEnv* ev, // context
1409 nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental commit
1410 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
1411 // then the commit will be finished. Note the store is effectively write
1412 // locked until commit is finished or canceled through the thumb instance.
1413 // Until the commit is done, the store will report it has readonly status.
1414
1415 NS_IMETHOD SessionCommit( // save all changes if large commits delayed
1416 nsIMdbEnv* ev, // context
1417 nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental commit
1418 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
1419 // then the commit will be finished. Note the store is effectively write
1420 // locked until commit is finished or canceled through the thumb instance.
1421 // Until the commit is done, the store will report it has readonly status.
1422
1423 NS_IMETHOD
1424 CompressCommit( // commit and make db physically smaller if possible
1425 nsIMdbEnv* ev, // context
1426 nsIMdbThumb** acqThumb) = 0; // acquire thumb for incremental commit
1427 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
1428 // then the commit will be finished. Note the store is effectively write
1429 // locked until commit is finished or canceled through the thumb instance.
1430 // Until the commit is done, the store will report it has readonly status.
1431
1432 // } ----- end commit methods -----
1433
1434 // } ===== end nsIMdbStore methods =====
1435 };
1436
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbStore,NS_IMDBSTORE_IID)1437 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbStore, NS_IMDBSTORE_IID)
1438
1439 /*| nsIMdbCursor: base cursor class for iterating row cells and table rows
1440 **|
1441 **|| count: the number of elements in the collection (table or row)
1442 **|
1443 **|| seed: the change count in the underlying collection, which is synced
1444 **| with the collection when the iteration position is set, and henceforth
1445 **| acts to show whether the iter has lost collection synchronization, in
1446 **| case it matters to clients whether any change happens during iteration.
1447 **|
1448 **|| pos: the position of the current element in the collection. Negative
1449 **| means a position logically before the first element. A positive value
1450 **| equal to count (or larger) implies a position after the last element.
1451 **| To iterate over all elements, set the position to negative, so subsequent
1452 **| calls to any 'next' method will access the first collection element.
1453 **|
1454 **|| doFailOnSeedOutOfSync: whether a cursor should return an error if the
1455 **| cursor's snapshot of a table's seed becomes stale with respect the table's
1456 **| current seed value (which implies the iteration is less than total) in
1457 **| between to cursor calls that actually access collection content. By
1458 **| default, a cursor should assume this attribute is false until specified,
1459 **| so that iterations quietly try to re-sync when they lose coherence.
1460 |*/
1461
1462 #define NS_IMDBCURSOR_IID_STR "a0c37337-6ebc-474c-90db-e65ea0b850aa"
1463
1464 #define NS_IMDBCURSOR_IID \
1465 { \
1466 0xa0c37337, 0x6ebc, 0x474c, { \
1467 0x90, 0xdb, 0xe6, 0x5e, 0xa0, 0xb8, 0x50, 0xaa \
1468 } \
1469 }
1470
1471 class nsIMdbCursor : public nsISupports { // collection iterator
1472 public:
1473 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBCURSOR_IID)
1474 // { ===== begin nsIMdbCursor methods =====
1475
1476 // { ----- begin attribute methods -----
1477 NS_IMETHOD GetCount(nsIMdbEnv* ev, mdb_count* outCount) = 0; // readonly
1478 NS_IMETHOD GetSeed(nsIMdbEnv* ev, mdb_seed* outSeed) = 0; // readonly
1479
1480 NS_IMETHOD SetPos(nsIMdbEnv* ev, mdb_pos inPos) = 0; // mutable
1481 NS_IMETHOD GetPos(nsIMdbEnv* ev, mdb_pos* outPos) = 0;
1482
1483 NS_IMETHOD SetDoFailOnSeedOutOfSync(nsIMdbEnv* ev, mdb_bool inFail) = 0;
1484 NS_IMETHOD GetDoFailOnSeedOutOfSync(nsIMdbEnv* ev, mdb_bool* outFail) = 0;
1485 // } ----- end attribute methods -----
1486
1487 // } ===== end nsIMdbCursor methods =====
1488 };
1489
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbCursor,NS_IMDBCURSOR_IID)1490 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbCursor, NS_IMDBCURSOR_IID)
1491
1492 #define NS_IMDBPORTTABLECURSOR_IID_STR = "f181a41e-933d-49b3-af93-20d3634b8b78"
1493
1494 #define NS_IMDBPORTTABLECURSOR_IID \
1495 { \
1496 0xf181a41e, 0x933d, 0x49b3, { \
1497 0xaf, 0x93, 0x20, 0xd3, 0x63, 0x4b, 0x8b, 0x78 \
1498 } \
1499 }
1500
1501 /*| nsIMdbPortTableCursor: cursor class for iterating port tables
1502 **|
1503 **|| port: the cursor is associated with a specific port, which can be
1504 **| set to a different port (which resets the position to -1 so the
1505 **| next table acquired is the first in the port.
1506 **|
1507 |*/
1508 class nsIMdbPortTableCursor : public nsISupports { // table collection iterator
1509 public:
1510 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBPORTTABLECURSOR_IID)
1511 // { ===== begin nsIMdbPortTableCursor methods =====
1512
1513 // { ----- begin attribute methods -----
1514 NS_IMETHOD SetPort(nsIMdbEnv* ev, nsIMdbPort* ioPort) = 0; // sets pos to -1
1515 NS_IMETHOD GetPort(nsIMdbEnv* ev, nsIMdbPort** acqPort) = 0;
1516
1517 NS_IMETHOD SetRowScope(nsIMdbEnv* ev, // sets pos to -1
1518 mdb_scope inRowScope) = 0;
1519 NS_IMETHOD GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope) = 0;
1520 // setting row scope to zero iterates over all row scopes in port
1521
1522 NS_IMETHOD SetTableKind(nsIMdbEnv* ev, // sets pos to -1
1523 mdb_kind inTableKind) = 0;
1524 NS_IMETHOD GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind) = 0;
1525 // setting table kind to zero iterates over all table kinds in row scope
1526 // } ----- end attribute methods -----
1527
1528 // { ----- begin table iteration methods -----
1529 NS_IMETHOD NextTable( // get table at next position in the db
1530 nsIMdbEnv* ev, // context
1531 nsIMdbTable** acqTable) = 0; // the next table in the iteration
1532 // } ----- end table iteration methods -----
1533
1534 // } ===== end nsIMdbPortTableCursor methods =====
1535 };
1536
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbPortTableCursor,NS_IMDBPORTTABLECURSOR_IID)1537 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbPortTableCursor, NS_IMDBPORTTABLECURSOR_IID)
1538
1539 /*| nsIMdbCollection: an object that collects a set of other objects as members.
1540 **| The main purpose of this base class is to unify the perceived semantics
1541 **| of tables and rows where their collection behavior is similar. This helps
1542 **| isolate the mechanics of collection behavior from the other semantics that
1543 **| are more characteristic of rows and tables.
1544 **|
1545 **|| count: the number of objects in a collection is the member count. (Some
1546 **| collection interfaces call this attribute the 'size', but that can be a
1547 **| little ambiguous, and counting actual members is harder to confuse.)
1548 **|
1549 **|| seed: the seed of a collection is a counter for changes in membership in
1550 **| a specific collection. This seed should change when members are added to
1551 **| or removed from a collection, but not when a member changes internal state.
1552 **| The seed should also change whenever the internal collection of members has
1553 **| a complex state change that reorders member positions (say by sorting) that
1554 **| would affect the nature of an iteration over that collection of members.
1555 **| The purpose of a seed is to inform any outstanding collection cursors that
1556 **| they might be stale, without incurring the cost of broadcasting an event
1557 **| notification to such cursors, which would need more data structure support.
1558 **| Presumably a cursor in a particular mdb code suite has much more direct
1559 **| access to a collection seed member slot that this abstract COM interface,
1560 **| so this information is intended more for clients outside mdb that want to
1561 **| make inferences similar to those made by the collection cursors. The seed
1562 **| value as an integer magnitude is not very important, and callers should not
1563 **| assume meaningful information can be derived from an integer value beyond
1564 **| whether it is equal or different from a previous inspection. A seed uses
1565 **| integers of many bits in order to make the odds of wrapping and becoming
1566 **| equal to an earlier seed value have probability that is vanishingly small.
1567 **|
1568 **|| port: every collection is associated with a specific database instance.
1569 **|
1570 **|| cursor: a subclass of nsIMdbCursor suitable for this specific collection
1571 **| subclass. The ability to GetCursor() from the base nsIMdbCollection class
1572 **| is not really as useful as getting a more specifically typed cursor more
1573 **| directly from the base class without any casting involved. So including
1574 **| this method here is more for conceptual illustration.
1575 **|
1576 **|| oid: every collection has an identity that persists from session to
1577 **| session. Implementations are probably able to distinguish row IDs from
1578 **| table IDs, but we don't specify anything official in this regard. A
1579 **| collection has the same identity for the lifetime of the collection,
1580 **| unless identity is swapped with another collection by means of a call to
1581 **| BecomeContent(), which is considered a way to swap a new representation
1582 **| for an old well-known object. (Even so, only content appears to change,
1583 **| while the identity seems to stay the same.)
1584 **|
1585 **|| become: developers can effectively cause two objects to swap identities,
1586 **| in order to effect a complete swap between what persistent content is
1587 **| represented by two oids. The caller should consider this a content swap,
1588 **| and not identity wap, because identities will seem to stay the same while
1589 **| only content changes. However, implementations will likely do this
1590 **| internally by swapping identities. Callers must swap content only
1591 **| between objects of similar type, such as a row with another row, and a
1592 **| table with another table, because implementations need not support
1593 **| cross-object swapping because it might break object name spaces.
1594 **|
1595 **|| dropping: when a caller expects a row or table will no longer be used, the
1596 **| caller can tell the collection to 'drop activity', which means the runtime
1597 **| object can have its internal representation purged to save memory or any
1598 **| other resource that is being consumed by the collection's representation.
1599 **| This has no effect on the collection's persistent content or semantics,
1600 **| and is only considered a runtime effect. After a collection drops
1601 **| activity, the object should still be as usable as before (because it has
1602 **| NOT been closed), but further usage can be expensive to re-instate because
1603 **| it might involve reallocating space and/or re-reading disk space. But
1604 **| since this future usage is not expected, the caller does not expect to
1605 **| pay the extra expense. An implementation can choose to implement
1606 **| 'dropping activity' in different ways, or even not at all if this
1607 **| operation is not really feasible. Callers cannot ask objects whether they
1608 **| are 'dropped' or not, so this should be transparent. (Note that
1609 **| implementors might fear callers do not really know whether future
1610 **| usage will occur, and therefore might delay the act of dropping until
1611 **| the near future, until seeing whether the object is used again
1612 **| immediately elsewhere. Such use soon after the drop request might cause
1613 **| the drop to be cancelled.)
1614 |*/
1615 class nsIMdbCollection : public nsISupports { // sequence of objects
1616 public:
1617 // { ===== begin nsIMdbCollection methods =====
1618
1619 // { ----- begin attribute methods -----
1620 NS_IMETHOD GetSeed(nsIMdbEnv* ev,
1621 mdb_seed* outSeed) = 0; // member change count
1622 NS_IMETHOD GetCount(nsIMdbEnv* ev,
1623 mdb_count* outCount) = 0; // member count
1624
1625 NS_IMETHOD GetPort(nsIMdbEnv* ev,
1626 nsIMdbPort** acqPort) = 0; // collection container
1627 // } ----- end attribute methods -----
1628
1629 // { ----- begin cursor methods -----
1630 NS_IMETHOD GetCursor( // make a cursor starting iter at inMemberPos
1631 nsIMdbEnv* ev, // context
1632 mdb_pos inMemberPos, // zero-based ordinal pos of member in collection
1633 nsIMdbCursor** acqCursor) = 0; // acquire new cursor instance
1634 // } ----- end cursor methods -----
1635
1636 // { ----- begin ID methods -----
1637 NS_IMETHOD GetOid(nsIMdbEnv* ev,
1638 mdbOid* outOid) = 0; // read object identity
1639 NS_IMETHOD BecomeContent(nsIMdbEnv* ev,
1640 const mdbOid* inOid) = 0; // exchange content
1641 // } ----- end ID methods -----
1642
1643 // { ----- begin activity dropping methods -----
1644 NS_IMETHOD DropActivity( // tell collection usage no longer expected
1645 nsIMdbEnv* ev) = 0;
1646 // } ----- end activity dropping methods -----
1647
1648 // } ===== end nsIMdbCollection methods =====
1649 };
1650
1651 /*| nsIMdbTable: an ordered collection of rows
1652 **|
1653 **|| row scope: an integer token for an atomized string in this database
1654 **| that names a space for row IDs. This attribute of a table is intended
1655 **| as guidance metainformation that helps with searching a database for
1656 **| tables that operate on collections of rows of the specific type. By
1657 **| convention, a table with a specific row scope is expected to focus on
1658 **| containing rows that belong to that scope, however exceptions are easily
1659 **| allowed because all rows in a table are known by both row ID and scope.
1660 **| (A table with zero row scope is never allowed because this would make it
1661 **| ambiguous to use a zero row scope when iterating over tables in a port to
1662 **| indicate that all row scopes should be seen by a cursor.)
1663 **|
1664 **|| table kind: an integer token for an atomized string in this database
1665 **| that names a kind of table as a subset of the associated row scope. This
1666 **| attribute is intended as guidance metainformation to clarify the role of
1667 **| this table with respect to other tables in the same row scope, and this
1668 **| also helps search for such tables in a database. By convention, a table
1669 **| with a specific table kind has a consistent role for containing rows with
1670 **| respect to other collections of such rows in the same row scope. Also by
1671 **| convention, at least one table in a row scope has a table kind purporting
1672 **| to contain ALL the rows that belong in that row scope, so that at least
1673 **| one table exists that allows all rows in a scope to be iterated over.
1674 **| (A table with zero table kind is never allowed because this would make it
1675 **| ambiguous to use a zero table kind when iterating over tables in a port to
1676 **| indicate that all table kinds in a row scope should be seen by a cursor.)
1677 **|
1678 **|| port: every table is considered part of some port that contains the
1679 **| table, so that closing the containing port will cause the table to be
1680 **| indirectly closed as well. We make it easy to get the containing port for
1681 **| a table, because the port supports important semantic interfaces that will
1682 **| affect how content in table is presented; the most important port context
1683 **| that affects a table is specified by the set of token to string mappings
1684 **| that affect all tokens used throughout the database, and which drive the
1685 **| meanings of row scope, table kind, cell columns, etc.
1686 **|
1687 **|| cursor: a cursor that iterates over the rows in this table, where rows
1688 **| have zero-based index positions from zero to count-1. Making a cursor
1689 **| with negative position will next iterate over the first row in the table.
1690 **|
1691 **|| position: given any position from zero to count-1, a table will return
1692 **| the row ID and row scope for the row at that position. (One can use the
1693 **| GetRowAllCells() method to read that row, or else use a row cursor to both
1694 **| get the row at some position and read its content at the same time.) The
1695 **| position depends on whether a table is sorted, and upon the actual sort.
1696 **| Note that moving a row's position is only possible in unsorted tables.
1697 **|
1698 **|| row set: every table contains a collection of rows, where a member row is
1699 **| referenced by the table using the row ID and row scope for the row. No
1700 **| single table owns a given row instance, because rows are effectively ref-
1701 **| counted and destroyed only when the last table removes a reference to that
1702 **| particular row. (But a row can be emptied of all content no matter how
1703 **| many refs exist, and this might be the next best thing to destruction.)
1704 **| Once a row exists in a least one table (after NewRow() is called), then it
1705 **| can be added to any other table by calling AddRow(), or removed from any
1706 **| table by calling CutRow(), or queried as a member by calling HasRow(). A
1707 **| row can only be added to a table once, and further additions do nothing and
1708 **| complain not at all. Cutting a row from a table only does something when
1709 **| the row was actually a member, and otherwise does nothing silently.
1710 **|
1711 **|| row ref count: one can query the number of tables (and/or cells)
1712 **| containing a row as a member or a child.
1713 **|
1714 **|| row content: one can access or modify the cell content in a table's row
1715 **| by moving content to or from an instance of nsIMdbRow. Note that nsIMdbRow
1716 **| never represents the actual row inside a table, and this is the reason
1717 **| why nsIMdbRow instances do not have row IDs or row scopes. So an instance
1718 **| of nsIMdbRow always and only contains a snapshot of some or all content in
1719 **| past, present, or future persistent row inside a table. This means that
1720 **| reading and writing rows in tables has strictly copy semantics, and we
1721 **| currently do not plan any exceptions for specific performance reasons.
1722 **|
1723 **|| sorting: note all rows are assumed sorted by row ID as a secondary
1724 **| sort following the primary column sort, when table rows are sorted.
1725 **|
1726 **|| indexes:
1727 |*/
1728
1729 #define NS_IMDBTABLE_IID_STR = "fe11bc98-d02b-4128-9fac-87042fdf9639"
1730
1731 #define NS_IMDBTABLE_IID \
1732 { \
1733 0xfe11bc98, 0xd02b, 0x4128, { \
1734 0x9f, 0xac, 0x87, 0x04, 0x2f, 0xdf, 0x96, 0x39 \
1735 } \
1736 }
1737
1738 class nsIMdbTable : public nsIMdbCollection { // a collection of rows
1739 public:
1740 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBTABLE_IID)
1741 // { ===== begin nsIMdbTable methods =====
1742
1743 // { ----- begin meta attribute methods -----
1744 NS_IMETHOD SetTablePriority(nsIMdbEnv* ev, mdb_priority inPrio) = 0;
1745 NS_IMETHOD GetTablePriority(nsIMdbEnv* ev, mdb_priority* outPrio) = 0;
1746
1747 NS_IMETHOD GetTableBeVerbose(nsIMdbEnv* ev, mdb_bool* outBeVerbose) = 0;
1748 NS_IMETHOD SetTableBeVerbose(nsIMdbEnv* ev, mdb_bool inBeVerbose) = 0;
1749
1750 NS_IMETHOD GetTableIsUnique(nsIMdbEnv* ev, mdb_bool* outIsUnique) = 0;
1751
1752 NS_IMETHOD GetTableKind(nsIMdbEnv* ev, mdb_kind* outTableKind) = 0;
1753 NS_IMETHOD GetRowScope(nsIMdbEnv* ev, mdb_scope* outRowScope) = 0;
1754
1755 NS_IMETHOD GetMetaRow(
1756 nsIMdbEnv* ev, // context
1757 const mdbOid* inOptionalMetaRowOid, // can be nil to avoid specifying
1758 mdbOid* outOid, // output meta row oid, can be nil to suppress output
1759 nsIMdbRow** acqRow) = 0; // acquire table's unique singleton meta row
1760 // The purpose of a meta row is to support the persistent recording of
1761 // meta info about a table as cells put into the distinguished meta row.
1762 // Each table has exactly one meta row, which is not considered a member
1763 // of the collection of rows inside the table. The only way to tell
1764 // whether a row is a meta row is by the fact that it is returned by this
1765 // GetMetaRow() method from some table. Otherwise nothing distinguishes
1766 // a meta row from any other row. A meta row can be used anyplace that
1767 // any other row can be used, and can even be put into other tables (or
1768 // the same table) as a table member, if this is useful for some reason.
1769 // The first attempt to access a table's meta row using GetMetaRow() will
1770 // cause the meta row to be created if it did not already exist. When the
1771 // meta row is created, it will have the row oid that was previously
1772 // requested for this table's meta row; or if no oid was ever explicitly
1773 // specified for this meta row, then a unique oid will be generated in
1774 // the row scope named "m" (so obviously MDB clients should not
1775 // manually allocate any row IDs from that special meta scope namespace).
1776 // The meta row oid can be specified either when the table is created, or
1777 // else the first time that GetMetaRow() is called, by passing a non-nil
1778 // pointer to an oid for parameter inOptionalMetaRowOid. The meta row's
1779 // actual oid is returned in outOid (if this is a non-nil pointer), and
1780 // it will be different from inOptionalMetaRowOid when the meta row was
1781 // already given a different oid earlier.
1782 // } ----- end meta attribute methods -----
1783
1784 // { ----- begin cursor methods -----
1785 NS_IMETHOD
1786 GetTableRowCursor( // make a cursor, starting iteration at inRowPos
1787 nsIMdbEnv* ev, // context
1788 mdb_pos inRowPos, // zero-based ordinal position of row in table
1789 nsIMdbTableRowCursor** acqCursor) = 0; // acquire new cursor instance
1790 // } ----- end row position methods -----
1791
1792 // { ----- begin row position methods -----
1793 NS_IMETHOD PosToOid( // get row member for a table position
1794 nsIMdbEnv* ev, // context
1795 mdb_pos inRowPos, // zero-based ordinal position of row in table
1796 mdbOid* outOid) = 0; // row oid at the specified position
1797
1798 NS_IMETHOD OidToPos( // test for the table position of a row member
1799 nsIMdbEnv* ev, // context
1800 const mdbOid* inOid, // row to find in table
1801 mdb_pos* outPos) = 0; // zero-based ordinal position of row in table
1802
1803 NS_IMETHOD PosToRow( // test for the table position of a row member
1804 nsIMdbEnv* ev, // context
1805 mdb_pos inRowPos, // zero-based ordinal position of row in table
1806 nsIMdbRow** acqRow) = 0; // acquire row at table position inRowPos
1807
1808 NS_IMETHOD RowToPos( // test for the table position of a row member
1809 nsIMdbEnv* ev, // context
1810 nsIMdbRow* ioRow, // row to find in table
1811 mdb_pos* outPos) = 0; // zero-based ordinal position of row in table
1812 // } ----- end row position methods -----
1813
1814 // { ----- begin oid set methods -----
1815 NS_IMETHOD AddOid( // make sure the row with inOid is a table member
1816 nsIMdbEnv* ev, // context
1817 const mdbOid* inOid) = 0; // row to ensure membership in table
1818
1819 NS_IMETHOD HasOid( // test for the table position of a row member
1820 nsIMdbEnv* ev, // context
1821 const mdbOid* inOid, // row to find in table
1822 mdb_bool* outHasOid) = 0; // whether inOid is a member row
1823
1824 NS_IMETHOD CutOid( // make sure the row with inOid is not a member
1825 nsIMdbEnv* ev, // context
1826 const mdbOid* inOid) = 0; // row to remove from table
1827 // } ----- end oid set methods -----
1828
1829 // { ----- begin row set methods -----
1830 NS_IMETHOD NewRow( // create a new row instance in table
1831 nsIMdbEnv* ev, // context
1832 mdbOid*
1833 ioOid, // please use minus one (unbound) rowId for db-assigned IDs
1834 nsIMdbRow** acqRow) = 0; // create new row
1835
1836 NS_IMETHOD AddRow( // make sure the row with inOid is a table member
1837 nsIMdbEnv* ev, // context
1838 nsIMdbRow* ioRow) = 0; // row to ensure membership in table
1839
1840 NS_IMETHOD HasRow( // test for the table position of a row member
1841 nsIMdbEnv* ev, // context
1842 nsIMdbRow* ioRow, // row to find in table
1843 mdb_bool* outHasRow) = 0; // whether row is a table member
1844
1845 NS_IMETHOD CutRow( // make sure the row with inOid is not a member
1846 nsIMdbEnv* ev, // context
1847 nsIMdbRow* ioRow) = 0; // row to remove from table
1848
1849 NS_IMETHOD CutAllRows( // remove all rows from the table
1850 nsIMdbEnv* ev) = 0; // context
1851 // } ----- end row set methods -----
1852
1853 // { ----- begin hinting methods -----
1854 NS_IMETHOD SearchColumnsHint( // advise re future expected search cols
1855 nsIMdbEnv* ev, // context
1856 const mdbColumnSet* inColumnSet) = 0; // columns likely to be searched
1857
1858 NS_IMETHOD SortColumnsHint( // advise re future expected sort columns
1859 nsIMdbEnv* ev, // context
1860 const mdbColumnSet* inColumnSet) = 0; // columns for likely sort requests
1861
1862 NS_IMETHOD StartBatchChangeHint( // advise before many adds and cuts
1863 nsIMdbEnv* ev, // context
1864 const void* inLabel) = 0; // intend unique address to match end call
1865 // If batch starts nest by virtue of nesting calls in the stack, then
1866 // the address of a local variable makes a good batch start label that
1867 // can be used at batch end time, and such addresses remain unique.
1868
1869 NS_IMETHOD EndBatchChangeHint( // advise before many adds and cuts
1870 nsIMdbEnv* ev, // context
1871 const void* inLabel) = 0; // label matching start label
1872 // Suppose a table is maintaining one or many sort orders for a table,
1873 // so that every row added to the table must be inserted in each sort,
1874 // and every row cut must be removed from each sort. If a db client
1875 // intends to make many such changes before needing any information
1876 // about the order or positions of rows inside a table, then a client
1877 // might tell the table to start batch changes in order to disable
1878 // sorting of rows for the interim. Presumably a table will then do
1879 // a full sort of all rows at need when the batch changes end, or when
1880 // a surprise request occurs for row position during batch changes.
1881 // } ----- end hinting methods -----
1882
1883 // { ----- begin searching methods -----
1884 NS_IMETHOD FindRowMatches( // search variable number of sorted cols
1885 nsIMdbEnv* ev, // context
1886 const mdbYarn*
1887 inPrefix, // content to find as prefix in row's column cell
1888 nsIMdbTableRowCursor** acqCursor) = 0; // set of matching rows
1889
1890 NS_IMETHOD GetSearchColumns( // query columns used by FindRowMatches()
1891 nsIMdbEnv* ev, // context
1892 mdb_count* outCount, // context
1893 mdbColumnSet* outColSet) = 0; // caller supplied space to put columns
1894 // GetSearchColumns() returns the columns actually searched when the
1895 // FindRowMatches() method is called. No more than mColumnSet_Count
1896 // slots of mColumnSet_Columns will be written, since mColumnSet_Count
1897 // indicates how many slots are present in the column array. The
1898 // actual number of search column used by the table is returned in
1899 // the outCount parameter; if this number exceeds mColumnSet_Count,
1900 // then a caller needs a bigger array to read the entire column set.
1901 // The minimum of mColumnSet_Count and outCount is the number slots
1902 // in mColumnSet_Columns that were actually written by this method.
1903 //
1904 // Callers are expected to change this set of columns by calls to
1905 // nsIMdbTable::SearchColumnsHint() or SetSearchSorting(), or both.
1906 // } ----- end searching methods -----
1907
1908 // { ----- begin sorting methods -----
1909 // sorting: note all rows are assumed sorted by row ID as a secondary
1910 // sort following the primary column sort, when table rows are sorted.
1911
1912 NS_IMETHOD
1913 CanSortColumn( // query which column is currently used for sorting
1914 nsIMdbEnv* ev, // context
1915 mdb_column inColumn, // column to query sorting potential
1916 mdb_bool* outCanSort) = 0; // whether the column can be sorted
1917
1918 NS_IMETHOD GetSorting( // view same table in particular sorting
1919 nsIMdbEnv* ev, // context
1920 mdb_column inColumn, // requested new column for sorting table
1921 nsIMdbSorting** acqSorting) = 0; // acquire sorting for column
1922
1923 NS_IMETHOD SetSearchSorting( // use this sorting in FindRowMatches()
1924 nsIMdbEnv* ev, // context
1925 mdb_column inColumn, // often same as nsIMdbSorting::GetSortColumn()
1926 nsIMdbSorting* ioSorting) = 0; // requested sorting for some column
1927 // SetSearchSorting() attempts to inform the table that ioSorting
1928 // should be used during calls to FindRowMatches() for searching
1929 // the column which is actually sorted by ioSorting. This method
1930 // is most useful in conjunction with nsIMdbSorting::SetCompare(),
1931 // because otherwise a caller would not be able to override the
1932 // comparison ordering method used during searches. Note that some
1933 // database implementations might be unable to use an arbitrarily
1934 // specified sort order, either due to schema or runtime interface
1935 // constraints, in which case ioSorting might not actually be used.
1936 // Presumably ioSorting is an instance that was returned from some
1937 // earlier call to nsIMdbTable::GetSorting(). A caller can also
1938 // use nsIMdbTable::SearchColumnsHint() to specify desired change
1939 // in which columns are sorted and searched by FindRowMatches().
1940 //
1941 // A caller can pass a nil pointer for ioSorting to request that
1942 // column inColumn no longer be used at all by FindRowMatches().
1943 // But when ioSorting is non-nil, then inColumn should match the
1944 // column actually sorted by ioSorting; when these do not agree,
1945 // implementations are instructed to give precedence to the column
1946 // specified by ioSorting (so this means callers might just pass
1947 // zero for inColumn when ioSorting is also provided, since then
1948 // inColumn is both redundant and ignored).
1949 // } ----- end sorting methods -----
1950
1951 // { ----- begin moving methods -----
1952 // moving a row does nothing unless a table is currently unsorted
1953
1954 NS_IMETHOD MoveOid( // change position of row in unsorted table
1955 nsIMdbEnv* ev, // context
1956 const mdbOid* inOid, // row oid to find in table
1957 mdb_pos inHintFromPos, // suggested hint regarding start position
1958 mdb_pos inToPos, // desired new position for row inRowId
1959 mdb_pos* outActualPos) = 0; // actual new position of row in table
1960
1961 NS_IMETHOD MoveRow( // change position of row in unsorted table
1962 nsIMdbEnv* ev, // context
1963 nsIMdbRow* ioRow, // row oid to find in table
1964 mdb_pos inHintFromPos, // suggested hint regarding start position
1965 mdb_pos inToPos, // desired new position for row inRowId
1966 mdb_pos* outActualPos) = 0; // actual new position of row in table
1967 // } ----- end moving methods -----
1968
1969 // { ----- begin index methods -----
1970 NS_IMETHOD AddIndex( // create a sorting index for column if possible
1971 nsIMdbEnv* ev, // context
1972 mdb_column inColumn, // the column to sort by index
1973 nsIMdbThumb** acqThumb) =
1974 0; // acquire thumb for incremental index building
1975 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
1976 // then the index addition will be finished.
1977
1978 NS_IMETHOD CutIndex( // stop supporting a specific column index
1979 nsIMdbEnv* ev, // context
1980 mdb_column inColumn, // the column with index to be removed
1981 nsIMdbThumb** acqThumb) =
1982 0; // acquire thumb for incremental index destroy
1983 // Call nsIMdbThumb::DoMore() until done, or until the thumb is broken, and
1984 // then the index removal will be finished.
1985
1986 NS_IMETHOD HasIndex( // query for current presence of a column index
1987 nsIMdbEnv* ev, // context
1988 mdb_column inColumn, // the column to investigate
1989 mdb_bool* outHasIndex) = 0; // whether column has index for this column
1990
1991 NS_IMETHOD EnableIndexOnSort( // create an index for col on first sort
1992 nsIMdbEnv* ev, // context
1993 mdb_column inColumn) = 0; // the column to index if ever sorted
1994
1995 NS_IMETHOD QueryIndexOnSort( // check whether index on sort is enabled
1996 nsIMdbEnv* ev, // context
1997 mdb_column inColumn, // the column to investigate
1998 mdb_bool* outIndexOnSort) =
1999 0; // whether column has index-on-sort enabled
2000
2001 NS_IMETHOD DisableIndexOnSort( // prevent future index creation on sort
2002 nsIMdbEnv* ev, // context
2003 mdb_column inColumn) = 0; // the column to index if ever sorted
2004 // } ----- end index methods -----
2005
2006 // } ===== end nsIMdbTable methods =====
2007 };
2008
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbTable,NS_IMDBTABLE_IID)2009 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbTable, NS_IMDBTABLE_IID)
2010
2011 /*| nsIMdbSorting: a view of a table in some particular sort order. This
2012 **| row order closely resembles a readonly array of rows with the same row
2013 **| membership as the underlying table, but in a different order than the
2014 **| table's explicit row order. But the sorting's row membership changes
2015 **| whenever the table's membership changes (without any notification, so
2016 **| keep this in mind when modifying the table).
2017 **|
2018 **|| table: every sorting is associated with a particular table. You
2019 **| cannot change which table is used by a sorting (just ask some new
2020 **| table for a suitable sorting instance instead).
2021 **|
2022 **|| compare: the ordering method used by a sorting, wrapped up in a
2023 **| abstract plug-in interface. When this was never installed by an
2024 **| explicit call to SetNewCompare(), a compare object is still returned,
2025 **| and it might match the compare instance returned by the factory method
2026 **| nsIMdbFactory::MakeCompare(), which represents a default sort order
2027 **| (which we fervently hope is consistently ASCII byte ordering).
2028 **|
2029 **|| cursor: in case callers are more comfortable with a cursor style
2030 **| of accessing row members, each sorting will happily return a cursor
2031 **| instance with behavior very similar to a cursor returned from a call
2032 **| to nsIMdbTable::GetTableRowCursor(), but with different row order.
2033 **| A cursor should show exactly the same information as the pos methods.
2034 **|
2035 **|| pos: the PosToOid() and PosToRow() methods are just like the table
2036 **| methods of the same name, except they show rows in the sort order of
2037 **| the sorting, rather than that of the table. These methods are like
2038 **| readonly array position accessor's, or like a C++ operator[].
2039 |*/
2040 class nsIMdbSorting : public nsIMdbObject { // sorting of some table
2041 public:
2042 // { ===== begin nsIMdbSorting methods =====
2043
2044 // { ----- begin attribute methods -----
2045 // sorting: note all rows are assumed sorted by row ID as a secondary
2046 // sort following the primary column sort, when table rows are sorted.
2047
2048 NS_IMETHOD GetTable(nsIMdbEnv* ev, nsIMdbTable** acqTable) = 0;
2049 NS_IMETHOD GetSortColumn( // query which col is currently sorted
2050 nsIMdbEnv* ev, // context
2051 mdb_column* outColumn) = 0; // col the table uses for sorting (or zero)
2052
2053 // } ----- end attribute methods -----
2054
2055 // { ----- begin cursor methods -----
2056 NS_IMETHOD GetSortingRowCursor( // make a cursor, starting at inRowPos
2057 nsIMdbEnv* ev, // context
2058 mdb_pos inRowPos, // zero-based ordinal position of row in table
2059 nsIMdbTableRowCursor** acqCursor) = 0; // acquire new cursor instance
2060 // A cursor interface turning same info as PosToOid() or PosToRow().
2061 // } ----- end row position methods -----
2062
2063 // { ----- begin row position methods -----
2064 NS_IMETHOD PosToOid( // get row member for a table position
2065 nsIMdbEnv* ev, // context
2066 mdb_pos inRowPos, // zero-based ordinal position of row in table
2067 mdbOid* outOid) = 0; // row oid at the specified position
2068
2069 NS_IMETHOD PosToRow( // test for the table position of a row member
2070 nsIMdbEnv* ev, // context
2071 mdb_pos inRowPos, // zero-based ordinal position of row in table
2072 nsIMdbRow** acqRow) = 0; // acquire row at table position inRowPos
2073 // } ----- end row position methods -----
2074
2075 // } ===== end nsIMdbSorting methods =====
2076 };
2077
2078 /*| nsIMdbTableRowCursor: cursor class for iterating table rows
2079 **|
2080 **|| table: the cursor is associated with a specific table, which can be
2081 **| set to a different table (which resets the position to -1 so the
2082 **| next row acquired is the first in the table.
2083 **|
2084 **|| NextRowId: the rows in the table can be iterated by identity alone,
2085 **| without actually reading the cells of any row with this method.
2086 **|
2087 **|| NextRowCells: read the next row in the table, but only read cells
2088 **| from the table which are already present in the row (so no new cells
2089 **| are added to the row, even if they are present in the table). All the
2090 **| cells will have content specified, even it is the empty string. No
2091 **| columns will be removed, even if missing from the row (because missing
2092 **| and empty are semantically equivalent).
2093 **|
2094 **|| NextRowAllCells: read the next row in the table, and access all the
2095 **| cells for this row in the table, adding any missing columns to the row
2096 **| as needed until all cells are represented. All the
2097 **| cells will have content specified, even it is the empty string. No
2098 **| columns will be removed, even if missing from the row (because missing
2099 **| and empty are semantically equivalent).
2100 **|
2101 |*/
2102
2103 #define NS_IMDBTABLEROWCURSOR_IID_STR = "4f325dad-0385-4b62-a992-c914ab93587e"
2104
2105 #define NS_IMDBTABLEROWCURSOR_IID \
2106 { \
2107 0x4f325dad, 0x0385, 0x4b62, { \
2108 0xa9, 0x92, 0xc9, 0x14, 0xab, 0x93, 0x58, 0x7e \
2109 } \
2110 }
2111
2112 class nsIMdbTableRowCursor : public nsISupports { // table row iterator
2113 public:
2114 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBTABLEROWCURSOR_IID)
2115
2116 // { ===== begin nsIMdbTableRowCursor methods =====
2117
2118 // { ----- begin attribute methods -----
2119 // NS_IMETHOD SetTable(nsIMdbEnv* ev, nsIMdbTable* ioTable) = 0; // sets pos
2120 // to -1 Method SetTable() cut and made obsolete in keeping with new sorting
2121 // methods.
2122
2123 NS_IMETHOD GetTable(nsIMdbEnv* ev, nsIMdbTable** acqTable) = 0;
2124 // } ----- end attribute methods -----
2125
2126 // { ----- begin duplicate row removal methods -----
2127 NS_IMETHOD CanHaveDupRowMembers(nsIMdbEnv* ev, // cursor might hold dups?
2128 mdb_bool* outCanHaveDups) = 0;
2129
2130 NS_IMETHOD MakeUniqueCursor( // clone cursor, removing duplicate rows
2131 nsIMdbEnv* ev, // context
2132 nsIMdbTableRowCursor** acqCursor) = 0; // acquire clone with no dups
2133 // Note that MakeUniqueCursor() is never necessary for a cursor which was
2134 // created by table method nsIMdbTable::GetTableRowCursor(), because a table
2135 // never contains the same row as a member more than once. However, a cursor
2136 // created by table method nsIMdbTable::FindRowMatches() might contain the
2137 // same row more than once, because the same row can generate a hit by more
2138 // than one column with a matching string prefix. Note this method can
2139 // return the very same cursor instance with just an incremented refcount,
2140 // when the original cursor could not contain any duplicate rows (calling
2141 // CanHaveDupRowMembers() shows this case on a false return). Otherwise
2142 // this method returns a different cursor instance. Callers should not use
2143 // this MakeUniqueCursor() method lightly, because it tends to defeat the
2144 // purpose of lazy programming techniques, since it can force creation of
2145 // an explicit row collection in a new cursor's representation, in order to
2146 // inspect the row membership and remove any duplicates; this can have big
2147 // impact if a collection holds tens of thousands of rows or more, when
2148 // the original cursor with dups simply referenced rows indirectly by row
2149 // position ranges, without using an explicit row set representation.
2150 // Callers are encouraged to use nsIMdbCursor::GetCount() to determine
2151 // whether the row collection is very large (tens of thousands), and to
2152 // delay calling MakeUniqueCursor() when possible, until a user interface
2153 // element actually demands the creation of an explicit set representation.
2154 // } ----- end duplicate row removal methods -----
2155
2156 // { ----- begin oid iteration methods -----
2157 NS_IMETHOD NextRowOid( // get row id of next row in the table
2158 nsIMdbEnv* ev, // context
2159 mdbOid* outOid, // out row oid
2160 mdb_pos* outRowPos) = 0; // zero-based position of the row in table
2161 // } ----- end oid iteration methods -----
2162
2163 // { ----- begin row iteration methods -----
2164 NS_IMETHOD NextRow( // get row cells from table for cells already in row
2165 nsIMdbEnv* ev, // context
2166 nsIMdbRow** acqRow, // acquire next row in table
2167 mdb_pos* outRowPos) = 0; // zero-based position of the row in table
2168
2169 NS_IMETHOD PrevRowOid( // get row id of previous row in the table
2170 nsIMdbEnv* ev, // context
2171 mdbOid* outOid, // out row oid
2172 mdb_pos* outRowPos) = 0; // zero-based position of the row in table
2173 // } ----- end oid iteration methods -----
2174
2175 // { ----- begin row iteration methods -----
2176 NS_IMETHOD PrevRow( // get row cells from table for cells already in row
2177 nsIMdbEnv* ev, // context
2178 nsIMdbRow** acqRow, // acquire previous row in table
2179 mdb_pos* outRowPos) = 0; // zero-based position of the row in table
2180
2181 // } ----- end row iteration methods -----
2182
2183 // { ----- begin copy iteration methods -----
2184 // NS_IMETHOD NextRowCopy( // put row cells into sink only when already in
2185 // sink
2186 // nsIMdbEnv* ev, // context
2187 // nsIMdbRow* ioSinkRow, // sink for row cells read from next row
2188 // mdbOid* outOid, // out row oid
2189 // mdb_pos* outRowPos) = 0; // zero-based position of the row in table
2190 //
2191 // NS_IMETHOD NextRowCopyAll( // put all row cells into sink, adding to sink
2192 // nsIMdbEnv* ev, // context
2193 // nsIMdbRow* ioSinkRow, // sink for row cells read from next row
2194 // mdbOid* outOid, // out row oid
2195 // mdb_pos* outRowPos) = 0; // zero-based position of the row in table
2196 // } ----- end copy iteration methods -----
2197
2198 // } ===== end nsIMdbTableRowCursor methods =====
2199 };
2200
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbTableRowCursor,NS_IMDBTABLEROWCURSOR_IID)2201 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbTableRowCursor, NS_IMDBTABLEROWCURSOR_IID)
2202
2203 /*| nsIMdbRow: a collection of cells
2204 **|
2205 |*/
2206
2207 #define NS_IMDBROW_IID_STR "271e8d6e-183a-40e3-9f18-36913b4c7853"
2208
2209 #define NS_IMDBROW_IID \
2210 { \
2211 0x271e8d6e, 0x183a, 0x40e3, { \
2212 0x9f, 0x18, 0x36, 0x91, 0x3b, 0x4c, 0x78, 0x53 \
2213 } \
2214 }
2215
2216 class nsIMdbRow : public nsIMdbCollection { // cell tuple
2217 public:
2218 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBROW_IID)
2219 // { ===== begin nsIMdbRow methods =====
2220
2221 // { ----- begin cursor methods -----
2222 NS_IMETHOD GetRowCellCursor( // make a cursor starting iteration at inCellPos
2223 nsIMdbEnv* ev, // context
2224 mdb_pos inCellPos, // zero-based ordinal position of cell in row
2225 nsIMdbRowCellCursor** acqCursor) = 0; // acquire new cursor instance
2226 // } ----- end cursor methods -----
2227
2228 // { ----- begin column methods -----
2229 NS_IMETHOD AddColumn( // make sure a particular column is inside row
2230 nsIMdbEnv* ev, // context
2231 mdb_column inColumn, // column to add
2232 const mdbYarn* inYarn) = 0; // cell value to install
2233
2234 NS_IMETHOD CutColumn( // make sure a column is absent from the row
2235 nsIMdbEnv* ev, // context
2236 mdb_column inColumn) = 0; // column to ensure absent from row
2237
2238 NS_IMETHOD CutAllColumns( // remove all columns from the row
2239 nsIMdbEnv* ev) = 0; // context
2240 // } ----- end column methods -----
2241
2242 // { ----- begin cell methods -----
2243 NS_IMETHOD NewCell( // get cell for specified column, or add new one
2244 nsIMdbEnv* ev, // context
2245 mdb_column inColumn, // column to add
2246 nsIMdbCell** acqCell) = 0; // cell column and value
2247
2248 NS_IMETHOD AddCell( // copy a cell from another row to this row
2249 nsIMdbEnv* ev, // context
2250 const nsIMdbCell* inCell) = 0; // cell column and value
2251
2252 NS_IMETHOD GetCell( // find a cell in this row
2253 nsIMdbEnv* ev, // context
2254 mdb_column inColumn, // column to find
2255 nsIMdbCell** acqCell) = 0; // cell for specified column, or null
2256
2257 NS_IMETHOD EmptyAllCells( // make all cells in row empty of content
2258 nsIMdbEnv* ev) = 0; // context
2259 // } ----- end cell methods -----
2260
2261 // { ----- begin row methods -----
2262 NS_IMETHOD AddRow( // add all cells in another row to this one
2263 nsIMdbEnv* ev, // context
2264 nsIMdbRow* ioSourceRow) = 0; // row to union with
2265
2266 NS_IMETHOD SetRow( // make exact duplicate of another row
2267 nsIMdbEnv* ev, // context
2268 nsIMdbRow* ioSourceRow) = 0; // row to duplicate
2269 // } ----- end row methods -----
2270
2271 // { ----- begin blob methods -----
2272 NS_IMETHOD SetCellYarn(nsIMdbEnv* ev, // synonym for AddColumn()
2273 mdb_column inColumn, // column to write
2274 const mdbYarn* inYarn) = 0; // reads from yarn slots
2275 // make this text object contain content from the yarn's buffer
2276
2277 NS_IMETHOD GetCellYarn(nsIMdbEnv* ev,
2278 mdb_column inColumn, // column to read
2279 mdbYarn* outYarn) = 0; // writes some yarn slots
2280 // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
2281
2282 NS_IMETHOD AliasCellYarn(nsIMdbEnv* ev,
2283 mdb_column inColumn, // column to alias
2284 mdbYarn* outYarn) = 0; // writes ALL yarn slots
2285
2286 NS_IMETHOD NextCellYarn(nsIMdbEnv* ev, // iterative version of GetCellYarn()
2287 mdb_column* ioColumn, // next column to read
2288 mdbYarn* outYarn) = 0; // writes some yarn slots
2289 // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
2290 //
2291 // The ioColumn argument is an inout parameter which initially contains the
2292 // last column accessed and returns the next column corresponding to the
2293 // content read into the yarn. Callers should start with a zero column
2294 // value to say 'no previous column', which causes the first column to be
2295 // read. Then the value returned in ioColumn is perfect for the next call
2296 // to NextCellYarn(), since it will then be the previous column accessed.
2297 // Callers need only examine the column token returned to see which cell
2298 // in the row is being read into the yarn. When no more columns remain,
2299 // and the iteration has ended, ioColumn will return a zero token again.
2300 // So iterating over cells starts and ends with a zero column token.
2301
2302 NS_IMETHOD SeekCellYarn( // resembles nsIMdbRowCellCursor::SeekCell()
2303 nsIMdbEnv* ev, // context
2304 mdb_pos inPos, // position of cell in row sequence
2305 mdb_column* outColumn, // column for this particular cell
2306 mdbYarn* outYarn) = 0; // writes some yarn slots
2307 // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
2308 // Callers can pass nil for outYarn to indicate no interest in content, so
2309 // only the outColumn value is returned. NOTE to subclasses: you must be
2310 // able to ignore outYarn when the pointer is nil; please do not crash.
2311
2312 // } ----- end blob methods -----
2313
2314 // } ===== end nsIMdbRow methods =====
2315 };
2316
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbRow,NS_IMDBROW_IID)2317 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbRow, NS_IMDBROW_IID)
2318
2319 /*| nsIMdbRowCellCursor: cursor class for iterating row cells
2320 **|
2321 **|| row: the cursor is associated with a specific row, which can be
2322 **| set to a different row (which resets the position to -1 so the
2323 **| next cell acquired is the first in the row.
2324 **|
2325 **|| NextCell: get the next cell in the row and return its position and
2326 **| a new instance of a nsIMdbCell to represent this next cell.
2327 |*/
2328
2329 #define NS_IMDBROWCELLCURSOR_IID_STR "b33371a7-5d63-4d10-85a8-e44dffe75c28"
2330
2331 #define NS_IMDBROWCELLCURSOR_IID \
2332 { \
2333 0x271e8d6e, 0x5d63, 0x4d10, { \
2334 0x85, 0xa8, 0xe4, 0x4d, 0xff, 0xe7, 0x5c, 0x28 \
2335 } \
2336 }
2337
2338 class nsIMdbRowCellCursor : public nsISupports { // cell collection iterator
2339 public:
2340 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBROWCELLCURSOR_IID)
2341 // { ===== begin nsIMdbRowCellCursor methods =====
2342
2343 // { ----- begin attribute methods -----
2344 NS_IMETHOD SetRow(nsIMdbEnv* ev, nsIMdbRow* ioRow) = 0; // sets pos to -1
2345 NS_IMETHOD GetRow(nsIMdbEnv* ev, nsIMdbRow** acqRow) = 0;
2346 // } ----- end attribute methods -----
2347
2348 // { ----- begin cell seeking methods -----
2349 NS_IMETHOD SeekCell(nsIMdbEnv* ev, // context
2350 mdb_pos inPos, // position of cell in row sequence
2351 mdb_column* outColumn, // column for this particular cell
2352 nsIMdbCell** acqCell) = 0; // the cell at inPos
2353 // } ----- end cell seeking methods -----
2354
2355 // { ----- begin cell iteration methods -----
2356 NS_IMETHOD NextCell( // get next cell in the row
2357 nsIMdbEnv* ev, // context
2358 nsIMdbCell** acqCell, // changes to the next cell in the iteration
2359 mdb_column* outColumn, // column for this particular cell
2360 mdb_pos* outPos) = 0; // position of cell in row sequence
2361
2362 NS_IMETHOD PickNextCell( // get next cell in row within filter set
2363 nsIMdbEnv* ev, // context
2364 nsIMdbCell* ioCell, // changes to the next cell in the iteration
2365 const mdbColumnSet* inFilterSet, // col set of actual caller interest
2366 mdb_column* outColumn, // column for this particular cell
2367 mdb_pos* outPos) = 0; // position of cell in row sequence
2368
2369 // Note that inFilterSet should not have too many (many more than 10?)
2370 // cols, since this might imply a potential excessive consumption of time
2371 // over many cursor calls when looking for column and filter intersection.
2372 // } ----- end cell iteration methods -----
2373
2374 // } ===== end nsIMdbRowCellCursor methods =====
2375 };
2376
NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbRowCellCursor,NS_IMDBROWCELLCURSOR_IID)2377 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbRowCellCursor, NS_IMDBROWCELLCURSOR_IID)
2378
2379 /*| nsIMdbBlob: a base class for objects composed mainly of byte sequence state.
2380 **| (This provides a base class for nsIMdbCell, so that cells themselves can
2381 **| be used to set state in another cell, without extracting a buffer.)
2382 |*/
2383 class nsIMdbBlob : public nsISupports { // a string with associated charset
2384 public:
2385 // { ===== begin nsIMdbBlob methods =====
2386
2387 // { ----- begin attribute methods -----
2388 NS_IMETHOD SetBlob(nsIMdbEnv* ev,
2389 nsIMdbBlob* ioBlob) = 0; // reads inBlob slots
2390 // when inBlob is in the same suite, this might be fastest cell-to-cell
2391
2392 NS_IMETHOD ClearBlob( // make empty (so content has zero length)
2393 nsIMdbEnv* ev) = 0;
2394 // clearing a yarn is like SetYarn() with empty yarn instance content
2395
2396 NS_IMETHOD GetBlobFill(nsIMdbEnv* ev,
2397 mdb_fill* outFill) = 0; // size of blob
2398 // Same value that would be put into mYarn_Fill, if one called GetYarn()
2399 // with a yarn instance that had mYarn_Buf==nil and mYarn_Size==0.
2400
2401 NS_IMETHOD SetYarn(nsIMdbEnv* ev,
2402 const mdbYarn* inYarn) = 0; // reads from yarn slots
2403 // make this text object contain content from the yarn's buffer
2404
2405 NS_IMETHOD GetYarn(nsIMdbEnv* ev,
2406 mdbYarn* outYarn) = 0; // writes some yarn slots
2407 // copy content into the yarn buffer, and update mYarn_Fill and mYarn_Form
2408
2409 NS_IMETHOD AliasYarn(nsIMdbEnv* ev,
2410 mdbYarn* outYarn) = 0; // writes ALL yarn slots
2411 // AliasYarn() reveals sensitive internal text buffer state to the caller
2412 // by setting mYarn_Buf to point into the guts of this text implementation.
2413 //
2414 // The caller must take great care to avoid writing on this space, and to
2415 // avoid calling any method that would cause the state of this text object
2416 // to change (say by directly or indirectly setting the text to hold more
2417 // content that might grow the size of the buffer and free the old buffer).
2418 // In particular, callers should scrupulously avoid making calls into the
2419 // mdb interface to write any content while using the buffer pointer found
2420 // in the returned yarn instance. Best safe usage involves copying content
2421 // into some other kind of external content representation beyond mdb.
2422 //
2423 // (The original design of this method a week earlier included the concept
2424 // of very fast and efficient cooperative locking via a pointer to some lock
2425 // member slot. But let's ignore that complexity in the current design.)
2426 //
2427 // AliasYarn() is specifically intended as the first step in transferring
2428 // content from nsIMdbBlob to a nsString representation, without forcing extra
2429 // allocations and/or memory copies. (A standard nsIMdbBlob_AsString() utility
2430 // will use AliasYarn() as the first step in setting a nsString instance.)
2431 //
2432 // This is an alternative to the GetYarn() method, which has copy semantics
2433 // only; AliasYarn() relaxes a robust safety principle only for performance
2434 // reasons, to accommodate the need for callers to transform text content to
2435 // some other canonical representation that would necessitate an additional
2436 // copy and transformation when such is incompatible with the mdbYarn format.
2437 //
2438 // The implementation of AliasYarn() should have extremely little overhead
2439 // besides the virtual dispatch to the method implementation, and the code
2440 // necessary to populate all the mdbYarn member slots with internal buffer
2441 // address and metainformation that describes the buffer content. Note that
2442 // mYarn_Grow must always be set to nil to indicate no resizing is allowed.
2443
2444 // } ----- end attribute methods -----
2445
2446 // } ===== end nsIMdbBlob methods =====
2447 };
2448
2449 /*| nsIMdbCell: the text in a single column of a row. The base nsIMdbBlob
2450 **| class provides all the interface related to accessing cell text.
2451 **|
2452 **|| column: each cell in a row appears in a specific column, where this
2453 **| column is identified by the an integer mdb_scope value (generated by
2454 **| the StringToScopeToken() method in the containing nsIMdbPort instance).
2455 **| Because a row cannot have more than one cell with the same column,
2456 **| something must give if one calls SetColumn() with an existing column
2457 **| in the same row. When this happens, the other cell is replaced with
2458 **| this cell (and the old cell is closed if it has outstanding refs).
2459 **|
2460 **|| row: every cell instance is a part of some row, and every cell knows
2461 **| which row is the parent row. (Note this should be represented by a
2462 **| weak backpointer, so that outstanding cell references cannot keep a
2463 **| row open that should be closed. Otherwise we'd have ref graph cycles.)
2464 **|
2465 **|| text: a cell can either be text, or it can have a child row or table,
2466 **| but not both at once. If text is read from a cell with a child, the text
2467 **| content should be empty (for AliasYarn()) or a description of the type
2468 **| of child (perhaps "mdb:cell:child:row" or "mdb:cell:child:table").
2469 **|
2470 **|| child: a cell might reference another row or a table, rather than text.
2471 **| The interface for putting and getting children rows and tables was first
2472 **| defined in the nsIMdbTable interface, but then this was moved to this cell
2473 **| interface as more natural.
2474 |*/
2475
2476 #define NS_IMDBCELL_IID \
2477 { \
2478 0xa3b62f71, 0xa181, 0x4a91, { \
2479 0xb6, 0x6b, 0x27, 0x10, 0x9b, 0x88, 0x98, 0x35 \
2480 } \
2481 }
2482
2483 #define NS_IMDBCELL_IID_STR = "a3b62f71-a181-4a91-b66b-27109b889835"
2484
2485 class nsIMdbCell
2486 : public nsIMdbBlob { // text attribute in row with column scope
2487 public:
2488 NS_DECLARE_STATIC_IID_ACCESSOR(NS_IMDBTABLEROWCURSOR_IID)
2489 // { ===== begin nsIMdbCell methods =====
2490
2491 // { ----- begin attribute methods -----
2492 NS_IMETHOD SetColumn(nsIMdbEnv* ev, mdb_column inColumn) = 0;
2493 NS_IMETHOD GetColumn(nsIMdbEnv* ev, mdb_column* outColumn) = 0;
2494
2495 NS_IMETHOD GetCellInfo( // all cell metainfo except actual content
2496 nsIMdbEnv* ev,
2497 mdb_column* outColumn, // the column in the containing row
2498 mdb_fill* outBlobFill, // the size of text content in bytes
2499 mdbOid* outChildOid, // oid of possible row or table child
2500 mdb_bool* outIsRowChild) = 0; // nonzero if child, and a row child
2501
2502 // Checking all cell metainfo is a good way to avoid forcing a large cell
2503 // in to memory when you don't actually want to use the content.
2504
2505 NS_IMETHOD GetRow(nsIMdbEnv* ev, // parent row for this cell
2506 nsIMdbRow** acqRow) = 0;
2507 NS_IMETHOD GetPort(nsIMdbEnv* ev, // port containing cell
2508 nsIMdbPort** acqPort) = 0;
2509 // } ----- end attribute methods -----
2510
2511 // { ----- begin children methods -----
2512 NS_IMETHOD HasAnyChild( // does cell have a child instead of text?
2513 nsIMdbEnv* ev,
2514 mdbOid* outOid, // out id of row or table (or unbound if no child)
2515 mdb_bool* outIsRow) =
2516 0; // nonzero if child is a row (rather than a table)
2517
2518 NS_IMETHOD GetAnyChild( // access table of specific attribute
2519 nsIMdbEnv* ev, // context
2520 nsIMdbRow** acqRow, // child row (or null)
2521 nsIMdbTable** acqTable) = 0; // child table (or null)
2522
2523 NS_IMETHOD SetChildRow( // access table of specific attribute
2524 nsIMdbEnv* ev, // context
2525 nsIMdbRow* ioRow) = 0; // inRow must be bound inside this same db port
2526
2527 NS_IMETHOD GetChildRow( // access row of specific attribute
2528 nsIMdbEnv* ev, // context
2529 nsIMdbRow** acqRow) = 0; // acquire child row (or nil if no child)
2530
2531 NS_IMETHOD SetChildTable( // access table of specific attribute
2532 nsIMdbEnv* ev, // context
2533 nsIMdbTable* inTable) =
2534 0; // table must be bound inside this same db port
2535
2536 NS_IMETHOD GetChildTable( // access table of specific attribute
2537 nsIMdbEnv* ev, // context
2538 nsIMdbTable** acqTable) = 0; // acquire child table (or nil if no child)
2539 // } ----- end children methods -----
2540
2541 // } ===== end nsIMdbCell methods =====
2542 };
2543
2544 NS_DEFINE_STATIC_IID_ACCESSOR(nsIMdbCell, NS_IMDBTABLEROWCURSOR_IID)
2545
2546 // } %%%%% end C++ abstract class interfaces %%%%%
2547
2548 // 456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
2549
2550 #endif /* _MDB_ */
2551