Browse files

Add an implementation for libcbio

  • Loading branch information...
1 parent 851438b commit 2da91c6ff93519fa368347a21daa75d5c131d587 @trondn trondn committed Apr 19, 2012
Showing with 2,691 additions and 0 deletions.
  1. +42 −0 .gitignore
  2. +95 −0 Makefile.am
  3. +104 −0 config/autorun.sh
  4. +666 −0 config/config.rpath
  5. +86 −0 configure.ac
  6. +183 −0 include/libcbio/cbio.h
  7. +61 −0 include/libcbio/types.h
  8. +42 −0 include/libcbio/visibility.h
  9. +181 −0 m4/couchbase.m4
  10. +300 −0 src/document.c
  11. +84 −0 src/error.c
  12. +195 −0 src/instance.c
  13. +48 −0 src/internal.h
  14. +604 −0 tests/testapp.c
View
42 .gitignore
@@ -0,0 +1,42 @@
+# Keep the entries sorted to reduce the risk for a merge conflict
+*.[ao]
+*.dll
+*.la
+*.lo
+*.exe
+*.exp
+*.lib
+*.obj
+*.orig
+*~
+.deps
+.dirstamp
+.libs
+/Makefile
+/Makefile.in
+/aclocal.m4
+/autom4te.cache
+/build/
+/config.cache
+/config.log
+/config.status
+/config/compile
+/config/config.guess
+/config/config.sub
+/config/depcomp
+/config/install-sh
+/config/ltmain.sh
+/config/missing
+/configure
+/libtool
+/m4/libtool.m4
+/m4/lt*m4
+/m4/version.m4
+/testcase.couch
+/vc100.idb
+/vc100.pdb
+config.h
+config.h.in
+core*
+stamp-h1
+tests/test_*
View
95 Makefile.am
@@ -0,0 +1,95 @@
+#
+# Copyright 2012 Couchbase, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+ACLOCAL_AMFLAGS = -I m4 --force
+lib_LTLIBRARIES = libcbio.la
+
+pkginclude_HEADERS = \
+ include/libcbio/cbio.h \
+ include/libcbio/types.h \
+ include/libcbio/visibility.h
+
+libcbio_la_CPPFLAGS = $(AM_CPPFLAGS) -DLIBCBIO_INTERNAL=1
+libcbio_la_SOURCES = src/document.c src/error.c src/instance.c src/internal.h
+libcbio_la_LDFLAGS = $(AM_LDFLAGS) -lcouchstore
+
+check_PROGRAMS = tests/test_open_empty_filename \
+ tests/test_create_database tests/test_get_miss \
+ tests/test_store_single_document tests/test_get_hit \
+ tests/test_delete_document \
+ tests/test_delete_nonexistent_document \
+ tests/test_get_deleted_document \
+ tests/test_bulk_store_documents \
+ tests/test_changes_since
+
+TESTS=${check_PROGRAMS}
+
+tests_test_open_empty_filename_SOURCES = tests/testapp.c
+tests_test_open_empty_filename_LDFLAGS = libcbio.la
+
+tests_test_create_database_SOURCES = tests/testapp.c
+tests_test_create_database_LDFLAGS = libcbio.la
+
+tests_test_get_hit_SOURCES = tests/testapp.c
+tests_test_get_hit_LDFLAGS = libcbio.la
+
+tests_test_get_miss_SOURCES = tests/testapp.c
+tests_test_get_miss_LDFLAGS = libcbio.la
+
+tests_test_store_single_document_SOURCES = tests/testapp.c
+tests_test_store_single_document_LDFLAGS = libcbio.la
+
+tests_test_delete_document_SOURCES = tests/testapp.c
+tests_test_delete_document_LDFLAGS = libcbio.la
+
+tests_test_delete_nonexistent_document_SOURCES = tests/testapp.c
+tests_test_delete_nonexistent_document_LDFLAGS = libcbio.la
+
+tests_test_get_deleted_document_SOURCES = tests/testapp.c
+tests_test_get_deleted_document_LDFLAGS = libcbio.la
+
+tests_test_bulk_store_documents_SOURCES = tests/testapp.c
+tests_test_bulk_store_documents_LDFLAGS = libcbio.la
+
+tests_test_changes_since_SOURCES = tests/testapp.c
+tests_test_changes_since_LDFLAGS = libcbio.la
+
+
+LINTFLAGS=-Iinclude -b -c -errchk=%all \
+ -erroff=E_INCL_NUSD,E_CAST_INT_TO_SMALL_INT,E_PTRDIFF_OVERFLOW \
+ -errtags=yes -errhdr=%user \
+ -errsecurity=extended -fd -Ncheck=%all -Nlevel=4 -n -Xc99=none
+lint:
+ $(LINT.c) $(libcbio_la_SOURCES)
+
+reformat:
+ astyle --mode=c \
+ --quiet \
+ --style=1tbs \
+ --indent=spaces=4 \
+ --indent-namespaces \
+ --indent-col1-comments \
+ --max-instatement-indent=78 \
+ --pad-oper \
+ --pad-header \
+ --add-brackets \
+ --unpad-paren \
+ --align-pointer=name \
+ --align-reference=name \
+ $(top_srcdir)/include/libcbio/*.[ch] \
+ $(top_srcdir)/src/*.[ch] \
+ $(top_srcdir)/tests/*.[ch]
+
View
104 config/autorun.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+LIBTOOLIZE_FLAGS="--automake --copy --force"
+AUTOMAKE_FLAGS="--add-missing --copy --force --foreign --warning=portability"
+ACLOCAL_FLAGS="-I m4"
+AUTOHEADER_FLAGS="--warnings=error"
+AUTOCONF_CLAGS="--warnings=error --force"
+
+
+ARGV0=$0
+ARGS="$@"
+
+die() { echo "$@"; exit 1; }
+
+run() {
+ echo "$ARGV0: running \`$@' $ARGS"
+ $@ $ARGS
+}
+
+# Try to locate a program by using which, and verify that the file is an
+# executable
+locate_binary() {
+ for f in $@
+ do
+ file=`which $f 2>/dev/null | grep -v '^no '`
+ if test -n "$file" -a -x "$file"; then
+ echo $file
+ return 0
+ fi
+ done
+
+ echo ""
+ return 1
+}
+
+if test -f config/pre_hook.sh
+then
+ . config/pre_hook.sh
+fi
+
+if [ -d .git ]
+then
+ cat > m4/version.m4 <<EOF
+m4_define([VERSION_NUMBER], [`git describe | tr '-' '_'`])
+m4_define([GIT_CHANGESET],[`git rev-parse HEAD`])
+EOF
+fi
+
+# Try to detect the supported binaries if the user didn't
+# override that by pushing the environment variable
+if test x$LIBTOOLIZE = x; then
+ LIBTOOLIZE=`locate_binary libtoolize glibtoolize`
+ if test x$LIBTOOLIZE = x; then
+ die "Did not find a supported libtoolize"
+ fi
+fi
+
+if test x$ACLOCAL = x; then
+ ACLOCAL=`locate_binary aclocal-1.11 aclocal-1.10 aclocal`
+ if test x$ACLOCAL = x; then
+ die "Did not find a supported aclocal"
+ fi
+fi
+
+if test x$AUTOMAKE = x; then
+ AUTOMAKE=`locate_binary automake-1.11 automake-1.10 automake`
+ if test x$AUTOMAKE = x; then
+ die "Did not find a supported automake"
+ fi
+fi
+
+if test x$AUTOCONF = x; then
+ AUTOCONF=`locate_binary autoconf`
+ if test x$AUTOCONF = x; then
+ die "Did not find a supported autoconf"
+ fi
+fi
+
+if test x$AUTOHEADER = x; then
+ AUTOHEADER=`locate_binary autoheader`
+ if test x$AUTOHEADER = x; then
+ die "Did not find a supported autoheader"
+ fi
+fi
+
+run $LIBTOOLIZE $LIBTOOLIZE_FLAGS || die "Can't execute libtoolize"
+run $ACLOCAL $ACLOCAL_FLAGS || die "Can't execute aclocal"
+run $AUTOHEADER $AUTOHEADER_FLAGS || die "Can't execute autoheader"
+run $AUTOMAKE $AUTOMAKE_FLAGS || die "Can't execute automake"
+run $AUTOCONF $AUTOCONF_FLAGS || die "Can't execute autoconf"
+
+if test -f config/post_hook.sh
+then
+ . config/post_hook.sh
+fi
+
+echo "---"
+echo "Configured with the following tools:"
+echo " * `$LIBTOOLIZE --version | head -1`"
+echo " * `$ACLOCAL --version | head -1`"
+echo " * `$AUTOHEADER --version | head -1`"
+echo " * `$AUTOMAKE --version | head -1`"
+echo " * `$AUTOCONF --version | head -1`"
+echo "---"
View
666 config/config.rpath
@@ -0,0 +1,666 @@
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+# Copyright 1996-2007 Free Software Foundation, Inc.
+# Taken from GNU libtool, 2001
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+# than 256 bytes, otherwise the compiler driver will dump core. The only
+# known workaround is to choose shorter directory names for the build
+# directory and/or the installation directory.
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+ wl='-Wl,'
+else
+ case "$host_os" in
+ aix*)
+ wl='-Wl,'
+ ;;
+ darwin*)
+ case $cc_basename in
+ xlc*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | pw32* | os2*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ wl='-Wl,'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ wl='-Wl,'
+ ;;
+ newsos6)
+ ;;
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ icc* | ecc*)
+ wl='-Wl,'
+ ;;
+ pgcc | pgf77 | pgf90)
+ wl='-Wl,'
+ ;;
+ ccc*)
+ wl='-Wl,'
+ ;;
+ como)
+ wl='-lopt='
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ osf3* | osf4* | osf5*)
+ wl='-Wl,'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ wl='-Wl,'
+ ;;
+ sunos4*)
+ wl='-Qoption ld '
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ wl='-Wl,'
+ ;;
+ sysv4*MP*)
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ wl='-Wl,'
+ ;;
+ unicos*)
+ wl='-Wl,'
+ ;;
+ uts4*)
+ ;;
+ esac
+fi
+
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+ cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ # Unlike libtool, we use -rpath here, not --rpath, since the documented
+ # option of GNU ld is called -rpath, not --rpath.
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ case "$host_os" in
+ aix3* | aix4* | aix5*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we cannot use
+ # them.
+ ld_shlibs=no
+ ;;
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ cygwin* | mingw* | pw32*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ gnu* | linux* | k*bsd*-gnu)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ netbsd*)
+ ;;
+ solaris*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+ sunos4*)
+ hardcode_direct=yes
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ if test "$ld_shlibs" = no; then
+ hardcode_libdir_flag_spec=
+ fi
+else
+ case "$host_os" in
+ aix3*)
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ else
+ aix_use_runtimelinking=no
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+ fi
+ hardcode_direct=yes
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ fi
+ # Begin _LT_AC_SYS_LIBPATH_AIX.
+ echo 'int main () { return 0; }' > conftest.c
+ ${CC} ${LDFLAGS} conftest.c -o conftest
+ aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ fi
+ if test -z "$aix_libpath"; then
+ aix_libpath="/usr/lib:/lib"
+ fi
+ rm -f conftest.c conftest
+ # End _LT_AC_SYS_LIBPATH_AIX.
+ if test "$aix_use_runtimelinking" = yes; then
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ else
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ fi
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ libext=lib
+ ;;
+ darwin* | rhapsody*)
+ hardcode_direct=no
+ if test "$GCC" = yes ; then
+ :
+ else
+ case $cc_basename in
+ xlc*)
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+ fi
+ ;;
+ dgux*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+ freebsd2.2*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ freebsd2*)
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ freebsd* | dragonfly*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ hpux9*)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ hpux10*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+ hpux11*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ ;;
+ *)
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+ irix5* | irix6* | nonstopux*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ netbsd*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ newsos6)
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ osf3*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ osf4* | osf5*)
+ if test "$GCC" = yes; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ # Both cc and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+ solaris*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ sunos4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ sysv4)
+ case $host_vendor in
+ sni)
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ hardcode_direct=no
+ ;;
+ motorola)
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ ;;
+ sysv4.3*)
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ ld_shlibs=yes
+ fi
+ ;;
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator=':'
+ ;;
+ uts4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec= # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+ aix3*)
+ library_names_spec='$libname.a'
+ ;;
+ aix4* | aix5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ amigaos*)
+ library_names_spec='$libname.a'
+ ;;
+ beos*)
+ library_names_spec='$libname$shrext'
+ ;;
+ bsdi[45]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ cygwin* | mingw* | pw32*)
+ shrext=.dll
+ library_names_spec='$libname.dll.a $libname.lib'
+ ;;
+ darwin* | rhapsody*)
+ shrext=.dylib
+ library_names_spec='$libname$shrext'
+ ;;
+ dgux*)
+ library_names_spec='$libname$shrext'
+ ;;
+ freebsd1*)
+ ;;
+ freebsd* | dragonfly*)
+ case "$host_os" in
+ freebsd[123]*)
+ library_names_spec='$libname$shrext$versuffix' ;;
+ *)
+ library_names_spec='$libname$shrext' ;;
+ esac
+ ;;
+ gnu*)
+ library_names_spec='$libname$shrext'
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $host_cpu in
+ ia64*)
+ shrext=.so
+ ;;
+ hppa*64*)
+ shrext=.sl
+ ;;
+ *)
+ shrext=.sl
+ ;;
+ esac
+ library_names_spec='$libname$shrext'
+ ;;
+ interix[3-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ library_names_spec='$libname$shrext'
+ case "$host_os" in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
+ *) libsuff= shlibsuff= ;;
+ esac
+ ;;
+ esac
+ ;;
+ linux*oldld* | linux*aout* | linux*coff*)
+ ;;
+ linux* | k*bsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ knetbsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ netbsd*)
+ library_names_spec='$libname$shrext'
+ ;;
+ newsos6)
+ library_names_spec='$libname$shrext'
+ ;;
+ nto-qnx*)
+ library_names_spec='$libname$shrext'
+ ;;
+ openbsd*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ os2*)
+ libname_spec='$name'
+ shrext=.dll
+ library_names_spec='$libname.a'
+ ;;
+ osf3* | osf4* | osf5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sunos4*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ sysv4 | sysv4.3*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv4*MP*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ library_names_spec='$libname$shrext'
+ ;;
+ uts4*)
+ library_names_spec='$libname$shrext'
+ ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
View
86 configure.ac
@@ -0,0 +1,86 @@
+#
+# Copyright 2012 Couchbase, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+AC_PREREQ(2.60)
+m4_include([m4/version.m4])
+AC_INIT(libcouch, VERSION_NUMBER, support@couchbase.com)
+AC_CONFIG_SRCDIR([src/internal.h])
+AC_CONFIG_AUX_DIR(config)
+AC_USE_SYSTEM_EXTENSIONS
+AM_INIT_AUTOMAKE(subdir-objects)
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_LN_S
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AM_CONFIG_HEADER([src/config.h])
+AC_CONFIG_MACRO_DIR([m4])
+
+# the malloc tests seems to be broken for cross compilation.. ignore them
+ac_cv_func_malloc_0_nonnull=yes
+ac_cv_func_realloc_0_nonnull=yes
+
+COUCHBASE_GENERIC_COMPILER(c99)
+AM_CPPFLAGS="$AM_CPPFLAGS -I\${top_srcdir}/src"
+
+LIBCOUCHBASE_API_CURRENT=1
+LIBCOUCHBASE_API_REVISION=0
+LIBCOUCHBASE_API_AGE=0
+AC_SUBST(LIBCOUCHBASE_API_CURRENT)
+AC_SUBST(LIBCOUCHBASE_API_REVISION)
+AC_SUBST(LIBCOUCHBASE_API_AGE)
+
+AC_CHECK_HEADERS_ONCE([libcouchstore/couch_common.h])
+
+AS_IF([test "x$ac_cv_header_libcouchstore_couch_common_h" != "xyes"],
+ [AC_MSG_ERROR(Failed to locate libcouchstore/couch_common.h)])
+
+AH_TOP([
+#ifndef CONFIG_H
+#define CONFIG_H
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2012 Couchbase, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * This file is generated by running configure. Any changes you make to this
+ * file will be overwritten the next time you run configure. If you want to
+ * make permanent changes to the file you should edit configure.ac instead.
+ * All platform-specific includes should be placed inside config_static.h
+ * to keep the config.h as small as possible. That allows us for easily
+ * use another build systems with a poor support for automake (like Windows)
+ */
+])
+
+AH_BOTTOM([
+#endif
+])
+
+dnl ----------------------------------------------------------------------------
+AC_CONFIG_FILES([Makefile])
+AC_OUTPUT
View
183 include/libcbio/cbio.h
@@ -0,0 +1,183 @@
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2012 Couchbase, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIBCBIO_CBIO_H
+#define LIBCBIO_CBIO_H 1
+
+#include <libcbio/visibility.h>
+#include <libcbio/types.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ LIBCBIO_API
+ cbio_error_t cbio_open_handle(const char *name,
+ libcbio_open_mode_t mode,
+ libcbio_t *handle);
+
+ /**
+ * cbio_close_handle release all allocated resources for the handle
+ * and invalidates it.
+ */
+ LIBCBIO_API
+ void cbio_close_handle(libcbio_t handle);
+
+ LIBCBIO_API
+ off_t cbio_get_header_position(libcbio_t handle);
+
+
+ LIBCBIO_API
+ cbio_error_t cbio_create_empty_document(libcbio_t handle,
+ libcbio_document_t *doc);
+
+ /**
+ * This is a helper function to avoid having to call
+ * cbio_document_release() followed by
+ * cbio_create_empty_document(). Please note that you can
+ * <b>not</b> call cbio_document_reinitialize() on a document
+ * returned from cbio_get_document() (that have undefined behaviour,
+ * but will most likely crash your process)
+ */
+ LIBCBIO_API
+ void cbio_document_reinitialize(libcbio_document_t doc);
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_set_id(libcbio_document_t doc,
+ const void *id,
+ size_t nid,
+ int allocate);
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_set_meta(libcbio_document_t doc,
+ const void *meta,
+ size_t nmeta,
+ int allocate);
+
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_set_revision(libcbio_document_t doc, uint64_t revno);
+
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_set_deleted(libcbio_document_t doc, int deleted);
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_set_value(libcbio_document_t doc,
+ const void *value,
+ size_t nvalue,
+ int allocate);
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_set_content_type(libcbio_document_t doc,
+ uint8_t content_type);
+
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_get_id(libcbio_document_t doc,
+ const void **id,
+ size_t *nid);
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_get_meta(libcbio_document_t doc,
+ const void **meta,
+ size_t *nmeta);
+
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_get_revision(libcbio_document_t doc,
+ uint64_t *revno);
+
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_get_deleted(libcbio_document_t doc, int *deleted);
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_get_value(libcbio_document_t doc,
+ const void **value,
+ size_t *nvalue);
+
+ LIBCBIO_API
+ cbio_error_t cbio_document_get_content_type(libcbio_document_t doc,
+ uint8_t *content_type);
+
+ LIBCBIO_API
+ cbio_error_t cbio_get_document(libcbio_t handle,
+ const void *id,
+ size_t nid,
+ libcbio_document_t *doc);
+
+ LIBCBIO_API
+ cbio_error_t cbio_store_document(libcbio_t handle,
+ libcbio_document_t doc);
+
+ LIBCBIO_API
+ cbio_error_t cbio_store_documents(libcbio_t handle,
+ libcbio_document_t *doc,
+ size_t ndocs);
+
+ LIBCBIO_API
+ void cbio_document_release(libcbio_document_t doc);
+
+ LIBCBIO_API
+ cbio_error_t cbio_commit(libcbio_t handle);
+
+ LIBCBIO_API
+ const char *cbio_strerror(cbio_error_t err);
+
+
+
+
+ /**
+ * The callback function used by cbio_changes_since() to iterate
+ * through the documents.
+ *
+ * The document automatically released if the callback
+ * returns 0. A non-zero return value will preserve the document
+ * for future use (should be freed with cbio_document_release() by the
+ * caller)
+ *
+ * @param habdle the libcbio handle
+ * @param doc the current document
+ * @param ctx user context
+ * @return 0 or 1. See description above
+ */
+ typedef int (*cbio_changes_callback_fn)(libcbio_t handle,
+ libcbio_document_t doc,
+ void *ctx);
+
+ /**
+ * Iterate through the changes since sequence number `since`.
+ *
+ * @param handle libcbio handle
+ * @param since the sequence number to start iterating from
+ * @param callback the callback function used to iterate over all changes
+ * @param ctx client context (passed to the callback)
+ * @return CBIO_SUCCESS upon success
+ */
+ LIBCBIO_API
+ cbio_error_t cbio_changes_since(libcbio_t handle,
+ uint64_t since,
+ cbio_changes_callback_fn callback,
+ void *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
View
61 include/libcbio/types.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2012 Couchbase, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LIBCBIO_TYPES_H
+#define LIBCBIO_TYPES_H 1
+
+#ifndef LIBCBIO_CBIO_H
+#error "Include libcbio/cbio.h instead"
+#endif
+
+#include <sys/types.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ struct libcbio_st;
+ typedef struct libcbio_st *libcbio_t;
+
+ struct libcbio_document_st;
+ typedef struct libcbio_document_st *libcbio_document_t;
+
+ typedef enum {
+ CBIO_OPEN_RDONLY,
+ CBIO_OPEN_RW
+ } libcbio_open_mode_t;
+
+ typedef enum {
+ CBIO_SUCCESS = 0x00,
+ CBIO_ERROR_ENOMEM,
+ CBIO_ERROR_EIO,
+ CBIO_ERROR_EINVAL,
+ CBIO_ERROR_INTERNAL,
+ CBIO_ERROR_OPEN_FILE,
+ CBIO_ERROR_CORRUPT,
+ CBIO_ERROR_ENOENT,
+ CBIO_ERROR_NO_HEADER,
+ CBIO_ERROR_HEADER_VERSION,
+ CBIO_ERROR_CHECKSUM_FAIL
+ } cbio_error_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
View
42 include/libcbio/visibility.h
@@ -0,0 +1,42 @@
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2012 Couchbase, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef LIBCBIO_VISIBILITY_H
+#define LIBCBIO_VISIBILITY_H 1
+
+#if defined(LIBCBIO_INTERNAL)
+
+#ifdef __SUNPRO_C
+#define LIBCBIO_API __global
+#elif defined(HAVE_VISIBILITY) && HAVE_VISIBILITY
+#define LIBCBIO_API __attribute__ ((visibility("default")))
+#elif defined(_MSC_VER)
+#define LIBCBIO_API extern __declspec(dllexport)
+#else
+#define LIBCBIO_API
+#endif
+
+#else
+
+#ifdef _MSC_VER
+#define LIBCBIO_API extern __declspec(dllimport)
+#else
+#define LIBCBIO_API
+#endif
+
+#endif
+
+#endif
View
181 m4/couchbase.m4
@@ -0,0 +1,181 @@
+dnl Copyright (C) 2011 Couchbase, Inc
+dnl This file is free software; Couchbase, Inc
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([COUCHBASE_GENERIC_COMPILER], [
+ AC_ARG_ENABLE([warnings],
+ [AS_HELP_STRING([--enable-warnings],
+ [Enable more compiler warnings. @<:@default=off@:>@])],
+ [ac_cv_enable_warnings="yes"],
+ [ac_cv_enable_warnings="no"])
+
+ AC_ARG_ENABLE([werror],
+ [AS_HELP_STRING([--enable-werror],
+ [Treat warnings as errors. @<:@default=off@:>@])],
+ [ac_cv_enable_werror="yes"],
+ [ac_cv_enable_werror="no"])
+
+ AC_ARG_ENABLE([debug],
+ [AS_HELP_STRING([--enable-debug],
+ [Enable debug build (non-optimized). @<:@default=off@:>@])],
+ [ac_cv_enable_debug="yes"],
+ [ac_cv_enable_debug="no"])
+
+ C_LANGUAGE_SPEC=c99
+ m4_foreach([arg], [$*],
+ [
+ m4_case(arg, [c89], [C_LANGUAGE_SPEC=c89],
+ [c99], [C_LANGUAGE_SPEC=c99],
+ [cxx], [NEED_CPP=yes])
+ ])
+
+ GCC_NO_WERROR="-Wno-error"
+ GCC_WERROR="-Werror"
+ GCC_C_OPTIMIZE="-O3"
+ GCC_CXX_OPTIMIZE="-O3"
+ GCC_C_DEBUG="-O0 -g3"
+ GCC_CXX_DEBUG="-O0 -g3"
+ GCC_VISIBILITY="-DHAVE_VISIBILITY=1 -fvisibility=hidden"
+ GCC_CPPFLAGS="-pipe"
+ GCC_CFLAGS="-std=gnu99"
+ GCC_CXXFLAGS=""
+ GCC_C89=-std=c89
+ GCC_C99=-std=gnu99
+ GCC_LDFLAGS=""
+ GCC_CPP_WARNINGS="-Wall -pedantic -Wundef -Wshadow -fdiagnostics-show-option -Wformat -fno-strict-aliasing -Wno-strict-aliasing -Wextra"
+ GCC_C_COMPILER_WARNINGS="-Wstrict-prototypes -Wmissing-prototypes -Wredundant-decls -Wmissing-declarations -Wcast-align"
+ GCC_CXX_COMPILER_WARNINGS="-std=gnu++98 -Woverloaded-virtual -Wnon-virtual-dtor -Wctor-dtor-privacy -Wno-long-long -Wno-redundant-decls"
+
+ SPRO_NO_WERROR="-errwarn=%none"
+ SPRO_WERROR="-errwarn=%all"
+ SPRO_C_OPTIMIZE="-O -xbuiltin=%default"
+ SPRO_CXX_OPTIMIZE="-O -xbuiltin=%default"
+ SPRO_C_DEBUG="-g3 -traceback=common -xcheck=%all"
+ SPRO_CXX_DEBUG="-g3 -traceback=common -xcheck=%all"
+ SPRO_VISIBILITY="-xldscope=hidden"
+ SPRO_CPPFLAGS="-mt=yes -D_THREAD_SAFE"
+ SPRO_CXXFLAGS="-xlang=c99 -compat=5 -library=stlport4 -template=no%extdef"
+ SPRO_C89="-Xt -xc99=none"
+ SPRO_C99="-D_XOPEN_SOURCE=600 -xc99=all"
+ SPRO_CFLAGS=""
+ SPRO_CPP_WARNINGS="-errhdr=%user -errfmt=error -errshort=full -errtags "
+ SPRO_C_COMPILER_WARNINGS="-v"
+ SPRO_CXX_COMPILER_WARNINGS="+w +w2"
+ SPRO_LDFLAGS="-mt=yes"
+
+ AC_CHECK_DECL([__SUNPRO_C], [SUNCC="yes"], [SUNCC="no"])
+ AC_CHECK_DECL([__GNUC__], [GCC="yes"], [GCC="no"])
+
+ AS_IF([test "x$GCC" = "xyes"],
+ [
+ AM_CPPFLAGS="$AM_CPPFLAGS $GCC_CPPFLAGS"
+ AM_CFLAGS="$AM_CPPFLAGS $GCC_CFLAGS"
+ AM_CXXFLAGS="$AM_CPPFLAGS $GCC_CXXFLAGS"
+ AS_IF(test "$C_LANGUAGE_SPEC" = c89,
+ [AM_CFLAGS="$AM_CPPFLAGS $GCC_C89"],
+ AS_IF(test "$C_LANGUAGE_SPEC" = c99,
+ [AM_CFLAGS="$AM_CPPFLAGS $GCC_C99"])
+ )
+ AM_LDFLAGS="$AM_LDFLAGS $GCC_LDFLAGS"
+ NO_WERROR="$GCC_NO_WERROR"
+ WERROR="$GCC_WERROR"
+ C_OPTIMIZE="$GCC_C_OPTIMIZE"
+ CXX_OPTIMIZE="$GCC_CXX_OPTIMIZE"
+ C_DEBUG="$GCC_C_DEBUG"
+ CXX_DEBUG="$GCC_CXX_DEBUG"
+ VISIBILITY="$GCC_VISIBILITY"
+ CPP_WARNINGS="$GCC_CPP_WARNINGS"
+ C_COMPILER_WARNINGS="$GCC_C_COMPILER_WARNINGS"
+ CXX_COMPILER_WARNINGS="$GCC_CXX_COMPILER_WARNINGS"
+ ])
+
+ AS_IF([test "x$SUNCC" = "xyes"],
+ [
+ AM_CPPFLAGS="$AM_CPPFLAGS $SPRO_CPPFLAGS"
+ AM_CFLAGS="$AM_CPPFLAGS $SPRO_CFLAGS"
+ AM_CXXFLAGS="$AM_CPPFLAGS $SPRO_CXXFLAGS"
+ AS_IF(test "$C_LANGUAGE_SPEC" = c89,
+ [AM_CFLAGS="$AM_CPPFLAGS $SPRO_C89"],
+ AS_IF(test "$C_LANGUAGE_SPEC" = c99,
+ [AM_CFLAGS="$AM_CPPFLAGS $SPRO_C99"])
+ )
+ AM_LDFLAGS="$AM_LDFLAGS $SPRO_LDFLAGS"
+ NO_WERROR="$SPRO_NO_WERROR"
+ WERROR="$SPRO_WERROR"
+ C_OPTIMIZE="$SPRO_C_OPTIMIZE"
+ CXX_OPTIMIZE="$SPRO_CXX_OPTIMIZE"
+ C_DEBUG="$SPRO_C_DEBUG"
+ CXX_DEBUG="$SPRO_CXX_DEBUG"
+ VISIBILITY="$SPRO_VISIBILITY"
+ CPP_WARNINGS="$SPRO_CPP_WARNINGS"
+ C_COMPILER_WARNINGS="$SPRO_C_COMPILER_WARNINGS"
+ CXX_COMPILER_WARNINGS="$SPRO_CXX_COMPILER_WARNINGS"
+ ])
+
+ AM_CPPFLAGS="$AM_CPPFLAGS -I\${top_srcdir}/include $VISIBILITY"
+ AM_LDFLAGS="$AM_LDFLAGS $VISIBILITY"
+
+
+ AS_IF([test "$ac_cv_enable_warnings" = "yes"],
+ [AM_CPPFLAGS="$AM_CPPFLAGS $CPP_WARNINGS"
+ AM_CFLAGS="$AM_CFLAGS $C_COMPILER_WARNINGS"
+ AM_CXXFLAGS="$AM_CXXFLAGS $CXX_COMPILER_WARNINGS"])
+
+ AS_IF([test "$ac_cv_enable_werror" = "yes"],
+ [
+ AM_CPPFLAGS="$AM_CPPFLAGS $WERROR"
+ ])
+
+ AS_IF([test "$ac_cv_enable_debug" = "yes"],
+ [
+ AM_CFLAGS="$AM_CFLAGS $C_DEBUG"
+ AM_CXXFLAGS="$AM_CXXFLAGS $CXX_DEBUG"
+ ],
+ [
+ AM_CFLAGS="$AM_CFLAGS $C_OPTIMIZE"
+ AM_CXXFLAGS="$AM_CXXFLAGS $CXX_OPTIMIZE"
+ ])
+
+ dnl Export GCC variables
+ AC_SUBST(GCC_NO_WERROR)
+ AC_SUBST(GCC_WERROR)
+ AC_SUBST(GCC_C_OPTIMIZE)
+ AC_SUBST(GCC_CXX_OPTIMIZE)
+ AC_SUBST(GCC_C_DEBUG)
+ AC_SUBST(GCC_CXX_DEBUG)
+ AC_SUBST(GCC_VISIBILITY)
+ AC_SUBST(GCC_CPPFLAGS)
+ AC_SUBST(GCC_CPP_WARNINGS)
+ AC_SUBST(GCC_C_COMPILER_WARNINGS)
+ AC_SUBST(GCC_CXX_COMPILER_WARNINGS)
+
+ dnl Export Sun Studio variables
+ AC_SUBST(SPRO_NO_WERROR)
+ AC_SUBST(SPRO_WERROR)
+ AC_SUBST(SPRO_C_OPTIMIZE)
+ AC_SUBST(SPRO_CXX_OPTIMIZE)
+ AC_SUBST(SPRO_C_DEBUG)
+ AC_SUBST(SPRO_CXX_DEBUG)
+ AC_SUBST(SPRO_VISIBILITY)
+ AC_SUBST(SPRO_CPPFLAGS)
+ AC_SUBST(SPRO_CPP_WARNINGS)
+ AC_SUBST(SPRO_C_COMPILER_WARNINGS)
+ AC_SUBST(SPRO_CXX_COMPILER_WARNINGS)
+
+ dnl Export the ones we're using
+ AC_SUBST(NO_WERROR)
+ AC_SUBST(WERROR)
+ AC_SUBST(C_OPTIMIZE)
+ AC_SUBST(CXX_OPTIMIZE)
+ AC_SUBST(C_DEBUG)
+ AC_SUBST(CXX_DEBUG)
+ AC_SUBST(VISIBILITY)
+ AC_SUBST(CPP_WARNINGS)
+ AC_SUBST(C_COMPILER_WARNINGS)
+ AC_SUBST(CXX_COMPILER_WARNINGS)
+ AC_SUBST(AM_LDFLAGS)
+ AC_SUBST(AM_CPPFLAGS)
+ AC_SUBST(AM_CFLAGS)
+ AC_SUBST(AM_CXXFLAGS)
+])
View
300 src/document.c
@@ -0,0 +1,300 @@
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2012 Couchbase, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "internal.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+LIBCBIO_API
+void cbio_document_release(libcbio_document_t doc)
+{
+ cbio_document_reinitialize(doc);
+ free(doc);
+}
+
+LIBCBIO_API
+cbio_error_t cbio_create_empty_document(libcbio_t handle,
+ libcbio_document_t *doc)
+{
+ libcbio_document_t ret = calloc(1, sizeof(*ret));
+ (void)handle;
+ *doc = ret;
+ if (*doc != NULL) {
+ ret->scratch = 1;
+ return CBIO_SUCCESS;
+ }
+
+ return CBIO_ERROR_ENOMEM;
+}
+
+LIBCBIO_API
+void cbio_document_reinitialize(libcbio_document_t doc)
+{
+ if (doc->scratch == 1) {
+ free(doc->info);
+ free(doc->doc);
+ } else {
+ if (doc->info != NULL) {
+ couchstore_free_docinfo(doc->info);
+ }
+ if (doc->doc) {
+ couchstore_free_document(doc->doc);
+ }
+ }
+ free(doc->tmp_alloc_id);
+ free(doc->tmp_alloc_meta);
+ free(doc->tmp_alloc_bp);
+
+ doc->info = NULL;
+ doc->doc = NULL;
+ doc->tmp_alloc_id = doc->tmp_alloc_meta = doc->tmp_alloc_bp;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_document_set_id(libcbio_document_t doc,
+ const void *id,
+ size_t nid,
+ int allocate)
+{
+ /* The couchstore API got the const wrong here.. */
+ void *ptr = (void *)id;
+ assert(doc);
+
+ if (doc->doc == NULL) {
+ if ((doc->doc = calloc(1, sizeof(*doc->doc))) == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+ }
+
+ if (doc->info == NULL) {
+ if ((doc->info = calloc(1, sizeof(*doc->info))) == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+ }
+
+ if (allocate) {
+ free(doc->tmp_alloc_id);
+ if ((doc->tmp_alloc_id = ptr = malloc(nid)) == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+ memcpy(ptr, id, nid);
+ }
+
+ doc->info->id.buf = doc->doc->id.buf = ptr;
+ doc->info->id.size = doc->doc->id.size = nid;
+
+ return CBIO_SUCCESS;
+}
+
+
+LIBCBIO_API
+cbio_error_t cbio_document_set_meta(libcbio_document_t doc,
+ const void *meta,
+ size_t nmeta,
+ int allocate)
+{
+ /* The couchstore API got the const wrong here.. */
+ void *ptr = (void *)meta;
+ assert(doc);
+
+ if (doc->info == NULL) {
+ if ((doc->info = calloc(1, sizeof(*doc->info))) == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+ }
+
+ if (allocate) {
+ free(doc->tmp_alloc_meta);
+ if ((doc->tmp_alloc_meta = ptr = malloc(nmeta)) == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+ memcpy(ptr, meta, nmeta);
+ }
+
+ doc->info->rev_meta.buf = ptr;
+ doc->info->rev_meta.size = nmeta;
+
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_document_set_revision(libcbio_document_t doc, uint64_t revno)
+{
+ assert(doc);
+
+ if (doc->info == NULL) {
+ if ((doc->info = calloc(1, sizeof(*doc->info))) == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+ }
+
+ doc->info->rev_seq = revno;
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_document_set_deleted(libcbio_document_t doc, int deleted)
+{
+ assert(doc);
+
+ if (doc->info == NULL) {
+ if ((doc->info = calloc(1, sizeof(*doc->info))) == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+ }
+
+ doc->info->deleted = deleted;
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_document_set_value(libcbio_document_t doc,
+ const void *value,
+ size_t nvalue,
+ int allocate)
+{
+ /* The couchstore API got the const wrong here.. */
+ void *ptr = (void *)value;
+ assert(doc);
+
+ if (doc->doc == NULL) {
+ if ((doc->doc = calloc(1, sizeof(*doc->doc))) == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+ }
+
+ if (doc->info == NULL) {
+ if ((doc->info = calloc(1, sizeof(*doc->info))) == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+ }
+
+ if (allocate) {
+ free(doc->tmp_alloc_bp);
+ if ((doc->tmp_alloc_bp = ptr = malloc(nvalue)) == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+ memcpy(ptr, value, nvalue);
+ }
+
+ doc->doc->data.buf = ptr;
+ doc->info->size = doc->doc->data.size = nvalue;
+
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_document_set_content_type(libcbio_document_t doc,
+ uint8_t content_type)
+{
+ assert(doc);
+
+ if (doc->info == NULL) {
+ if ((doc->info = calloc(1, sizeof(*doc->info))) == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+ }
+
+ /* @todo verify the content type */
+ doc->info->content_meta = content_type;
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_document_get_id(libcbio_document_t doc,
+ const void **id,
+ size_t *nid)
+{
+ if (doc == NULL || (doc->doc == NULL && doc->info == NULL)) {
+ return CBIO_ERROR_EINVAL;
+ }
+
+ if (doc->doc != NULL) {
+ *id = doc->doc->id.buf;
+ *nid = doc->doc->id.size;
+ } else {
+ *id = doc->info->id.buf;
+ *nid = doc->info->id.size;
+ }
+
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_document_get_meta(libcbio_document_t doc,
+ const void **meta,
+ size_t *nmeta)
+{
+ if (doc == NULL || doc->info == NULL) {
+ return CBIO_ERROR_EINVAL;
+ }
+
+ *meta = doc->info->rev_meta.buf;
+ *nmeta = doc->info->rev_meta.size;
+
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_document_get_revision(libcbio_document_t doc, uint64_t *revno)
+{
+ if (doc == NULL || doc->info == NULL) {
+ return CBIO_ERROR_EINVAL;
+ }
+
+ *revno = doc->info->rev_seq;
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_document_get_deleted(libcbio_document_t doc, int *deleted)
+{
+ if (doc == NULL || doc->info == NULL) {
+ return CBIO_ERROR_EINVAL;
+ }
+
+ *deleted = doc->info->deleted;
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_document_get_value(libcbio_document_t doc,
+ const void **value,
+ size_t *nvalue)
+{
+ if (doc == NULL || doc->doc == NULL) {
+ return CBIO_ERROR_EINVAL;
+ }
+
+ *value = doc->doc->data.buf;
+ *nvalue = doc->doc->data.size;
+
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_document_get_content_type(libcbio_document_t doc,
+ uint8_t *content_type)
+{
+ if (doc == NULL || doc->info == NULL) {
+ return CBIO_ERROR_EINVAL;
+ }
+
+ *content_type = doc->info->content_meta;
+ return CBIO_SUCCESS;
+}
View
84 src/error.c
@@ -0,0 +1,84 @@
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2012 Couchbase, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "internal.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+cbio_error_t cbio_remap_error(couchstore_error_t in)
+{
+ switch (in) {
+ case COUCHSTORE_SUCCESS:
+ return CBIO_SUCCESS;
+ case COUCHSTORE_ERROR_OPEN_FILE:
+ return CBIO_ERROR_OPEN_FILE;
+ case COUCHSTORE_ERROR_CORRUPT:
+ return CBIO_ERROR_CORRUPT;
+ case COUCHSTORE_ERROR_ALLOC_FAIL:
+ return CBIO_ERROR_ENOMEM;
+ case COUCHSTORE_ERROR_READ:
+ return CBIO_ERROR_EIO;
+ case COUCHSTORE_ERROR_DOC_NOT_FOUND:
+ return CBIO_ERROR_ENOENT;
+ case COUCHSTORE_ERROR_NO_HEADER:
+ return CBIO_ERROR_NO_HEADER;
+ case COUCHSTORE_ERROR_WRITE:
+ return CBIO_ERROR_EIO;
+ case COUCHSTORE_ERROR_HEADER_VERSION:
+ return CBIO_ERROR_HEADER_VERSION;
+ case COUCHSTORE_ERROR_CHECKSUM_FAIL:
+ return CBIO_ERROR_CHECKSUM_FAIL;
+ case COUCHSTORE_ERROR_INVALID_ARGUMENTS:
+ return CBIO_ERROR_EINVAL;
+ case COUCHSTORE_ERROR_NO_SUCH_FILE:
+ return CBIO_ERROR_ENOENT;
+ default:
+ return CBIO_ERROR_INTERNAL;
+
+ }
+}
+
+LIBCBIO_API
+const char *cbio_strerror(cbio_error_t err)
+{
+ switch (err) {
+ case CBIO_SUCCESS:
+ return "success";
+ case CBIO_ERROR_ENOMEM:
+ return "allocation failed";
+ case CBIO_ERROR_EIO:
+ return "io error";
+ case CBIO_ERROR_EINVAL:
+ return "invalid arguments";
+ case CBIO_ERROR_OPEN_FILE:
+ return "failed to open file";
+ case CBIO_ERROR_CORRUPT:
+ return "file corrupt";
+ case CBIO_ERROR_ENOENT:
+ return "no entry";
+ case CBIO_ERROR_NO_HEADER:
+ return "no header";
+ case CBIO_ERROR_HEADER_VERSION:
+ return "illegal header version";
+ case CBIO_ERROR_CHECKSUM_FAIL:
+ return "checksum fail";
+ case CBIO_ERROR_INTERNAL:
+ default:
+ return "Internal error";
+ }
+}
View
195 src/instance.c
@@ -0,0 +1,195 @@
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2012 Couchbase, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "internal.h"
+
+#include <stdlib.h>
+
+LIBCBIO_API
+cbio_error_t cbio_open_handle(const char *name,
+ libcbio_open_mode_t mode,
+ libcbio_t *handle)
+{
+ couchstore_error_t err;
+ uint64_t flags;
+ libcbio_t ret;
+
+ ret = calloc(1, sizeof(*ret));
+ if (ret == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+
+ ret->mode = mode;
+ if (mode == CBIO_OPEN_RDONLY) {
+ flags = COUCHSTORE_OPEN_FLAG_RDONLY;
+ } else {
+ flags = COUCHSTORE_OPEN_FLAG_CREATE;
+ }
+
+ err = couchstore_open_db(name, flags, &ret->couchstore_handle);
+ if (err != COUCHSTORE_SUCCESS) {
+ free(ret);
+ return cbio_remap_error(err);
+ }
+
+ *handle = ret;
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+void cbio_close_handle(libcbio_t handle)
+{
+ if (handle->mode != CBIO_OPEN_RDONLY) {
+ (void)cbio_commit(handle);
+ }
+
+ couchstore_close_db(handle->couchstore_handle);
+ free(handle);
+}
+
+LIBCBIO_API
+off_t cbio_get_header_position(libcbio_t handle)
+{
+ return (off_t)couchstore_get_header_position(handle->couchstore_handle);
+}
+
+LIBCBIO_API
+cbio_error_t cbio_get_document(libcbio_t handle,
+ const void *id,
+ size_t nid,
+ libcbio_document_t *doc)
+{
+ libcbio_document_t ret = calloc(1, sizeof(*ret));
+ couchstore_error_t err;
+
+ if (ret == NULL) {
+ return CBIO_ERROR_ENOMEM;
+ }
+
+ err = couchstore_docinfo_by_id(handle->couchstore_handle, id, nid, &ret->info);
+ if (err != COUCHSTORE_SUCCESS) {
+ cbio_document_release(ret);
+ return cbio_remap_error(err);
+ }
+
+ err = couchstore_open_doc_with_docinfo(handle->couchstore_handle,
+ ret->info,
+ &ret->doc, 0);
+ if (err != COUCHSTORE_SUCCESS || ret->info->deleted) {
+ cbio_document_release(ret);
+ if (err == COUCHSTORE_SUCCESS) {
+ return CBIO_ERROR_ENOENT;
+ }
+ return cbio_remap_error(err);
+ }
+
+ *doc = ret;
+ return CBIO_SUCCESS;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_store_document(libcbio_t handle,
+ libcbio_document_t doc)
+{
+ return cbio_store_documents(handle, &doc, 1);
+}
+
+LIBCBIO_API
+cbio_error_t cbio_store_documents(libcbio_t handle,
+ libcbio_document_t *doc,
+ size_t ndocs)
+{
+ Doc **docs;
+ DocInfo **info;
+ size_t ii;
+ couchstore_error_t err;
+
+ if (handle->mode == CBIO_OPEN_RDONLY) {
+ return CBIO_ERROR_EINVAL;
+ }
+
+ docs = calloc(ndocs, sizeof(Doc *));
+ info = calloc(ndocs, sizeof(DocInfo *));
+ if (docs == NULL || info == NULL) {
+ free(docs);
+ free(info);
+ return CBIO_ERROR_ENOMEM;
+ }
+
+ for (ii = 0; ii < ndocs; ++ii) {
+ docs[ii] = doc[ii]->doc;
+ info[ii] = doc[ii]->info;
+ }
+
+ err = couchstore_save_documents(handle->couchstore_handle, docs, info,
+ ndocs, 0);
+ free(docs);
+ free(info);
+
+ return cbio_remap_error(err);
+}
+
+LIBCBIO_API
+cbio_error_t cbio_commit(libcbio_t handle)
+{
+ if (handle->mode == CBIO_OPEN_RDONLY) {
+ return CBIO_ERROR_EINVAL;
+ }
+ return cbio_remap_error(couchstore_commit(handle->couchstore_handle));
+}
+
+struct cbio_wrap_ctx {
+ cbio_changes_callback_fn callback;
+ libcbio_t handle;
+ void *ctx;
+};
+
+static int couchstore_changes_callback(Db *db, DocInfo *docinfo, void *ctx)
+{
+ (void)db;
+ int ret = 0;
+ libcbio_document_t doc = calloc(1, sizeof(*doc));
+ if (doc) {
+ struct cbio_wrap_ctx *uctx = ctx;
+ doc->info = docinfo;
+
+ ret = uctx->callback(uctx->handle, doc, uctx->ctx);
+ if (ret == 0) {
+ free(doc);
+ }
+ }
+
+ return ret;
+}
+
+LIBCBIO_API
+cbio_error_t cbio_changes_since(libcbio_t handle,
+ uint64_t since,
+ cbio_changes_callback_fn callback,
+ void *ctx)
+{
+ struct cbio_wrap_ctx uctx = { .callback = callback,
+ .handle = handle,
+ .ctx = ctx
+ };
+ couchstore_error_t err;
+ err = couchstore_changes_since(handle->couchstore_handle,
+ since, 0,
+ couchstore_changes_callback,
+ &uctx);
+
+ return cbio_remap_error(err);
+}
View
48 src/internal.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2012 Couchbase, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef LIBCBIO_INTERNAL
+#error "This is a private interface to libcbio!"
+#endif
+
+#include <libcbio/cbio.h>
+#include <libcouchstore/couch_db.h>
+
+#ifndef INTERNAL_H
+#define INTERNAL_H 1
+
+#ifdef __cplusplus
+#error "What are you thinking?? this is a C project"
+#endif
+
+struct libcbio_st {
+ Db *couchstore_handle;
+ libcbio_open_mode_t mode;
+};
+
+struct libcbio_document_st {
+ Doc *doc;
+ DocInfo *info;
+
+ void *tmp_alloc_id;
+ void *tmp_alloc_meta;
+ void *tmp_alloc_bp;
+ int scratch;
+};
+
+cbio_error_t cbio_remap_error(couchstore_error_t in);
+
+#endif
View
604 tests/testapp.c
@@ -0,0 +1,604 @@
+/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright 2012 Couchbase, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <libcbio/cbio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+void *blob;
+size_t blobsize;
+
+const char *dbfile = "testcase.cbio";
+
+typedef int (*testcase)(void);
+struct test {
+ const char *name;
+ testcase func;
+};
+
+int verbose;
+int core;
+
+static void report(const char *fmt, ...)
+{
+ if (verbose) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, " ");
+ fflush(stderr);
+ }
+
+ if (core) {
+ abort();
+ }
+}
+
+static int open_empty_filename(void)
+{
+ libcbio_t handle;
+ cbio_error_t err = cbio_open_handle("", CBIO_OPEN_RDONLY, &handle);
+ if (err != CBIO_ERROR_ENOENT) {
+ report("Expected open of \"\" to fail, but it \"%s\" ",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ return 0;
+}
+
+static int create_database(void)
+{
+ libcbio_t handle;
+ cbio_error_t err = cbio_open_handle(dbfile,
+ CBIO_OPEN_RDONLY,
+ &handle);
+ if (err != CBIO_ERROR_ENOENT) {
+ report("Expected open of \"%s\" to fail, but it \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_open_handle(dbfile, CBIO_OPEN_RW, &handle);
+ if (err != CBIO_SUCCESS) {
+ report("Expected open of \"%s\" to succeed, but it \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ cbio_close_handle(handle);
+ err = cbio_open_handle(dbfile, CBIO_OPEN_RDONLY, &handle);
+ if (err != CBIO_SUCCESS) {
+ report("Expected open of \"%s\" to succeed after I created it, "
+ "but it \"%s\"", cbio_strerror(err));
+ return 1;
+ }
+ cbio_close_handle(handle);
+
+ return 0;
+}
+
+static int get_miss(void)
+{
+ libcbio_t handle;
+ libcbio_document_t doc;
+ cbio_error_t err;
+
+ err = cbio_open_handle(dbfile, CBIO_OPEN_RW, &handle);
+ if (err != CBIO_SUCCESS) {
+ report("Expected open of \"%s\" to succeed, but it \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_get_document(handle, "hi-there", sizeof("hi-there"), &doc);
+ if (err != CBIO_ERROR_ENOENT) {
+ report("I did not expect to find \"hi-there\" in the database"
+ ", but I got \"%s\"", cbio_strerror(err));
+ return 1;
+ }
+
+ cbio_close_handle(handle);
+ return 0;
+}
+
+static int store_document(void)
+{
+ libcbio_t handle;
+ libcbio_document_t doc;
+ cbio_error_t err;
+
+ err = cbio_open_handle(dbfile, CBIO_OPEN_RW, &handle);
+ if (err != CBIO_SUCCESS) {
+ report("Expected open of \"%s\" to succeed, but it \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_create_empty_document(handle, &doc);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to create an empty document: \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_document_set_id(doc, "hi-there", sizeof("hi-there"), 0);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to set document id \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_document_set_revision(doc, 0);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to set revision \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_document_set_value(doc, "hei", 3, 0);
+ if (err != CBIO_SUCCESS) {
+ report("Failed ot set value \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_store_document(handle, doc);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to store document \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ cbio_commit(handle);
+ cbio_document_release(doc);
+ cbio_close_handle(handle);
+ return 0;
+}
+
+static int get_hit(void)
+{
+ libcbio_t handle;
+ libcbio_document_t doc;
+ cbio_error_t err;
+
+ if (get_miss() != 0 || store_document() != 0) {
+ /* Error already reported */
+ return 1;
+ }
+
+ err = cbio_open_handle(dbfile, CBIO_OPEN_RDONLY, &handle);
+ if (err != CBIO_SUCCESS) {
+ report("Expected open of \"%s\" to succeed, but it \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_get_document(handle, "hi-there", sizeof("hi-there"), &doc);
+ if (err != CBIO_SUCCESS) {
+ report("Expected to find the document, but I got \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ cbio_document_release(doc);
+ cbio_close_handle(handle);
+ return 0;
+}
+
+static int delete_document(void)
+{
+ libcbio_t handle;
+ libcbio_document_t doc;
+ cbio_error_t err;
+
+ if (get_miss() != 0 || store_document() != 0) {
+ /* Error already reported */
+ return 1;
+ }
+
+ err = cbio_open_handle(dbfile, CBIO_OPEN_RW, &handle);
+ if (err != CBIO_SUCCESS) {
+ report("Expected open of \"%s\" to succeed, but it \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_create_empty_document(handle, &doc);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to create an empty document: \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_document_set_id(doc, "hi-there", sizeof("hi-there"), 0);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to set document id \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_document_set_revision(doc, 1);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to set revision \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_document_set_deleted(doc, 1);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to set deleted \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_store_document(handle, doc);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to store document \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ cbio_commit(handle);
+ cbio_document_release(doc);
+ cbio_close_handle(handle);
+
+ return 0;
+}
+
+static int delete_nonexistent_document(void)
+{
+ libcbio_t handle;
+ libcbio_document_t doc;
+ cbio_error_t err;
+
+ err = cbio_open_handle(dbfile, CBIO_OPEN_RW, &handle);
+ if (err != CBIO_SUCCESS) {
+ report("Expected open of \"%s\" to succeed, but it \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_create_empty_document(handle, &doc);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to create an empty document: \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_document_set_id(doc, "wtf", sizeof("wtf"), 0);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to set document id \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_document_set_revision(doc, 1);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to set revision \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_document_set_deleted(doc, 1);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to set deleted \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_store_document(handle, doc);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to store document \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ cbio_commit(handle);
+ cbio_document_release(doc);
+ cbio_close_handle(handle);
+ return 0;
+}
+
+static int get_deleted_document(void)
+{
+ return (delete_document() != 0 || get_miss() != 0) ? 1 : 0;
+}
+
+static int create_random_doc(libcbio_t handle, int idx, libcbio_document_t *doc)
+{
+ cbio_error_t err;
+
+ err = cbio_create_empty_document(handle, doc);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to create an empty document: \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ char id[20];
+ int len = snprintf(id, sizeof(id), "%d", idx);
+ err = cbio_document_set_id(*doc, id, len, 1);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to set document id \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_document_set_revision(*doc, 1);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to set revision \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ err = cbio_document_set_value(*doc, blob, random() % blobsize, 0);
+ if (err != CBIO_SUCCESS) {
+ report("Failed ot set value \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ return 0;
+}
+
+const int maxdoc = 100000;
+
+static int bulk_store_documents(void)
+{
+ const int chunksize = 1000;
+
+ cbio_error_t err;
+ libcbio_document_t *docs = calloc(chunksize, sizeof(libcbio_document_t));
+ blobsize = 8192;
+ blob = malloc(blobsize);
+
+ if (docs == NULL || blob == NULL) {
+ report("Failed to allocate memory to keep track of documents");
+ return 1;
+ }
+ libcbio_t handle;
+
+ err = cbio_open_handle(dbfile, CBIO_OPEN_RW, &handle);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to open handle \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ srand(0);
+
+ int total = 0;
+ do {
+ int currtx = random() % chunksize;
+
+ if (total + currtx > maxdoc) {
+ currtx = maxdoc - total;
+ }
+
+ for (int ii = 0; ii < currtx; ++ii) {
+ libcbio_document_t doc;
+ if (create_random_doc(handle, total + ii, &doc)) {
+ report("Failed to create a document");
+ return 1;
+ }
+ docs[ii] = doc;
+ }
+
+ fprintf(stdout, "\rStoring %d of %d..", currtx, total);
+ fflush(stdout);
+ err = cbio_store_documents(handle, docs, currtx);
+ if (err != CBIO_SUCCESS) {
+ report("Failed to store document \"%s\"",
+ cbio_strerror(err));
+ return 1;
+ }
+
+ cbio_commit(handle);
+ total += currtx;
+
+ for (int ii = 0; ii < currtx; ++ii) {
+ cbio_document_release(docs[ii]);
+ }
+ } while (total < maxdoc);
+
+ fprintf(stdout, "\r \r");
+ for (int ii = 0; ii < maxdoc; ++ii) {
+ libcbio_document_t doc;
+ char id[20];
+ int len = snprintf(id, sizeof(id), "%d", ii);
+ fprintf(stdout, "\rVerify %d....", ii);
+ err = cbio_get_document(handle, id, len, &doc);
+ if (err != CBIO_SUCCESS) {
+ report("Expected to find the document \"%s\", but I got \"%s\"",
+ id, cbio_strerror(err));
+ /* return 1; */
+ } else {
+ cbio_document_release(doc);
+ }
+ }
+ fprintf(stdout, "\r \r");
+
+ cbio_close_handle(handle);
+
+ free(docs);
+ return 0;
+}
+
+static int count_callback(libcbio_t handle, libcbio_document_t doc, void *ctx)