libfossil
fossil.hpp
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 #if !defined(NET_FOSSIL_SCM_LIBFOSSIL_HPP_INCLUDED)
4 #define NET_FOSSIL_SCM_LIBFOSSIL_HPP_INCLUDED
5 /**
6  License as yet undecided!
7 */
8 
9 /*
10  fossil.h MUST be included first so we can set some portability
11  flags and config-dependent typedefs!
12 */
13 #include "fossil-scm/fossil.h"
14 #include <stdexcept>
15 #include <string>
16 #include <sstream>
17 #include <stdarg.h>
18 #if 0
19 #include <cstdint> /* FIXME: use this if available (C++11) */
20 #endif
21 
22 /**
23  fsl is the primary namespace of the libfossil C++ API. The C++ API
24  wraps much of the C-level function and simplifies its usage
25  somewhat by using exceptions extensively for error reporting.
26 
27  A brief note about exceptions: functions and methods with do not
28  throw are marked as throw(). Any others may very well throw. Though
29  in practice the library APIs "simply do not fail" if used properly,
30  there are gazillions of _potential_ error cases which the
31  underlying C library _may_ propagate up to the client (in this case
32  the C++ API), and this C++ wrapper treats almost every C-level
33  error as an Exception, with only a few exceptions to simplify usage
34  (e.g. cleanup-related functions never throw because they are
35  generally used in destructors, and dtors are conventionally
36  prohibited from throwing). The base exception type used by the
37  library is fsl::Exception, which derives from std::exception per
38  long-standing convention.
39 
40  While the API is not STL-centric, it does provide some basic
41  STL-relatated support, e.g. the fsl::FslOutputFStream and
42  fsl::BufferOStream classes.
43 
44 */
45 namespace fsl {
46 
47  /**
48  The base exception type used by the API. It follows the libfossil
49  convention of returning errors as (if possible) an error code
50  from the fsl_rc_t enum and a descriptive string (which generally
51  defaults to the string-form of the FSL_RC_xxx constant value (see
52  fsl_rc_cstr()).
53  */
54  class Exception : public std::exception {
55  public:
56  /**
57  Cleans up any error string memory.
58  */
59  virtual ~Exception() throw();
60 
61  /** Copies the error message state from other. */
62  Exception(Exception const &other) throw();
63 
64  /** Copies the error message state from other. */
65  Exception & operator=(Exception const &other) throw();
66 
67  /**
68  Sets the error state from the given arguments. If msg.empty()
69  then fsl_rc_cstr(code) is used as a message string.
70  */
71  Exception(int code, std::string const & msg) throw();
72 
73  /**
74  Equivalent to Exception(code, fsl_rc_cstr(code)).
75  */
76  explicit Exception(int code) throw();
77 
78  /**
79  A default-constructed exception with no message string
80  and an error code of FSL_RC_ERROR. Intended to be used
81  in conjunction with the (fsl_error*) implicit conversion
82  and C APIs taking a fsl_error pointer.
83  */
84  Exception() throw();
85 
86  /**
87  Moves err's contents into this object, effectively upgrading it
88  to something we can throw. It is safe to pass a local
89  stack-allocated fsl_error object provided it is properly
90  initialized (via copy-construction from fsl_error_empty
91  resp. fsl_error_empty_m) because this function takes its memory
92  from it.
93  */
94  explicit Exception( fsl_error & err ) throw();
95 
96  /**
97  Copies err's contents into this object, effectively upgrading
98  it to something we can throw. Is generally intended to be
99  passed the return value from, e.g. fsl_cx_err_get_e().
100  */
101  explicit Exception( fsl_error const * err ) throw();
102 
103  /**
104  Sets the error state from the given code (generally assumed to
105  be a fsl_rc_t value!) and a formatted string, supporting the
106  same formatting options as fsl_appendf() and friends.
107 
108  As a special case, if code==FSL_RC_OOM then the message
109  string is ignored to avoid allocating memory for the
110  error message.
111 
112  When passing on strings from external sources, it is safest to
113  pass "%s" as the format string and the foreign string as the
114  first variadic argument. That ensures that percent signs in
115  the foreign input do not get processed as format specifiers
116  (which expect further arguments in the variadic list, which
117  will likely lead to undefined behaviour).
118  */
119  Exception(int code, char const * fmt, ...) throw();
120 
121  /**
122  Equivalent to Exception(code,fmt,...) except that it
123  takes a va_list.
124  */
125  Exception(int code, char const * fmt, va_list) throw();
126 
127  /**
128  Returns the message string provided to the ctor.
129  It's not called message() because this interface
130  is inherited from std::exception.
131  */
132  virtual char const * what() const throw();
133 
134  /**
135  Alias (for API consistency's sake) for what().
136  */
137  char const * messsage() const throw();
138 
139  /**
140  Returns the code passed to the constructor.
141  */
142  int code() const throw();
143 
144  /**
145  Equivalent to fsl_rc_cstr(this->code()).
146  */
147  char const * codeString() const throw();
148 
149  /**
150  Implicit conversion to simplify some integration with
151  the C APIs.
152  */
153  operator fsl_error * () throw();
154 
155  /**
156  Const-correct overload.
157  */
158  operator fsl_error const * () const throw();
159 
160  private:
161  fsl_error err;
162  /** Internal code consolidator. */
163  void error(int code, char const * fmt, va_list vargs) throw();
164  };
165 
166  /**
167  Out-of-memory exception.
168  */
169  class OOMException : public Exception{
170  public:
171  /**
172  Sets the code FSL_RC_OOM and uses no error string (to avoid
173  allocating more memory).
174  */
175  OOMException() throw();
176  };
177 
178  /**
179  A very thin varnish over ::fsl_buffer, the primary advantage
180  being that it frees its memory when it destructs, so it's easier
181  to keep exception-safe than a raw fsl_buffer.
182 
183  It implements an implicit conversion to (fsl_buffer*), making it
184  trivial to use with the C-level fsl_buffer APIs.
185 
186  Note that the underlying buffer APIs guaranty that they
187  NUL-terminates the buffer when data is appended to it, so it can
188  easily be used to create dynamic strings (which is in fact one of
189  its primary uses). As for strlen() and conventional string
190  classes (e.g. std::string), the automatically-added NUL byte is
191  never counted as part of the "effective length" of the buffer
192  (Buffer::used() resp. fsl_buffer::used).
193 
194  Example usage:
195 
196  @code
197  Buffer b;
198  b.appendf(b, "hi, %s!", "world"); // throws on buffer (re)allocation error
199  std::cout << b << '\n';
200  @endcode
201 
202  */
203  class Buffer {
204  private:
205  fsl_buffer buf;
206  public:
207  /**
208  Initializes the buffer. If startingSize is greater than
209  zero it reserves that amount of memory, throwing an
210  OOMException if that fails.
211  */
212  explicit Buffer(fsl_size_t startingSize);
213  /**
214  Initializes an empty buffer.
215  */
216  Buffer();
217  /**
218  Frees all memory owned by the buffer.
219  */
220  ~Buffer() throw();
221 
222  /**
223  Replaces the current buffer contents with a copy of those from
224  the given buffer. It re-uses the existing buffer memory if
225  enough is available, and will shrink itself to fit if re-using
226  a buffer would waste "too much" memory.
227  */
228  Buffer & operator=(Buffer const & other);
229 
230  /**
231  Copies the contents of the other buffer.
232  */
233  Buffer(Buffer const & other);
234 
235  /**
236  Implicit conversion to (fsl_buffer *) to simplify usage with
237  the C API.
238 
239  NEVER EVER use/rely upon this conversion in the following
240  context:
241 
242  - As a fsl_appendf() (or similar) argument when using the %b/%B
243  (fsl_buffer-specific) format specifiers. Use handle()
244  instead or the wrong conversion will be used because
245  compile-time doesn't know this conversion should be used at
246  that point (leading to undefined results).
247  */
248  operator fsl_buffer * () throw();
249 
250  /**
251  Const-correct overload.
252  */
253  operator fsl_buffer const * () const throw();
254 
255  /**
256  Returns the underlying fsl_buffer this object proxies.
257  See operator fsl_buffer *().
258  */
259  fsl_buffer * handle() throw();
260 
261  /**
262  Const-correct overload.
263  */
264  fsl_buffer const * handle() const throw();
265 
266  /**
267  Returns true if 0==used().
268  */
269  bool empty() const throw();
270 
271  /**
272  Returns the "used" number of bytes in the buffer.
273  */
274  fsl_size_t used() const throw();
275 
276  /**
277  Returns the current capacity of the buffer.
278  */
279  fsl_size_t capacity() const throw();
280 
281  /**
282  Returns a pointer to the current buffer, which points to
283  used() bytes of memory. Returns NULL for an empty()
284  buffer. The returned pointer may be invalidated on any changes
285  to the buffer.
286  */
287  unsigned char * mem() throw();
288 
289  /**
290  Const-correct overload.
291  */
292  unsigned char const * mem() const throw();
293 
294  /**
295  Equivalent to fsl_buffer_clear(*this).
296  */
297  Buffer & clear() throw();
298 
299  /**
300  Equivalent to fsl_buffer_reset(*this).
301  */
302  Buffer & reset() throw();
303 
304  /**
305  Equivalent to fsl_buffer_reserve(*this, n), but throws on error
306  and returns this object on success.
307  */
309 
310  /**
311  Equivalent to fsl_buffer_resize(*this, n), but throws on error
312  and returns this object on success.
313  */
314  Buffer & resize(fsl_size_t n);
315 
316  /**
317  STL-style iterator for the buffer's memory.
318  */
319  typedef unsigned char * iterator;
320 
321  /**
322  STL-style const iterator for the buffer's memory.
323  */
324  typedef unsigned char const * const_iterator;
325 
326  /**
327  Returns the starting memory position iterator,
328  or NULL if empty(). It may be invalidated by
329  any changes to the buffer.
330  */
331  iterator begin() throw();
332 
333  /**
334  Returns the one-after-the-end of the memory position iterator
335  (the "used" space, not necessarily the capacity), or NULL if
336  empty(). It may be invalidated by any changes to the buffer.
337  */
338  iterator end() throw();
339 
340  /**
341  Const-correct overload.
342  */
343  const_iterator begin() const throw();
344 
345  /**
346  Const-correct overload.
347  */
348  const_iterator end() const throw();
349 
350  /**
351  Basically equivalent to fsl_buffer_appendf(*this,...)
352  except that it throws if that function fails.
353  */
354  Buffer & appendf(char const * fmt, ...);
355 
356  /**
357  Returns a pointer to the buffer member. It may be
358  invalidated by any changes to the buffer. Returns
359  NULL if the buffer has never has any contents,
360  but after that this will return an empty string if
361  the buffer is empty.
362  */
363  char const * c_str() const throw();
364 
365  /**
366  Throws an Exception using the given error code and the contents
367  of the buffer as the message.
368  */
369  void toss(int errorCode) const;
370  };
371 
372  /**
373  Writes the first b.used() bytes of b.mem() to os and returns os.
374  */
375  std::ostream & operator<<( std::ostream & os, Buffer const & b );
376 
377  /**
378  Accepts any type compatible with std::ostream<<v, converts
379  it to a string (via std::ostringstream), then appends
380  that result to b. Returns b.
381 
382  */
383  template <typename ValueType>
384  Buffer & operator<<( Buffer & b, ValueType const v ){
385  std::ostringstream os;
386  os << v;
387  std::string const & s(os.str());
388  if(!s.empty()){
389  int const rc = fsl_buffer_append(b, s.data(),
390  (fsl_size_t)s.size());
391  if(rc) throw Exception(rc);
392  }
393  return b;
394  }
395 
396  class Db;
397  /**
398  A prepared statement, the C++ counterpart to ::fsl_stmt.
399 
400  The vast majority of the members (those not marked with throw())
401  throw an Exception on error.
402 
403  Sample usage:
404 
405  @code
406  Stmt st(myDb);
407  st.prepare("SELECT blah FROM foo WHERE id=?")
408  .bind(1,42)
409  .eachRow( MyStepFunctor() )
410  .finalize();
411  @endcode
412 
413  While they are normally created on the stack, they may live on
414  the heap as long as they do not outlive their database.
415  */
416  class Stmt {
417  public:
418  /**
419  Sets up initial state. Most of the member functions will throw
420  until this statement is prepared (via Db::prepare()).
421  */
422  explicit Stmt(Db & db) throw();
423  /**
424  Frees any underlying resources.
425  */
426  ~Stmt() throw();
427 
428  /**
429  Implicit conversion to (fsl_stmt *) to simplify usage with
430  the C API.
431 
432  ABSOLUTELY DO NOT:
433 
434  - ... use this conversion to pass this object to
435  fsl_stmt_finalize()!!! Doing so will lead to a dangling
436  pointer and an eventual segfault and/or double-free().
437 
438  - ... expect this conversion to be picked up when a function
439  takes a void pointer argument.
440  */
441  operator fsl_stmt * () throw();
442 
443  /**
444  Const-correct overload.
445  */
446  operator fsl_stmt const * () const throw();
447 
448  /**
449  Basically a proxy for fsl_db_prepare(), this routine sets this
450  object's statement up from the given formatted SQL string. See
451  fsl_appendf() for the supported formatting specifiers.
452 
453  When passing on strings from external sources, it is safest to
454  pass "%s" as the format string and the foreign string as the
455  first variadic argument. That ensures that percent signs in
456  the foreign input do not get processed as format specifiers
457  (which expect further arguments in the variadic list, which
458  will likely lead to undefined behaviour).
459 
460  Throws on error. Returns this object.
461  */
462  Stmt & prepare(char const * sql, ... );
463 
464  /**
465  Equivalent to this->prepare(db, "%s", sql.c_str()).
466  */
467  Stmt & prepare(std::string const & sql);
468 
469  /**
470  Equivalent to this->prepare(db, "%s", sql.c_str()).
471  */
472  Stmt & prepare(Buffer const & sql);
473 
474  /**
475  Steps one row. Returns true if it fetches a row, false at the
476  end of the result set (and for non-fetching queries like
477  INSERT/UPDATE/DELETE), and throws on error.
478  */
479  bool step();
480 
481  /**
482  step()s the statement one time and throws if the step() call
483  does _not_ return false. This is intended for stepping inserts,
484  updates, and other non-fetching queries. Throws on error,
485  returns this object on success.
486  */
487  Stmt & stepExpectDone();
488 
489  /**
490  "Resets" the statement so it can be executed again, as per
491  fsl_stmt_reset(). If resetStepCounterToo is true then the
492  step-counter is also reset to 0 (see fsl_stmt_reset2() and
493  stepCount()).
494 
495  Returns this object.
496  */
497  Stmt & reset(bool resetStepCounterToo = false);
498 
499  /**
500  Frees any underlying resources owned by this statement. It can
501  be prepared() again after calling this.
502  */
503  Stmt & finalize() throw();
504 
505  /**
506  Returns the number of times step() has fetched a row
507  of data since this counter was last reset.
508  */
509  int stepCount() const throw();
510 
511  /**
512  Returns the number of bound parameters in the statement.
513  */
514  int paramCount() const throw();
515 
516  /**
517  Returns the number of "fetchable" columns in the statement.
518  */
519  int columnCount() const throw();
520 
521  /**
522  Returns the SQL of the statement, or NULL if the statement is
523  not prepared.
524  */
525  char const * sql() const throw();
526 
527  /**
528  Returns this object's C-level fsl_stmt handle.
529 
530  Provided so that client APIs can use fsl_stmt_xxx() functions
531  not wrapped by the C++ APIs. DO NOT, under ANY CIRCUMSTANCES,
532  delete, free, fsl_stmt_finalize(), nor otherwise mess with this
533  handle's ownership. It is owned by this object.
534 
535  Returns NULL if not yet prepared.
536  */
537  fsl_stmt * handle() throw();
538 
539  /**
540  Const-correct overload.
541  */
542  fsl_stmt const * handle() const throw();
543 
544  /** Analog to fsl_stmt_g_int64() */
545  fsl_int32_t getInt32(short colZeroBased);
546 
547  /** Analog to fsl_stmt_g_int64() */
548  fsl_int64_t getInt64(short colZeroBased);
549 
550  /** Analog to fsl_stmt_g_id() */
551  fsl_id_t getId(short colZeroBased);
552 
553  /** Analog to fsl_stmt_g_double() */
554  double getDouble(short colZeroBased);
555 
556  /** Analog to fsl_stmt_g_text() */
557  char const * getText(short colZeroBased, fsl_size_t * length = NULL);
558 
559  /** Analog to fsl_stmt_g_blob() */
560  void const * getBlob(short colZeroBased, fsl_size_t * length = NULL);
561 
562  /** Analog to fsl_stmt_col_name() */
563  char const * columnName(short colZeroBased);
564 
565  /** Analog to fsl_stmt_param_index() */
566  int paramIndex(char const * name);
567 
568  /** Analog to fsl_stmt_bind_null() */
569  Stmt & bind(short colOneBased);
570 
571  /** Analog to fsl_stmt_bind_int32() */
572  Stmt & bind(short colOneBased, fsl_int32_t v);
573 
574  /** Analog to fsl_stmt_bind_int64() */
575  Stmt & bind(short colOneBased, fsl_int64_t v);
576 
577  /** Analog to fsl_stmt_bind_int64() */
578  Stmt & bind(short colOneBased, double v);
579 
580  /** Analog to fsl_stmt_bind_text() */
581  Stmt & bind(short colOneBased, char const * str,
582  fsl_int_t len = -1, bool copyBytes = true);
583 
584  /** Equivalent to bind(colOneBased, str.c_str(), str.size()); */
585  Stmt & bind(short colOneBased, std::string const & str);
586 
587  /** Analog to fsl_stmt_bind_blob() */
588  Stmt & bind(short colOneBased, void const * blob, fsl_size_t len,
589  bool copyBytes = true);
590 
591  /** Analog to fsl_stmt_bind_null_name() */
592  Stmt & bind(char const * col);
593 
594  /** Analog to fsl_stmt_bind_int32_name() */
595  Stmt & bind(char const * col, fsl_int32_t v);
596 
597  /** Analog to fsl_stmt_bind_int64_name() */
598  Stmt & bind(char const * col, fsl_int64_t v);
599 
600  /** Analog to fsl_stmt_bind_double_name() */
601  Stmt & bind(char const * col, double v);
602 
603  /** Analog to fsl_stmt_bind_text_name() */
604  Stmt & bind(char const * col, char const * str,
605  fsl_int_t len = -1, bool copyBytes = true);
606 
607  /** Equivalent to bind(col, str.c_str(), str.size()); */
608  Stmt & bind(char const * col, std::string const & str);
609 
610  /** Analog to fsl_stmt_bind_blob_name() */
611  Stmt & bind(char const * col, void const * blob,
612  fsl_size_t len, bool copyBytes = true);
613 
614  /**
615  Runs a loop over func(*this), calling it once for each time
616  this->step() returns true.
617  */
618  template <typename Func>
619  Stmt & eachRow( Func const & func ){
620  while(this->step()){
621  func(*this);
622  }
623  return *this;
624  }
625 
626  /**
627  Runs a loop over func(*this, state), calling it once for each
628  time this->step() returns true.
629  */
630  template <typename State, typename Func>
631  Stmt & eachRow( Func const & func, State & state ){
632  while(this->step()){
633  func(*this, state);
634  }
635  return *this;
636  }
637 
638  /**
639  Binds each entry of the input iterator range [begin,end),
640  starting at index 1 and moving up.
641  */
642  template <typename IteratorT>
643  Stmt & bindIter( IteratorT const & begin, IteratorT const & end ){
644  IteratorT it(begin);
645  short col = 0;
646  for( ; it != end; ++it ){
647  this->bind( ++col, *it );
648  }
649  return *this;
650  }
651  /**
652  Binds each entry of the given std::list-like type. Each entry
653  in the list is bound starting at index 1 and moving up.
654  */
655  template <typename ListType>
656  Stmt & bindList( ListType const & li ){
657  return bindIter( li.begin(), li.end() );
658  }
659 
660  /**
661  Runs a loop over func(this->handle(), &state), calling it
662  once for each time this->step() returns true. If func() returns
663  0 the loop continues. If it returns FSL_RC_BREAK then the loop
664  stops without an error. If some other value is returned an
665  exception is thrown. Basically a templated form of
666  fsl_stmt_each().
667  */
668  template <typename State>
669  Stmt & eachRow( fsl_stmt_each_f func, State & state ){
670  int rc = 0;
671  while(this->step()){
672  rc = func(&this->stmt, &state);
673  switch(rc){
674  case 0: continue;
675  case FSL_RC_BREAK: break;
676  default:
677  this->propagateError();
678  throw Exception(rc, "Statement eachRow() callback says: %s\n",
679  fsl_rc_cstr(rc));
680  }
681  }
682  return *this;
683  }
684 
685  private:
686  Db & db;
687  fsl_stmt stmt;
688  friend class Db;
689  /** Not implemented. Copying not allowed. */
690  Stmt(Stmt const &);
691  /** Not implemented. Copying not allowed. */
692  Stmt & operator=(Stmt const &);
693 
694  /**
695  Throws an Exception if col is not in the legal bind/get column
696  range. base is the counting index (0 for "get", 1 for
697  "bind"). It must be 0 or 1.
698  */
699  void assertRange(short col, short base) const;
700  /**
701  If rc is not 0 is throws an Exception. If rc==the error
702  code of the underlying db handle then that error info
703  is propagated.
704  */
705  void assertRC(char const * context, int rc) const;
706 
707  /**
708  If this->stmt.db is not NULL and this->stmt.db->error.code is
709  not 0 then it gets propagated as an Exception, else this is a
710  no-op.
711  */
712  void propagateError() const;
713 
714  /**
715  Throws a FSL_RC_MISUSE excception if this statement has not
716  been prepared.
717  */
718  void assertPrepared() const;
719  };// Stmt class
720 
721  /**
722  A utility class for binding values to statements.
723 
724  Example usage:
725 
726  @code
727  // Assume we have an INSERT or UPDATE statement
728  // with 3 columns to bind:
729  StmtBinder b(stmt);
730  b
731  (value1)(value2)(value3)
732  .insert()
733  (42)("hi")(someBlob, blobSize)
734  .insert()
735  ;
736  @endcode
737  */
738  class StmtBinder{
739  private:
740  Stmt & st;
741  short col;
742  public:
743  StmtBinder(Stmt &s);
744  ~StmtBinder();
745 
746  /**
747  Equivalent to stmt().bind(v,len,copyBytes),
748  except that it returns this object.
749  */
750  StmtBinder & operator()(char const * v, fsl_int_t len = -1,
751  bool copyBytes = true);
752 
753  /**
754  Equivalent to stmt().bind(v,len,copyBytes),
755  except that it returns this object.
756  */
757  StmtBinder & operator()(void const * v, fsl_size_t len,
758  bool copyBytes = true);
759 
760  /**
761  A generic bind() op which simply calls stmt().bind(X, v), where
762  X is the next bind column for this object. Throws if the column
763  is out of range or binding fails.
764 
765  Returns this object.
766  */
767  StmtBinder & operator()();
768  template <typename ValT>
770  st.bind(++this->col, v);
771  return *this;
772  }
773 
774  template <typename ListType>
775  StmtBinder & bindList( ListType const & li ){
776  this->st.bindList(li);
777  return *this;
778  }
779 
780 
781  /**
782  Resets this object's bind column counter. Calls stmt().reset()
783  if alsoStatement is true. Returns this object.
784  */
785  StmtBinder & reset(bool alsoStatement = true);
786 
787  /**
788  Returns the underlying statement handle.
789  */
790  Stmt & stmt();
791 
792  /**
793  Equivalent to stmt().step().
794  */
795  bool step();
796 
797  /**
798  Calls stepExpectDone() on the underlying statement, calls
799  this->reset(), and returns this object. Can be used for any
800  type of statement which is expected to trigger an
801  FSL_RC_STEP_DONE from the underlying fsl_stmt API. Basically
802  this means INSERT, UPDATE, REPLACE, and DELETE statements.
803 
804  The convenience factor of this function is that
805  stepExpectDone() will throw if fsl_stmt_step()ing the
806  underlying statement does _not_ return FSL_RC_STEP_DONE.
807  */
808  StmtBinder & once();
809 
810  /** Alias for once(), for readability. */
811  StmtBinder & insert(){return this->once();}
812  /** Alias for once(), for readability. */
813  StmtBinder & update(){return this->once();}
814  };
815 
816  /**
817  C++ counterpart to ::fsl_db.
818 
819  The vast majority of the members (those not marked with throw())
820  throw an Exception on error.
821  */
822  class Db {
823  public:
824  /**
825  Initializes internal state for a closed db. Use open() to open
826  it or handle() to import a foreign fsl_db handle.
827  */
828  Db();
829 
830  /**
831  Initializes internal state and calls Calls
832  this->open(filename,openFlags).
833  */
834  Db(char const * filename, int openFlags);
835 
836  /**
837  Calls this->close().
838  */
839  virtual ~Db() throw();
840 
841  /**
842  Counterpart of fsl_db_open(), with the same semantics for the
843  arguments, except that this function throws on error.
844 
845  Throws on error, else returns this object.
846 
847  Throws if the db is currently opened.
848  */
849  Db & open(char const * filename, int openFlags);
850 
851 
852  /**
853  Implicit conversion to (fsl_db *) to simplify usage with
854  the C API.
855 
856  ABSOLUTELY DO NOT:
857 
858  - ... use this conversion to pass this object to
859  fsl_db_close()!!! Doing so will lead to a dangling pointer and
860  an eventual segfault and/or double-free().
861 
862  - ... expect this conversion to be picked up when a function
863  takes a void pointer argument.
864  */
865  operator fsl_db * () throw();
866 
867  /**
868  Const-correct overload.
869  */
870  operator fsl_db const * () const throw();
871 
872  /**
873  If this->ownsHandle() is true and this object has an opened db,
874  it fsl_db_close() that db, (possibly) freeing the handle and
875  (definitely) any db-owned resources. If !this->ownsHandle()
876  this this clears this object's reference to the underlying db
877  but does _not_ fsl_db_close() it. If this object has no Db
878  handle then this is a harmless no-op.
879  */
880  Db & close() throw();
881 
882  /**
883  Calls this->close() and replaces the internal db handle with
884  the given one.
885 
886  If ownsHandle is true then this object takes over ownership of
887  db. It is CRITICAL that there never be more than one owner (and
888  that owner may be at the C level, unaware of this class). It is
889  also critical that the "owning" Db instance (or exteran fsl_db
890  handle not associated with an owning Db instance) outlive any
891  shared Db instances using that handle. (We can't currently
892  ensure that with a shared pointer due to C-level ownership
893  internals.)
894 
895  If ownsHandle is false then this object becomes a proxy for the
896  given handle but will never close the handle - its memory is
897  assumed to live somewhere else and the fsl_db instance MUST
898  OUTLIVE THIS OBJECT.
899 
900  It is legal to pass NULL db, which triggers a close() and then
901  clears the Db handle. In that case, this object will create a
902  new handle if open() is called on it while it has none.
903 
904  As a special case, if this->handle()==db, this is a no-op.
905 
906  The primarily intention of this mechanism is so that
907  fsl::Context, which proxies up to three db handles, can do so
908  without having to fight the C-level API for ownership of those
909  handles.
910  */
911  Db & handle( fsl_db * db, bool ownsHandle ) throw();
912 
913  /**
914  Returns the filename used to open the DB or NULL
915  if it is not opened.
916  */
917  char const * filename() throw();
918 
919  /**
920  Returns true if this object has an opened db handle,
921  else false.
922  */
923  bool isOpened() const throw();
924 
925  /**
926  Returns this object's C-level fsl_db handle.
927 
928  Provided so that client APIs can use fsl_db_xxx() functions
929  not wrapped by the C++ APIs. DO NOT, under ANY CIRCUMSTANCES,
930  delete, free, fsl_db_close(), nor otherwise mess with this
931  handle's ownership. It is owned by this object.
932 
933  Returns NULL if not yet prepared.
934  */
935  fsl_db * handle() throw();
936 
937  /**
938  Const-correct overload.
939  */
940  fsl_db const * handle() const throw();
941 
942  /**
943  Returns true if this object owns its underlying db handle, else
944  false. Note that it may legally return true even when
945  handle() returns NULL, meaning that this object is prepared
946  to create a handle of its own if needed.
947  */
948  bool ownsHandle() const throw();
949 
950  /**
951  Pushes a level onto the pseudo-recursive transaction stack. See
952  fsl_db_transaction_begin().
953 
954  Throws on error. Returns this object on success.
955 
956  DO NOT EVER use transactions in the API without this function.
957  For example, NEVER exec("BEGIN") because that bypasses the
958  recursive transaction support.
959 
960  For an exception-safer alternative to managing transaction
961  lifetimes, see the Db::Transaction helper class.
962  */
963  Db & begin();
964 
965  /**
966  Pops one level from the transaction stack as "successful,"
967  commiting the transaction only once all levels have been
968  popped.
969 
970  See fsl_db_transaction_commit().
971 
972  Throws on error. Returns this object on success.
973 
974  DO NOT EVER commit a transaction without this function. For
975  example, NEVER exec("COMMIT") because that bypasses the
976  recursive transaction support.
977 
978  */
979  Db & commit();
980 
981  /**
982  Pops one level from the transaction stack and marks the whole
983  transaction as failed. It will not actually roll back the
984  transaction until all levels have been popped, but further
985  commit() calls will implicitly fail until the top-most
986  transaction level is committed, at which point it will
987  recognize the failure and perform a rollback instead.
988 
989  See fsl_db_transaction_rollback().
990 
991  Throws on error. Returns this object on success.
992 
993  DO NOT EVER roll back a transaction without this function. For
994  example, NEVER exec("ROLLBACK") because that bypasses the
995  recursive transaction support.
996  */
997  Db & rollback() throw();
998 
999  /**
1000  Executes the given single fsl_appendf()-formatted SQL
1001  statement. See fsl_appendf() for the formatting options.
1002 
1003  Throws on error. Returns this object.
1004 
1005  See Stmt::prepare() for notes about how to sanely deal with
1006  unsanitized SQL strings from foreign sources.
1007  */
1008  Db & exec(char const * sql, ...);
1009 
1010  /**
1011  Equivalent to this->exec("%s", sql.c_str()).
1012  */
1013  Db & exec(std::string const & sql);
1014 
1015  /**
1016  Executes one or more SQL statements provided in the
1017  fsl_appendf()-formatted SQL string. See fsl_db_exec_multi()
1018  for details. This can be used to import whole schemas at once,
1019  for example.
1020 
1021  Throws on error. Returns this object.
1022  */
1023  Db & execMulti(char const * sql,...);
1024 
1025  /**
1026  Equivalent to this->execMulti("%s", sql.c_str()).
1027  */
1028  Db & execMulti(std::string const & sql);
1029 
1030  /** Analog to fsl_db_attach(), but throws on error. */
1031  Db & attach(char const * filename, char const * label);
1032 
1033  /** Analog to fsl_db_detach(), but throws on error. */
1034  Db & detach(char const * label);
1035 
1036  /**
1037  Returns the current number of transactions pushed onto the
1038  transaction stack. If this is greater than 0 then a transaction
1039  is active (though it might have a failure from a rollback()
1040  performed higher up in the stack).
1041  */
1042  int transactionLevel() const throw();
1043 
1044  /**
1045  A utility to simplify db transaction lifetimes.
1046 
1047  Sample usage:
1048 
1049  @code
1050  Db::Transaction tr(db);
1051  ...lots of stuff which might throw...
1052  tr.commit();
1053  @endcode
1054 
1055  If commit() is not called, the transaction will be rolled back
1056  then the Transaction instance destructs.
1057  */
1058  class Transaction {
1059  private:
1060  Db & db;
1061  int inTrans;
1062  //! Not copyable.
1063  Transaction & operator=(Transaction const &);
1064  //! Not copyable.
1065  Transaction(Transaction const &);
1066  public:
1067 
1068  /**
1069  Calls db.begin().
1070  */
1071  Transaction(Db & db);
1072 
1073  /**
1074  If neither commit() nor rollback() have been called,
1075  this calls rollback(), otherwise it does nothing.
1076  */
1077  ~Transaction() throw();
1078 
1079  /**
1080  Commits the transaction started by the ctor.
1081  */
1082  void commit();
1083 
1084  /**
1085  Rolls back the transaction started by the ctor.
1086  */
1087  void rollback() throw();
1088 
1089  /**
1090  Returns the current transaction level for the underlying db.
1091  */
1092  int level() const throw();
1093  };
1094 
1095 
1096  private:
1097 
1098  friend class Stmt;
1099 
1100  /**
1101  Only mutable so that we can steal db.error's contents when
1102  propagating exceptions. If it's not mutable then we have to
1103  copy that state at throw-time.
1104 
1105  FIXME: we really need a weak pointer and/or a shared ptr with a
1106  configurable finalizer.
1107  */
1108  mutable fsl_db * db;
1109  /**
1110  Whether or not this instance owns this->db.
1111  */
1112  bool ownsDb;
1113 
1114  /**
1115  Not implemented - copying not allowed.
1116  */
1117  Db(Db const &);
1118 
1119  /**
1120  Not implemented - copying not allowed.
1121  */
1122  Db & operator=(Db const &);
1123 
1124  void setup();
1125 
1126  /** Throws if rc is not 0. */
1127  void assertRC(char const * context, int rc) const;
1128 
1129  /** Throws if the db is not opened. */
1130  void assertOpened() const;
1131 
1132  /**
1133  Throws db->error state if db is opened and db->error.code is
1134  not 0, otherwise this is a no-op.
1135  */
1136  void propagateError() const;
1137  };
1138 
1139  /**
1140  C++ counterpart of ::fsl_cx, but generally requires less code to
1141  use because it throws exceptions for any notable errors.
1142 
1143  Example:
1144 
1145  @code
1146  Context cx;
1147  cx.openCheckout();
1148 
1149  fsl_uuid_cstr uuid = NULL;
1150  fsl_id_it rid = 0;
1151  fsl_checkout_version_info( cx, &rid, &uuid );
1152  // ^^^ note, that's a C function!
1153  FslOutputFStream os(cx);
1154  os << "Checkout version: "<<rid<< ' ' << uuid << '\n';
1155  @endcode
1156 
1157  The implicit conversion to ::fsl_cx makes it possible to pass
1158  instances to any C function taking such an argument (and legal to
1159  do so for most function).
1160  */
1161  class Context{
1162  public:
1163  /**
1164  Initializes a new fsl_cx instance, owned by this object, using
1165  the default initialization options.
1166 
1167  Throws on error.
1168  */
1169  Context();
1170 
1171  /**
1172  Initializes a new fsl_cx instance, owned by this object, using
1173  the given initialization options.
1174 
1175  Throws on error.
1176  */
1177  explicit Context(fsl_cx_init_opt const & opt);
1178 
1179  /**
1180  Initializes this object as a wrapper of the given initialized
1181  (via fsl_cx_init()) fsl_cx handle. If ownsHandle is true then
1182  ownership of f is transfered to this object. If ownsHandle is
1183  false then this object is just a "thin" proxy for f and f MUST
1184  OUTLIVE THIS OBJECT.
1185  */
1186  Context(fsl_cx * f, bool ownsHandle);
1187 
1188  /**
1189  If this object owns its context handle, it fsl_cx_finalize()s
1190  it, otherwise it does nothing.
1191 
1192  Note that this is not virtual. It's not expected that
1193  subclassing will be all that useful for this class.
1194  */
1195  ~Context();
1196 
1197  /**
1198  Implicit conversion to (fsl_cx *) to simplify usage with
1199  the C API.
1200 
1201  ABSOLUTELY DO NOT use this conversion...
1202 
1203  - ... to pass this object to fsl_cx_finalize()! Doing so will
1204  lead to a dangling pointer and an eventual segfault and/or
1205  double-free().
1206 
1207  - ... with fsl_checkout_close() or fsl_repo_close() because
1208  pointer ownership may get confused. Use closeDbs() instead. It
1209  will appear to work at times, but certain combinations of
1210  operations via the C API (e.g. opening a checkout, closing it,
1211  then opening a standalone repo) might get some C++-side pointers
1212  cross-wired (theoretically/hypothetically).
1213 
1214  - ... expect this conversion to be picked up when a function
1215  takes a void pointer argument.
1216  */
1217  operator fsl_cx * () throw();
1218 
1219  /**
1220  Const-correct overload.
1221  */
1222  operator fsl_cx const * () const throw();
1223 
1224  /**
1225  Returns this object's C-level fsl_cx handle.
1226 
1227  See operator fsl_cx *() for details.
1228  */
1229  fsl_cx * handle() throw();
1230 
1231  /**
1232  Returns true if this object owns its underlying db handle, else
1233  false. Note that it may legally return true even when
1234  handle() returns NULL, meaning that this object is prepared
1235  to create a handle of its own if needed.
1236  */
1237  bool ownsHandle() const throw();
1238 
1239  /**
1240  Const-correct overload.
1241  */
1242  fsl_cx const * handle() const throw();
1243 
1244  /**
1245  Counterpart of fsl_checkout_open_dir(). Throws on error,
1246  returns this object on success.
1247  */
1248  Context & openCheckout( char const * dirName = NULL );
1249 
1250  /**
1251 
1252  */
1253  Context & openRepo( char const * dbFile );
1254 
1255  /**
1256  Closes any opened repo/checkout/config databases. ACHTUNG: this
1257  may invalidate any Db handles pointing to them!
1258 
1259  Returns this object.
1260 
1261  ACHTUNG: because of ownership issues, clients must always use
1262  this function, instead of the C APIs, for closing repositories
1263  and checkouts.
1264  */
1265  Context & closeDbs() throw();
1266 
1267  /**
1268  Like fsl_rid_to_uuid(*this, rid), but returns the result as a
1269  std::string and throws on error or if no entry is found.
1270  */
1271  std::string ridToUuid(fsl_id_t rid);
1272 
1273  /**
1274  Like fsl_rid_to_artifact_uuid(*this, rid, type), but returns
1275  the result as a std::string and throws on error or if no entry
1276  is found.
1277  */
1278  std::string ridToArtifactUuid(fsl_id_t rid,
1279  fsl_catype_t type = FSL_CATYPE_ANY);
1280 
1281  /**
1282  Like fsl_sym_to_rid(*this,symbolicName), but throws on error
1283  or if no ID is found.
1284  */
1285  fsl_id_t symToRid(char const * symbolicName,
1286  fsl_catype_t type = FSL_CATYPE_ANY);
1287 
1288  /**
1289  Equivalent to symToRid(symbolicName.c_str(), type);
1290  */
1291  fsl_id_t symToRid(std::string const & symbolicName,
1292  fsl_catype_t type = FSL_CATYPE_ANY);
1293 
1294  /**
1295  Like fsl_sym_to_uuid(*this,...), but returns the result as a
1296  std::string and throws on error or if no entry is found. If rid
1297  is not NULL then on success the RID corresponding to the
1298  returned UUID is returned via *rid.
1299  */
1300  std::string symToUuid(char const * symbolicName,
1301  fsl_id_t * rid = NULL,
1302  fsl_catype_t type = FSL_CATYPE_ANY);
1303 
1304  /*Context & handle( fsl_db * db, bool ownsHandle ) throw();*/
1305 
1306  /**
1307  This returns a handle to the repository database. It might
1308  not be opened. The handle and its db connection are
1309  owned by this object resp. by lower levels of the API.
1310  */
1311  Db & dbRepo() throw();
1312 
1313  /**
1314  This returns a handle to the checkout database. It might
1315  not be opened. The handle and its db connection are
1316  owned by this object resp. by lower levels of the API.
1317 
1318  Note that if a checkout is opened, an repo will also be opened,
1319  but not necessarily the other way around.
1320  */
1321  Db & dbCheckout() throw();
1322 
1323  /**
1324  This returns a handle to the context's "main" database. It
1325  might not be opened. The handle and its db connection are owned
1326  by this object resp. by lower levels of the API.
1327  */
1328  Db & db() throw();
1329 
1330  /**
1331  A utility class for managing transactions for a Context-managed
1332  database (regardless of whether the checkout or repo db).
1333  */
1334  class Transaction {
1335  private:
1336  Db::Transaction tr;
1337  int level;
1338  public:
1339  /**
1340  Starts a transaction in cx.db(). Throws on error.
1341  */
1342  Transaction(Context &cx);
1343  /**
1344  If commit() has not been called, this rolls back the
1345  transaction, otherwise it does nothing.
1346  */
1347  ~Transaction() throw();
1348  /**
1349  Commits the transaction resp. pushes this level of the
1350  transaction stack off the stack.
1351  */
1352  void commit();
1353  };
1354 
1355  /**
1356  Analog to fsl_content_get(), but throws an error and returns
1357  this object.
1358  */
1359  Context & getContent( fsl_id_t rid, Buffer & dest );
1360 
1361  /**
1362  Analog to fsl_content_get_sym(), but throws an error and returns
1363  this object.
1364  */
1365  Context & getContent( char const * sym, Buffer & dest );
1366 
1367  /**
1368  Equivalent to getContent(sym.c_str(), dest).
1369  */
1370  Context & getContent( std::string const & sym, Buffer & dest );
1371 
1372  private:
1373  /**
1374  FIXME: we really need a weak pointer and/or a shared ptr with a
1375  configurable finalizer.
1376  */
1377  fsl_cx * f;
1378  bool ownsCx;
1379  Db dbCkout;
1380  Db dbRe;
1381  Db dbMain;
1382  /**
1383  Not implemented - copying not allowed.
1384  */
1385  Context(Context const &);
1386  /**
1387  Not implemented - copying not allowed.
1388  */
1389  Context & operator=(Context const &);
1390 
1391  void assertRC(char const * context, int rc) const;
1392  void assertHasRepo();
1393  void assertHasCheckout();
1394  void propagateError() const;
1395 
1396  void setup(fsl_cx_init_opt const * opt);
1397  };
1398 
1399 
1400  /**
1401  A utility class for iterating over fsl_list instances.
1402 
1403  VT must be a pointer-qualified type because fsl_list only holds
1404  arrays of pointers.
1405 
1406  Modification of the list invalidates any active iterators
1407  (semantically, but not technically, so be careful!).
1408 
1409  Example usage:
1410 
1411  @code
1412  typedef FslListIterator<char const *> Iter;
1413  // assume d is a fsl_deck instance.
1414  Iter it(d.P);
1415  Iter end;
1416  for( ; it != end; ++it ){
1417  char const * str = *it;
1418  if(str){...}
1419  }
1420  @endcode
1421 
1422  Note that this is not type-safe per se - it relies on the
1423  underlying list having only entries of the given type or NULL.
1424 
1425  When used in conjunction with the various fsl_list members of
1426  fsl_deck, it is important to remember that traversing over
1427  fsl_deck::F.list will often, but not always, behave much
1428  differently then FCardIterator because this class traverses only
1429  the F-cards found directly in that deck, which for delta
1430  manifests is only a small fraction of the F-cards actually in
1431  that version (the rest are inherited from its baseline
1432  manifest). FCardIterator is generally the right way to traverse
1433  the F-cards (though this approach has its uses as well).
1434  */
1435  template <typename VT>
1437  private:
1438  fsl_list const *li;
1439  fsl_int_t cursor;
1440  VT current;
1441  protected:
1442  VT currentValue() const throw(){
1443  return this->current;
1444  }
1445  public:
1446  //! STL-compatible value_type typedef.
1447  typedef VT value_type;
1448  //! API-conventional ValueType.
1449  typedef VT ValueType;
1450 
1451  /**
1452  Initializes this iterator to point to the first item im list
1453  (if list.used>0) or to be equivalent to the end iterator (if
1454  the list is empty).
1455 
1456  Changes to the list semantically invalidate all iterators, and
1457  using them afterwars invokes undefined behaviour.
1458  */
1459  explicit FslListIterator(fsl_list const &list)
1460  : li(&list), cursor(-1), current(NULL){
1461  if(li->used){
1462  current = static_cast<value_type>(li->list[0]);
1463  cursor = 1;
1464  }
1465  }
1466 
1467  /**
1468  Initializes an end iterator.
1469  */
1471  : li(NULL), cursor(-1), current(NULL)
1472  {}
1473 
1474  /**
1475  Increments the iterator to point at the next list entry. Throws
1476  if called on an end iterator or if called after the end of the
1477  list has been reached.
1478  */
1480  if((cursor<0) || ((fsl_size_t)cursor>li->used)){
1481  throw Exception(FSL_RC_RANGE,
1482  "Cannot increment past end of list.");
1483  }else if(li->used==(fsl_size_t)cursor){
1484  current = NULL;
1485  cursor = -1;
1486  }else{
1487  current = static_cast<value_type>(li->list[cursor++]);
1488  }
1489  return *this;
1490  }
1491 
1492  /**
1493  Returns the current element's value (possibly NULL!). Throws
1494  for an end iterator.
1495  */
1496  ValueType operator*(){
1497  if(cursor<0){
1498  throw Exception(FSL_RC_RANGE,
1499  "Invalid iterator dereference.");
1500  }
1501  return current;
1502  }
1503 
1504  bool operator==(FslListIterator const &rhs) const throw(){
1505  return (this->cursor==rhs.cursor);
1506  }
1507 
1508  bool operator!=(FslListIterator const &rhs) const throw(){
1509  return (this->cursor!=rhs.cursor);
1510  }
1511  };
1512 
1513  /**
1514  The C++ counterpart to the C-side fsl_deck class.
1515 
1516  Fossil's core metadata syntax calls the entries of the metadata
1517  "cards." A Deck (or fsl_deck) is a "collection of cards" which
1518  make up an atomic unit of metadata. In Fossil jargon a deck is
1519  called an "artifact," but libfossil adopted the name "deck"
1520  because "artifact" already has several meanings in this context.
1521  */
1522  class Deck{
1523  public:
1524  /**
1525  If this instance owns its underlying handle then this cleans up
1526  all resources owned by this instance, otherwise it does
1527  nothing.
1528  */
1529  ~Deck() throw();
1530 
1531  /**
1532  Initializes the deck using the given context. The second
1533  argument is only important when constructing decks, not
1534  when loading them.
1535  */
1536  explicit Deck(Context & cx, fsl_catype_t type = FSL_CATYPE_ANY);
1537 
1538  /**
1539  Makes this object a wrapper for d. If ownsHandle is true then
1540  this object takes over ownership of d, otherwise d is assumed
1541  to be owned elsewhere and it _must_ outlive this object.
1542  */
1543  Deck(Context & cx, fsl_deck * d, bool ownsHandle);
1544 
1545  /**
1546  Implicit conversion to (fsl_deck *) to simplify integration
1547  with the C API.
1548 
1549  ABSOLUTELY DO NOT use this conversion...
1550 
1551  - ... with fsl_deck_finalize(), as that may (depending on usage)
1552  steal a pointer out from under C++.
1553 
1554  - ... expect this conversion to be picked up when a function
1555  takes a void pointer argument.
1556  */
1557  operator fsl_deck *() throw();
1558 
1559  /**
1560  Const-correct overload.
1561  */
1562  operator fsl_deck const *() const throw();
1563 
1564  /**
1565  See operator fsl_deck*().
1566  */
1567  fsl_deck * handle() throw();
1568 
1569  /**
1570  Const-correct overload.
1571  */
1572  fsl_deck const * handle() const throw();
1573 
1574  /**
1575  If this deck was load()ed, returns the loaded artifact's type,
1576  else returns the type set in the constructor.
1577  */
1578  fsl_catype_t type() const throw();
1579 
1580  /**
1581  If this deck was load()ed, returns the blob.rid
1582  value, else returns 0.
1583  */
1584  fsl_id_t rid() const throw();
1585 
1586  /**
1587  If this deck was load()ed, returns the UUID string,
1588  else returns NULL. The bytes are owned by this
1589  object and may be invalidated by load().
1590  */
1591  fsl_uuid_cstr uuid() const throw();
1592 
1593  /**
1594  Analog to fsl_deck_has_required_cards().
1595  */
1596  bool hasAllRequiredCards() const throw();
1597 
1598  /**
1599  Analog to fsl_deck_required_cards_check(),
1600  but throws if that fails.
1601  */
1602  Deck const & assertHasRequiredCards() const;
1603 
1604  /**
1605  Analog to fsl_card_is_legal(), passing this->type() as the
1606  first argument to that function.
1607  */
1608  bool cardIsLegal(char cardLetter) const throw();
1609 
1610  /**
1611  Analog to fsl_deck_load_sym(), but throws on error. Populates this
1612  object with the loaded state.
1613  */
1614  Deck & load( fsl_id_t rid, fsl_catype_t type = FSL_CATYPE_ANY );
1615 
1616  /**
1617  Analog to fsl_deck_load_sym(), but throws on error. Populates this
1618  object with the loaded state.
1619  */
1620  Deck & load( char const * symbolicName, fsl_catype_t type = FSL_CATYPE_ANY );
1621 
1622  /**
1623  Equivalent to load(symbolicName.c_str(), type).
1624  */
1625  Deck & load( std::string const & symbolicName, fsl_catype_t type = FSL_CATYPE_ANY );
1626 
1627  /**
1628  This deck's Fossil Context.
1629  */
1630  Context & context() throw();
1631 
1632  /**
1633  Const-correct overload.
1634  */
1635  Context const & context() const throw() ;
1636 
1637  /**
1638  Equivalent to fsl_deck_clean(*this).
1639  */
1640  Deck & cleanup() throw();
1641 
1642  /**
1643  Analog to fsl_deck_output(), sending its output to the given
1644  stream. Throws on error and returns this object on success.
1645  */
1646  Deck const & output( std::ostream & os ) const;
1647 
1648  /**
1649  Analog to fsl_deck_output(), but throws on error
1650  and returns this object on success.
1651  */
1652  Deck const & output( fsl_output_f f, void * outState ) const;
1653 
1654  /**
1655  Analog to fsl_deck_save(), but throws on error and returns this
1656  object on success.
1657  */
1658  Deck & save(bool isPrivate = false);
1659 
1660  /**
1661  Analog to fsl_deck_unshuffle(), but throws on error and returns
1662  this object on success.
1663 
1664  Reminder: this is only necessary when using output().
1665  */
1666  Deck & unshuffle(bool calcRCard = true);
1667 
1668  /**
1669  Analog to fsl_deck_A_set() but throws on error and returns this
1670  object on success.
1671  */
1672  Deck & setCardA( char const * name,
1673  char const * tgt,
1674  fsl_uuid_cstr uuid );
1675 
1676  /**
1677  Analog to fsl_deck_B_set() but throws on error and returns this
1678  object on success. This destroys any object previously returned
1679  by baseline().
1680  */
1681  Deck & setCardB(fsl_uuid_cstr uuid);
1682 
1683  /**
1684  Analog to fsl_deck_C_set() but throws on error and returns this
1685  object on success.
1686  */
1687  Deck & setCardC( char const * comment );
1688 
1689  /**
1690  Analog to fsl_deck_D_set(), but uses the current time
1691  if (julianDay<0) and throws on error.
1692  */
1693  Deck & setCardD(double julianDay = -1.0);
1694 
1695  /**
1696  Analog to fsl_deck_E_set() but throws on error and returns this
1697  object on success. If the 2nd argument is less than 0 then
1698  the current time is used by default.
1699  */
1700  Deck & setCardE( fsl_uuid_cstr uuid, double julian = -1.0 );
1701 
1702  /**
1703  Analog to fsl_deck_F_add() but throws on error and returns this
1704  object on success.
1705  */
1706  Deck & addCardF(char const * name, fsl_uuid_cstr uuid,
1708  char const * oldName = NULL);
1709 
1710  /**
1711  Analog to fsl_deck_J_add() but throws on error and returns this
1712  object on success.
1713  */
1714  Deck & addCardJ( char isAppend, char const * key, char const * value );
1715 
1716  /**
1717  Analog to fsl_deck_K_set() but throws on error and returns this
1718  object on success.
1719  */
1720  Deck & setCardK(fsl_uuid_cstr uuid);
1721 
1722  /**
1723  Analog to fsl_deck_L_set() but throws on error and returns this
1724  object on success.
1725  */
1726  Deck & setCardL( char const * title );
1727 
1728  /**
1729  Analog to fsl_deck_M_add() but throws on error and returns this
1730  object on success.
1731  */
1732  Deck & addCardM(fsl_uuid_cstr uuid);
1733 
1734  /**
1735  Analog to fsl_deck_N_set() but throws on error and returns this
1736  object on success.
1737  */
1738  Deck & setCardN(char const * name);
1739 
1740  /**
1741  Analog to fsl_deck_P_add() but throws on error and returns this
1742  object on success.
1743  */
1744  Deck & addCardP(fsl_uuid_cstr uuid);
1745 
1746  /**
1747  Analog to fsl_deck_Q_add() but throws on error and returns this
1748  object on success.
1749  */
1750  Deck & addCardQ(char type, fsl_uuid_cstr target,
1751  fsl_uuid_cstr baseline);
1752 
1753  /**
1754  Analog to fsl_deck_T_add() but throws on error and returns this
1755  object on success.
1756  */
1757  Deck & addCardT(fsl_tag_type tagType,
1758  char const * name,
1759  fsl_uuid_cstr uuid = NULL,
1760  char const * value = NULL);
1761 
1762  /**
1763  Sets the U-card, analog to fsl_deck_U_set(). If name is NULL
1764  or !*name then fsl_cx_user_get(this->context()) is used
1765  to fetch the name. An empty name is not legal.
1766 
1767  Throws on error.
1768  */
1769  Deck & setCardU(char const * name = NULL);
1770 
1771  /**
1772  Analog to fsl_deck_W_set() but throws on error and returns this
1773  object on success.
1774  */
1775  Deck & setCardW(char const * content, fsl_int_t len = -1);
1776 
1777  /**
1778  If this is a CHECKIN deck and it is a delta manifest then its
1779  baseline is lazily loaded (if needed) and returned. Throws on
1780  loading error. Returns NULL if this is not CHECKIN or not a
1781  delta manifest. The returned object is owned by this object
1782  and will be cleaned up when it is or when the B-card is re-set
1783  (setCardB()).
1784  */
1785  Deck * baseline();
1786 
1787  /**
1788  An iterator type for traversing lists of T-cards (tags) in a
1789  deck.
1790 
1791  Example usage:
1792 
1793  @code
1794  Deck::TCardIterator it(myDeck);
1795  Deck::TCardIterator end;
1796  for( ; it != end; ++it ){
1797  std::cout
1798  << fsl_tag_prefix_char(it->type)
1799  << it->name << '\n';
1800  }
1801  @endcode
1802  */
1803  class TCardIterator : public FslListIterator<fsl_card_T const *>{
1804  private:
1806  public:
1807  /**
1808  Constructs a "begin" iterator for d's T-cards.
1809  */
1810  TCardIterator(Deck & d);
1811  /**
1812  Constructs an "end" iterator for a T-card list.
1813  */
1814  TCardIterator();
1815  ~TCardIterator() throw();
1816 
1817  /**
1818  Returns the same as *this, but throws for an end
1819  iterator.
1820  */
1821  fsl_card_T const * operator->() const;
1822  };
1823 
1824  /**
1825  An STL-style iterator class for use with traversing the F-cards
1826  in a Deck object. Because of how delta manifests work, F-cards
1827  have rather intricate traversal rules. This class helps hide
1828  those from the client (the only one it exposes is that F-cards
1829  are required to be in strict lexical order).
1830 
1831  Reminder: client code must be prepared to handle F-cards with
1832  NULL UUIDs. They appear when a file is removed between a
1833  baseline manifest and its delta. The delta marks deletions with
1834  a NULL UUID. A baseline manifest marks deletions by simply not
1835  including the file in the manifest (no F-card). The library
1836  "could" skip such entries when iterating, but knowing about
1837  deleted entries is useful at times.
1838 
1839  Potential TODO: a flag to this class which tells it to
1840  skip over deleted entries.
1841  */
1843  private:
1844  Deck * d;
1845  fsl_card_F const * fc;
1846  bool skipDeleted;
1847  void assertHasDeck();
1848  public:
1849  /**
1850  Rewinds d's F-card list and initializes this iterator to point
1851  to the first F-card in d. Remember that only decks of type
1852  FSL_CATYPE_CHECKIN have F-cards. Throws if rewinding fails (it
1853  only fails if lazy loading of a baseline manifest fails).
1854  */
1855  explicit FCardIterator(Deck & d, bool skipDeletedFiles = false);
1856 
1857  /**
1858  Constructs an "end" iterator.
1859  */
1860  FCardIterator() throw();
1861 
1862  ~FCardIterator() throw();
1863 
1864  /**
1865  Prefix increment: advances iterator and returns the new value.
1866 
1867  A no-op for an "end" iterator.
1868 
1869  If the skip-deleted flag was passed to the constructor then
1870  F-cards which represent deleted entries are skipped during
1871  traversal.
1872  */
1873  FCardIterator & operator++();
1874 
1875  /**
1876  The current F-card, or NULL at the end of the list.
1877  */
1878  fsl_card_F const * operator*();
1879 
1880  /**
1881  Convenience operator. Throws for an "end" iterator.
1882  */
1883  fsl_card_F const * operator->();
1884 
1885  /** Compares this object and rhs by name. */
1886  bool operator==(FCardIterator const &rhs) const throw();
1887  /** Compares this object and rhs by name. */
1888  bool operator!=(FCardIterator const &rhs) const throw();
1889  /** Compares this object and rhs by name. */
1890  bool operator<(FCardIterator const &rhs) const throw();
1891  };
1892 
1893  private:
1894  Context & cx;
1895  fsl_deck * d;
1896  Deck * deltaBase;
1897  bool ownsDeck;
1898  void setup(fsl_deck * d, fsl_catype_t type);
1899  void propagateError() const;
1900  void assertRC(char const * context, int rc) const;
1901  /** Not implemented - copying not currently allowed. */
1902  Deck(Deck const &);
1903  /** Not implemented - copying not currently allowed. */
1904  Deck & operator=(Deck const &);
1905  };
1906 
1907  /** Calls d.output(os) and returns os. */
1908  std::ostream & operator<<( std::ostream & os, Deck const & d );
1909 
1910  /**
1911  A fsl_appendf_f() implementation which requires that state be a
1912  std::ostream pointer. It uses std::ostream::write() to append n
1913  bytes of the data argument to the output stream. If the write()
1914  operation throws, this function catches it and returns FSL_RC_IO
1915  instead (because we propagating exceptions across the C API has
1916  undefined behaviour). Returns 0 on success, FSL_RC_IO if the
1917  stream is in an error state after the write.
1918  */
1919  fsl_int_t fsl_appendf_f_std_ostream( void * state, char const * data,
1920  fsl_int_t n );
1921 
1922  /**
1923  A fsl_output_f() implementation which requires that state be a
1924  std::ostream pointer. It uses std::ostream::write() to append n
1925  bytes of the data argument to the output stream. If the write()
1926  operation throws, this function catches it and returns FSL_RC_IO
1927  instead (because propagating exceptions across the C API has
1928  undefined behaviour). Returns 0 on success, FSL_RC_IO if the
1929  stream is in an error state after the write.
1930  */
1931  int fsl_output_f_std_ostream( void * state, void const * data,
1932  fsl_size_t n );
1933 
1934  /**
1935  A fsl_input_f() implementation which requires state to be a
1936  std::istream pointer. Characters are read from the stream until
1937  *n bytes are read or EOF is reached. If EOF is reached, *n is set
1938  to the number of bytes consumed (and written to dest) before
1939  reaching EOF. If the input operation throws, this function
1940  catches it and returns FSL_RC_IO instead (because propagating
1941  exceptions across the C API has undefined behaviour)
1942 
1943  Example usage:
1944 
1945  @code
1946  char const * filename = "some-file";
1947  std::ifstream is(filename);
1948  if(!is.good()) throw Exception(FSL_RC_IO,"Cannot open: %s", filename);
1949  fsl_buffer buf = fsl_buffer_empty;
1950  int rc = fsl_buffer_fill_from( &buf,
1951  fsl_input_f_std_istream,
1952  &is );
1953  if(rc) {...error...}
1954  else {...okay...}
1955  fsl_buffer_clear(&buf); // in error cases it might be partially filled!
1956  @endcode
1957 
1958  Better yet, use try/catch to better protect the buffer from
1959  leaks:
1960 
1961  @code
1962  fsl_buffer buf = fsl_buffer_empty;
1963  try{
1964  ... do i/o here ...
1965  }catch(...){
1966  fsl_buffer_clear(&buf);
1967  throw;
1968  }
1969  fsl_buffer_clear(&buf);
1970  @endcode
1971 
1972  _Even better_, use the Buffer class to manage buffer memory
1973  lifetime, making it inherently exception-safe:
1974 
1975  @code
1976  std::ifstream is(filename);
1977  Buffer buf;
1978  int rc = fsl_buffer_fill_from(buf, fsl_input_f_std_istream, &is );
1979  if(rc) throw Exception(rc); // now buf will not leak
1980  ...
1981  @endcode
1982  */
1983  int fsl_input_f_std_istream( void * state, void * dest, fsl_size_t * n );
1984 
1985  /**
1986  A std::streambuf impl which redirects a std::streambuf to
1987  fsl_output(). Can be used, e.g. to redirect std::cout and
1988  std::cerr to fsl_output().
1989  */
1990  class ContextOStreamBuf : public std::streambuf {
1991  private:
1992  fsl_cx * f;
1993  std::ostream * m_os;
1994  std::streambuf * m_old;
1995  void setup( fsl_cx * f );
1996  public:
1997  /**
1998  Redirects os's buffer to use this object, such that all output
1999  sent to os will instead go through this buffer to
2000  fsl_output(f,...). os must outlive this object. When this
2001  object destructs, os's old buffer is restored.
2002 
2003  Throws if f is NULL.
2004 
2005  Example:
2006 
2007  @code
2008  ContextOStreamBuf sb(myFossil, std::cout);
2009  std::cout << "This now goes through fsl_output(myFossil,...).\n";
2010  @endcode
2011  */
2012  ContextOStreamBuf( fsl_cx * f, std::ostream & os );
2013 
2014  /**
2015  Equivalent to passing cx.handle() to the other two-arg ctor.
2016  */
2017  ContextOStreamBuf( Context & cx, std::ostream & os );
2018 
2019  /**
2020  Redirects all output sent to this buffer to fsl_output(f,...).
2021 
2022  Throws if f is NULL.
2023  */
2024  explicit ContextOStreamBuf( fsl_cx * f );
2025 
2026  /**
2027  Equivalent to passing cx.handle() to the other one-arg ctor.
2028  */
2029  explicit ContextOStreamBuf( Context & cx );
2030 
2031  /**
2032  Flushes the buffer via this->sync();
2033 
2034  If this object wraps a stream, that streams buffer is then
2035  restored to its prior state.
2036  */
2037  virtual ~ContextOStreamBuf() throw();
2038 
2039  /**
2040  Outputs c as a single char via fsl_output(), using the fsl_cx
2041  instance passed to the constructor.
2042 
2043  On a write error it throws, else it returns 0.
2044  */
2045  virtual int overflow( int c );
2046 
2047  /**
2048  Falls fsl_flush(), passing it the fsl_cx instance passed to the
2049  ctor. Returns the result of that call.
2050  */
2051  virtual int sync();
2052 
2053  };
2054 
2055  /**
2056  A std::ostream which redirects its output to the output channel
2057  configured for a fsl_cx instance.
2058 
2059  Example usage:
2060 
2061  @code
2062  ContextOStream os(someContext.handle());
2063  os << "hi, world!\n"; // goes through fsl_output()
2064  @endcode
2065  */
2066  class ContextOStream : public std::ostringstream {
2067  private:
2068  fsl_cx * f;
2069  ContextOStreamBuf * sb;
2070  public:
2071 
2072  /**
2073  Sets up this buffer to direct all stream output sent to this
2074  buffer to fsl_output() instead, using f as the first argument
2075  to that function.
2076 
2077  Ownership of f is not changed. f must outlive this object.
2078  */
2079  explicit ContextOStream( fsl_cx * f );
2080 
2081  /**
2082  Equivalent to passing cx.handle() to the other ctor.
2083  */
2084  explicit ContextOStream( Context & cx );
2085 
2086  /**
2087  If initialized, it calls fsl_flush(), otherwise it has
2088  no visible side-effects.
2089  */
2090  virtual ~ContextOStream() throw();
2091 
2092  /**
2093  Appends a formatted string, as per fsl_outputf(), to the
2094  stream. This is primarily intended for adding SQL-related
2095  escaping to the buffer using the %q/%Q specifiers.
2096 
2097  Returns this object.
2098  */
2099  ContextOStream & appendf(char const * fmt, ...);
2100  };
2101 
2102  /**
2103  A std::streambuf impl which redirects a std::streambuf to a
2104  fsl_output_f(). It can be used, e.g. to redirect std::cout and
2105  std::cerr to a client-specific callback.
2106  */
2107  class FslOutputFStreamBuf : public std::streambuf {
2108  private:
2109  fsl_output_f out;
2110  void * outState;
2111  std::ostream * m_os;
2112  std::streambuf * m_old;
2113  void setup( fsl_output_f f, void * state );
2114  public:
2115  /**
2116  Redirects os's buffer to use this object, such that all output
2117  sent to os will instead go through this buffer to
2118  fsl_output(f,...). os must outlive this object. When this
2119  object destructs, os's old buffer is restored.
2120 
2121  Throws if !out.
2122 
2123  Example:
2124 
2125  @code
2126  FslOutputFStreamBuf sb(myCallback, callbackState, std::cout);
2127  std::cout << "This now goes through fsl_output(myFossil,...).\n";
2128  @endcode
2129  */
2130  FslOutputFStreamBuf( fsl_output_f out, void * outState,
2131  std::ostream & os );
2132 
2133  /**
2134  Sets up output sent to this stream to go throug
2135  out(outState,...).
2136 
2137  Throws if !out.
2138  */
2139  FslOutputFStreamBuf( fsl_output_f out, void * outState );
2140 
2141  /**
2142  If this object wraps a stream, that stream's buffer is restored
2143  to its prior state.
2144  */
2145  virtual ~FslOutputFStreamBuf() throw();
2146 
2147  /**
2148  Outputs c as a single byte via the output function provided to
2149  the ctor. Throws on error.
2150  */
2151  virtual int overflow( int c );
2152 
2153  /**
2154  Does nothing. Returns 0.
2155  */
2156  virtual int sync();
2157  };
2158 
2159 
2160  /**
2161  This std::ostream subclass which proxies a fsl_output_f()
2162  implementation, sending all output to that function.
2163 
2164  The stream throws on output errors.
2165 
2166  Example usage, sending output to a Buffer using stream
2167  operators:
2168 
2169  @code
2170  Buffer buf;
2171  FslOutputFStream os(fsl_output_f_buffer, buf.handle());
2172  // ^^^ For this particular case MAKE SURE to pass the C
2173  // fsl_buffer handle, NOT the C++ Buffer handle!
2174  os << "hi, world!";
2175  assert(10==buf.used());
2176 
2177  // Or, more simply:
2178  BufferOStream bos(buf);
2179  bos << "hi, world!";
2180  @endcode
2181  */
2182  class FslOutputFStream : public std::ostream {
2183  private:
2184  /** The underlying proxy buffer. */
2185  FslOutputFStreamBuf * sb;
2186  /**
2187  fsl_appendf_f() impl which requires state to be a
2188  FslOutputFStream pointer. All output gets sent to this stream's
2189  proxy function.
2190  */
2191  static fsl_int_t fslAppendfF( void * state, char const * s, fsl_int_t n );
2192 
2193  public:
2194 
2195  /**
2196  Sets up this stream to direct all stream output sent to this
2197  buffer to out(outState, ...) instead.
2198 
2199  Ownership of outState is not changed. outState, if not NULL,
2200  must outlive this object.
2201 
2202  Throws if !out.
2203  */
2204  explicit FslOutputFStream( fsl_output_f out, void * outState );
2205 
2206  /**
2207  Cleans up its internal resources.
2208  */
2209  virtual ~FslOutputFStream() throw();
2210 
2211  /**
2212  Appends a formatted string, as per fsl_outputf(), to the
2213  stream. This is primarily intended for adding SQL-related
2214  escaping to the buffer using the %q/%Q specifiers.
2215 
2216  Returns this object.
2217  */
2218  FslOutputFStream & appendf(char const * fmt, ...);
2219  };
2220 
2221 
2223  public:
2224  /**
2225  Sets up this object to redirect all stream output to the given
2226  buffer. Ownership of b is not changed and b must outlive this
2227  stream. It is legal to implicitly convert a Buffer object for
2228  this purpose.
2229 
2230  Throws if b is NULL.
2231  */
2232  explicit BufferOStream(fsl_buffer * b);
2233  /**
2234  Does nothing.
2235  */
2236  ~BufferOStream() throw();
2237  };
2238 
2239 }/*namespace fsl*/
2240 
2241 #endif
2242 /* NET_FOSSIL_SCM_LIBFOSSIL_HPP_INCLUDED */
A utility class for iterating over fsl_list instances.
Definition: fossil.hpp:1436
FslListIterator & operator++()
Increments the iterator to point at the next list entry.
Definition: fossil.hpp:1479
fsl_uint_t fsl_size_t
fsl_size_t is an unsigned integer type used to denote absolute ranges and lengths.
fsl_catype_t
An enumeration of the types of control artifacts used by Fossil.
Definition: fossil-core.h:1548
C++ counterpart of fsl_cx, but generally requires less code to use because it throws exceptions for a...
Definition: fossil.hpp:1161
int fsl_int32_t
Definition: fossil-config.h:81
License as yet undecided!
Definition: fossil-core.h:30
The main Fossil "context" type.
A std::streambuf impl which redirects a std::streambuf to fsl_output().
Definition: fossil.hpp:1990
Stmt & eachRow(Func const &func, State &state)
Runs a loop over func(*this, state), calling it once for each time this->step() returns true...
Definition: fossil.hpp:631
Out-of-memory exception.
Definition: fossil.hpp:169
Buffer & reset()
Equivalent to fsl_buffer_reset(*this).
Buffer & clear()
Equivalent to fsl_buffer_clear(*this).
fsl_int_t fsl_appendf_f_std_ostream(void *state, char const *data, fsl_int_t n)
A fsl_appendf_f() implementation which requires that state be a std::ostream pointer.
VT ValueType
API-conventional ValueType.
Definition: fossil.hpp:1449
Used by some iteration routines to indicate that iteration should stop prematurely without an error...
Definition: fossil-core.h:307
bool operator==(FslListIterator const &rhs) const
Definition: fossil.hpp:1504
char const * codeString() const
Equivalent to fsl_rc_cstr(this->code()).
StmtBinder & update()
Alias for once(), for readability.
Definition: fossil.hpp:813
int fsl_input_f_std_istream(void *state, void *dest, fsl_size_t *n)
A fsl_input_f() implementation which requires state to be a std::istream pointer. ...
Stmt & eachRow(fsl_stmt_each_f func, State &state)
Runs a loop over func(this->handle(), &state), calling it once for each time this->step() returns tru...
Definition: fossil.hpp:669
FSL_EXPORT int fsl_buffer_append(fsl_buffer *b, void const *src, fsl_int_t n)
Appends the first n bytes of src, plus a NUL byte, to b, expanding b as necessary and incrementing b-...
A container for storing generic error state.
Definition: fossil-util.h:692
~Buffer()
Frees all memory owned by the buffer.
This std::ostream subclass which proxies a fsl_output_f() implementation, sending all output to that ...
Definition: fossil.hpp:2182
A prepared statement, the C++ counterpart to fsl_stmt.
Definition: fossil.hpp:416
std::ostream & operator<<(std::ostream &os, Buffer const &b)
Writes the first b.used() bytes of b.mem() to os and returns os.
Db handle wrapper class.
Definition: fossil-db.h:105
StmtBinder & bindList(ListType const &li)
Definition: fossil.hpp:775
char const * fsl_uuid_cstr
The const counterpart of fsl_uuid_str.
Definition: fossil-util.h:92
Generic list container type.
Definition: fossil-util.h:150
Buffer & reserve(fsl_size_t n)
Equivalent to fsl_buffer_reserve(*this, n), but throws on error and returns this object on success...
FslListIterator()
Initializes an end iterator.
Definition: fossil.hpp:1470
OOMException()
Sets the code FSL_RC_OOM and uses no error string (to avoid allocating more memory).
Exception()
A default-constructed exception with no message string and an error code of FSL_RC_ERROR.
Represents a prepared statement handle.
Definition: fossil-db.h:321
Stmt & bind(short colOneBased)
Analog to fsl_stmt_bind_null()
VT value_type
STL-compatible value_type typedef.
Definition: fossil.hpp:1447
iterator end()
Returns the one-after-the-end of the memory position iterator (the "used" space, not necessarily the ...
char const * c_str() const
Returns a pointer to the buffer member.
int(* fsl_stmt_each_f)(fsl_stmt *stmt, void *state)
A callback interface for use with fsl_stmt_each() and fsl_db_each().
Definition: fossil-db.h:682
Sentinel value used to mark a deck as being "any" type.
Definition: fossil-core.h:1557
Buffer()
Initializes an empty buffer.
Stmt & eachRow(Func const &func)
Runs a loop over func(*this), calling it once for each time this->step() returns true.
Definition: fossil.hpp:619
unsigned char * iterator
STL-style iterator for the buffer's memory.
Definition: fossil.hpp:319
A utility class for managing transactions for a Context-managed database (regardless of whether the c...
Definition: fossil.hpp:1334
A very thin varnish over fsl_buffer, the primary advantage being that it frees its memory when it des...
Definition: fossil.hpp:203
virtual ~Exception()
Cleans up any error string memory.
The C++ counterpart to the C-side fsl_deck class.
Definition: fossil.hpp:1522
FslListIterator(fsl_list const &list)
Initializes this iterator to point to the first item im list (if list.used>0) or to be equivalent to ...
Definition: fossil.hpp:1459
fsl_file_perm_t
Filesystem-level permissions flags supported by fossil Manifests.
Definition: fossil-core.h:431
int code() const
Returns the code passed to the constructor.
fsl_size_t capacity() const
Returns the current capacity of the buffer.
fsl_int32_t fsl_id_t
fsl_id_t is a signed integer type used to store database record IDs.
FSL_EXPORT char const * fsl_rc_cstr(int)
Returns a "standard" string form for a fsl_rc_t code.
Represents a tag in a Manifest or Control Artifact.
bool operator!=(FslListIterator const &rhs) const
Definition: fossil.hpp:1508
A general-purpose buffer class, analog to Fossil v1's Blob class, but it is not called fsl_blob to av...
Definition: fossil-util.h:632
virtual char const * what() const
Returns the message string provided to the ctor.
unsigned char const * const_iterator
STL-style const iterator for the buffer's memory.
Definition: fossil.hpp:324
long long int fsl_int64_t
Definition: fossil-config.h:94
Indicates a regular, writable file.
Definition: fossil-core.h:433
The base exception type used by the API.
Definition: fossil.hpp:54
Represents one file entry in a Manifest/Control Artifact (i.e., a checkin version).
Exception & operator=(Exception const &other)
Copies the error message state from other.
Some range was violated (function argument, UTF character, etc.).
Definition: fossil-core.h:254
unsigned char * mem()
Returns a pointer to the current buffer, which points to used() bytes of memory.
A utility class for binding values to statements.
Definition: fossil.hpp:738
fsl_int64_t fsl_int_t
fsl_int_t is a signed integer type used to denote "relative" ranges and lengths, or to tell a routine...
Stmt & bindList(ListType const &li)
Binds each entry of the given std::list-like type.
Definition: fossil.hpp:656
fsl_size_t used
Number of "used" entries in the list.
Definition: fossil-util.h:159
A std::streambuf impl which redirects a std::streambuf to a fsl_output_f().
Definition: fossil.hpp:2107
char const * messsage() const
Alias (for API consistency's sake) for what().
StmtBinder & insert()
Alias for once(), for readability.
Definition: fossil.hpp:811
void ** list
Array of entries.
Definition: fossil-util.h:155
void toss(int errorCode) const
Throws an Exception using the given error code and the contents of the buffer as the message...
fsl_size_t used() const
Returns the "used" number of bytes in the buffer.
fsl_tag_type
Artifact tag types used by the Fossil framework.
Buffer & resize(fsl_size_t n)
Equivalent to fsl_buffer_resize(*this, n), but throws on error and returns this object on success...
ValueType operator*()
Returns the current element's value (possibly NULL!).
Definition: fossil.hpp:1496
A "deck" stores (predictably enough) a collection of "cards." Cards are constructs embedded within Fo...
Buffer & appendf(char const *fmt,...)
Basically equivalent to fsl_buffer_appendf(*this,...) except that it throws if that function fails...
StmtBinder & operator()(ValT v)
Definition: fossil.hpp:769
fsl_buffer * handle()
Returns the underlying fsl_buffer this object proxies.
VT currentValue() const
Definition: fossil.hpp:1442
A utility to simplify db transaction lifetimes.
Definition: fossil.hpp:1058
Buffer & operator=(Buffer const &other)
Replaces the current buffer contents with a copy of those from the given buffer.
Parameters for fsl_cx_init().
Definition: fossil-core.h:537
A std::ostream which redirects its output to the output channel configured for a fsl_cx instance...
Definition: fossil.hpp:2066
An STL-style iterator class for use with traversing the F-cards in a Deck object. ...
Definition: fossil.hpp:1842
Stmt & bindIter(IteratorT const &begin, IteratorT const &end)
Binds each entry of the input iterator range [begin,end), starting at index 1 and moving up...
Definition: fossil.hpp:643
C++ counterpart to fsl_db.
Definition: fossil.hpp:822
bool empty() const
Returns true if 0==used().
int fsl_output_f_std_ostream(void *state, void const *data, fsl_size_t n)
A fsl_output_f() implementation which requires that state be a std::ostream pointer.
An iterator type for traversing lists of T-cards (tags) in a deck.
Definition: fossil.hpp:1803
int(* fsl_output_f)(void *state, void const *src, fsl_size_t n)
Generic interface for streaming out data.
Definition: fossil-util.h:275
iterator begin()
Returns the starting memory position iterator, or NULL if empty().