You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by be...@apache.org on 2014/02/16 01:17:17 UTC

[1/2] couch commit: updated refs/heads/1994-merge-rcouch to f9e3095

Repository: couchdb-couch
Updated Branches:
  refs/heads/1994-merge-rcouch 64d7f590f -> f9e309519


useless files


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/bfd6cbb5
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/bfd6cbb5
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/bfd6cbb5

Branch: refs/heads/1994-merge-rcouch
Commit: bfd6cbb5268d1d6b7e57b0b4c07dbf5eb1fcbfaa
Parents: 64d7f59
Author: benoitc <bc...@gmail.com>
Authored: Sun Feb 16 00:24:38 2014 +0100
Committer: benoitc <bc...@gmail.com>
Committed: Sun Feb 16 00:24:38 2014 +0100

----------------------------------------------------------------------
 priv/couch_ejson_compare/couch_ejson_compare.c | 457 --------------------
 priv/couch_ejson_compare/erl_nif_compat.h      | 128 ------
 priv/icu_driver/couch_icu_driver.c             | 189 --------
 3 files changed, 774 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/bfd6cbb5/priv/couch_ejson_compare/couch_ejson_compare.c
----------------------------------------------------------------------
diff --git a/priv/couch_ejson_compare/couch_ejson_compare.c b/priv/couch_ejson_compare/couch_ejson_compare.c
deleted file mode 100644
index df68c2a..0000000
--- a/priv/couch_ejson_compare/couch_ejson_compare.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/**
- * 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 <stdio.h>
-#include <assert.h>
-#include "erl_nif_compat.h"
-#include "unicode/ucol.h"
-#include "unicode/ucasemap.h"
-
-#define MAX_DEPTH 10
-
-#if (ERL_NIF_MAJOR_VERSION > 2) || \
-    (ERL_NIF_MAJOR_VERSION == 2 && ERL_NIF_MINOR_VERSION >= 3)
-/* OTP R15B or higher */
-#define term_is_number(env, t) enif_is_number(env, t)
-#else
-#define term_is_number(env, t)  \
-    (!enif_is_binary(env, t) && \
-     !enif_is_list(env, t) &&   \
-     !enif_is_tuple(env, t))
-#endif
-
-static ERL_NIF_TERM ATOM_TRUE;
-static ERL_NIF_TERM ATOM_FALSE;
-static ERL_NIF_TERM ATOM_NULL;
-
-typedef struct {
-    ErlNifEnv* env;
-    int error;
-    UCollator* coll;
-} ctx_t;
-
-static UCollator** collators = NULL;
-static int collStackTop = 0;
-static int numCollators = 0;
-static ErlNifMutex* collMutex = NULL;
-
-static ERL_NIF_TERM less_json_nif(ErlNifEnv*, int, const ERL_NIF_TERM []);
-static int on_load(ErlNifEnv*, void**, ERL_NIF_TERM);
-static void on_unload(ErlNifEnv*, void*);
-static __inline int less_json(int, ctx_t*, ERL_NIF_TERM, ERL_NIF_TERM);
-static __inline int atom_sort_order(ErlNifEnv*, ERL_NIF_TERM);
-static __inline int compare_strings(ctx_t*, ErlNifBinary, ErlNifBinary);
-static __inline int compare_lists(int, ctx_t*, ERL_NIF_TERM, ERL_NIF_TERM);
-static __inline int compare_props(int, ctx_t*, ERL_NIF_TERM, ERL_NIF_TERM);
-static __inline void reserve_coll(ctx_t*);
-static __inline void release_coll(ctx_t*);
-
-
-void
-reserve_coll(ctx_t *ctx)
-{
-    if (ctx->coll == NULL) {
-        enif_mutex_lock(collMutex);
-        assert(collStackTop < numCollators);
-        ctx->coll = collators[collStackTop];
-        collStackTop += 1;
-        enif_mutex_unlock(collMutex);
-    }
-}
-
-
-void
-release_coll(ctx_t *ctx)
-{
-    if (ctx->coll != NULL) {
-        enif_mutex_lock(collMutex);
-        collStackTop -= 1;
-        assert(collStackTop >= 0);
-        enif_mutex_unlock(collMutex);
-    }
-}
-
-
-
-ERL_NIF_TERM
-less_json_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{
-    ctx_t ctx;
-    int result;
-
-    ctx.env = env;
-    ctx.error = 0;
-    ctx.coll = NULL;
-
-    result = less_json(1, &ctx, argv[0], argv[1]);
-    release_coll(&ctx);
-
-    /*
-     * There are 2 possible failure reasons:
-     *
-     * 1) We got an invalid EJSON operand;
-     * 2) The EJSON structures are too deep - to avoid allocating too
-     *    many C stack frames (because less_json is a recursive function),
-     *    and running out of memory, we throw a badarg exception to Erlang
-     *    and do the comparison in Erlang land. In practice, views keys are
-     *    EJSON structures with very little nesting.
-     */
-    return ctx.error ? enif_make_badarg(env) : enif_make_int(env, result);
-}
-
-
-int
-less_json(int depth, ctx_t* ctx, ERL_NIF_TERM a, ERL_NIF_TERM b)
-{
-    int aIsAtom, bIsAtom;
-    int aIsBin, bIsBin;
-    int aIsNumber, bIsNumber;
-    int aIsList, bIsList;
-    int aArity, bArity;
-    const ERL_NIF_TERM *aProps, *bProps;
-
-    /*
-     * Avoid too much recursion. Normally there isn't more than a few levels
-     * of recursion, as in practice view keys do not go beyond 1 to 3 levels
-     * of nesting. In case of too much recursion, signal it to the Erlang land
-     * via an exception and do the EJSON comparison in Erlang land.
-     */
-    if (depth > MAX_DEPTH) {
-        ctx->error = 1;
-        return 0;
-    }
-
-    aIsAtom = enif_is_atom(ctx->env, a);
-    bIsAtom = enif_is_atom(ctx->env, b);
-
-    if (aIsAtom) {
-        if (bIsAtom) {
-            int aSortOrd, bSortOrd;
-
-            if ((aSortOrd = atom_sort_order(ctx->env, a)) == -1) {
-                ctx->error = 1;
-                return 0;
-            }
-
-            if ((bSortOrd = atom_sort_order(ctx->env, b)) == -1) {
-                ctx->error = 1;
-                return 0;
-            }
-
-            return aSortOrd - bSortOrd;
-        }
-
-        return -1;
-    }
-
-    if (bIsAtom) {
-        return 1;
-    }
-
-    aIsNumber = term_is_number(ctx->env, a);
-    bIsNumber = term_is_number(ctx->env, b);
-
-    if (aIsNumber) {
-        if (bIsNumber) {
-            return enif_compare_compat(ctx->env, a, b);
-        }
-
-        return -1;
-    }
-
-    if (bIsNumber) {
-        return 1;
-    }
-
-    aIsBin = enif_is_binary(ctx->env, a);
-    bIsBin = enif_is_binary(ctx->env, b);
-
-    if (aIsBin) {
-        if (bIsBin) {
-            ErlNifBinary binA, binB;
-
-            enif_inspect_binary(ctx->env, a, &binA);
-            enif_inspect_binary(ctx->env, b, &binB);
-
-            return compare_strings(ctx, binA, binB);
-        }
-
-        return -1;
-    }
-
-    if (bIsBin) {
-        return 1;
-    }
-
-    aIsList = enif_is_list(ctx->env, a);
-    bIsList = enif_is_list(ctx->env, b);
-
-    if (aIsList) {
-        if (bIsList) {
-            return compare_lists(depth, ctx, a, b);
-        }
-
-        return -1;
-    }
-
-    if (bIsList) {
-        return 1;
-    }
-
-    if (!enif_get_tuple(ctx->env, a, &aArity, &aProps)) {
-        ctx->error = 1;
-        return 0;
-    }
-    if ((aArity != 1) || !enif_is_list(ctx->env, aProps[0])) {
-        ctx->error = 1;
-        return 0;
-    }
-
-    if (!enif_get_tuple(ctx->env, b, &bArity, &bProps)) {
-        ctx->error = 1;
-        return 0;
-    }
-    if ((bArity != 1) || !enif_is_list(ctx->env, bProps[0])) {
-        ctx->error = 1;
-        return 0;
-    }
-
-    return compare_props(depth, ctx, aProps[0], bProps[0]);
-}
-
-
-int
-atom_sort_order(ErlNifEnv* env, ERL_NIF_TERM a)
-{
-    if (enif_compare_compat(env, a, ATOM_NULL) == 0) {
-        return 1;
-    } else if (enif_compare_compat(env, a, ATOM_FALSE) == 0) {
-        return 2;
-    } else if (enif_compare_compat(env, a, ATOM_TRUE) == 0) {
-        return 3;
-    }
-
-    return -1;
-}
-
-
-int
-compare_lists(int depth, ctx_t* ctx, ERL_NIF_TERM a, ERL_NIF_TERM b)
-{
-    ERL_NIF_TERM headA, tailA;
-    ERL_NIF_TERM headB, tailB;
-    int aIsEmpty, bIsEmpty;
-    int result;
-
-    while (1) {
-        aIsEmpty = !enif_get_list_cell(ctx->env, a, &headA, &tailA);
-        bIsEmpty = !enif_get_list_cell(ctx->env, b, &headB, &tailB);
-
-        if (aIsEmpty) {
-            if (bIsEmpty) {
-                return 0;
-            }
-            return -1;
-        }
-
-        if (bIsEmpty) {
-            return 1;
-        }
-
-        result = less_json(depth + 1, ctx, headA, headB);
-
-        if (ctx->error || result != 0) {
-            return result;
-        }
-
-        a = tailA;
-        b = tailB;
-    }
-
-    return result;
-}
-
-
-int
-compare_props(int depth, ctx_t* ctx, ERL_NIF_TERM a, ERL_NIF_TERM b)
-{
-    ERL_NIF_TERM headA, tailA;
-    ERL_NIF_TERM headB, tailB;
-    int aArity, bArity;
-    const ERL_NIF_TERM *aKV, *bKV;
-    ErlNifBinary keyA, keyB;
-    int aIsEmpty, bIsEmpty;
-    int keyCompResult, valueCompResult;
-
-    while (1) {
-        aIsEmpty = !enif_get_list_cell(ctx->env, a, &headA, &tailA);
-        bIsEmpty = !enif_get_list_cell(ctx->env, b, &headB, &tailB);
-
-        if (aIsEmpty) {
-            if (bIsEmpty) {
-                return 0;
-            }
-            return -1;
-        }
-
-        if (bIsEmpty) {
-            return 1;
-        }
-
-        if (!enif_get_tuple(ctx->env, headA, &aArity, &aKV)) {
-            ctx->error = 1;
-            return 0;
-        }
-        if ((aArity != 2) || !enif_inspect_binary(ctx->env, aKV[0], &keyA)) {
-            ctx->error = 1;
-            return 0;
-        }
-
-        if (!enif_get_tuple(ctx->env, headB, &bArity, &bKV)) {
-            ctx->error = 1;
-            return 0;
-        }
-        if ((bArity != 2) || !enif_inspect_binary(ctx->env, bKV[0], &keyB)) {
-            ctx->error = 1;
-            return 0;
-        }
-
-        keyCompResult = compare_strings(ctx, keyA, keyB);
-
-        if (ctx->error || keyCompResult != 0) {
-            return keyCompResult;
-        }
-
-        valueCompResult = less_json(depth + 1, ctx, aKV[1], bKV[1]);
-
-        if (ctx->error || valueCompResult != 0) {
-            return valueCompResult;
-        }
-
-        a = tailA;
-        b = tailB;
-    }
-
-    return 0;
-}
-
-
-int
-compare_strings(ctx_t* ctx, ErlNifBinary a, ErlNifBinary b)
-{
-    UErrorCode status = U_ZERO_ERROR;
-    UCharIterator iterA, iterB;
-    int result;
-
-    uiter_setUTF8(&iterA, (const char *) a.data, (uint32_t) a.size);
-    uiter_setUTF8(&iterB, (const char *) b.data, (uint32_t) b.size);
-
-    reserve_coll(ctx);
-    result = ucol_strcollIter(ctx->coll, &iterA, &iterB, &status);
-
-    if (U_FAILURE(status)) {
-        ctx->error = 1;
-        return 0;
-    }
-
-    /* ucol_strcollIter returns 0, -1 or 1
-     * (see type UCollationResult in unicode/ucol.h) */
-
-    return result;
-}
-
-
-int
-on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
-{
-    UErrorCode status = U_ZERO_ERROR;
-    int i, j;
-
-    if (!enif_get_int(env, info, &numCollators)) {
-        return 1;
-    }
-
-    if (numCollators < 1) {
-        return 2;
-    }
-
-    collMutex = enif_mutex_create("coll_mutex");
-
-    if (collMutex == NULL) {
-        return 3;
-    }
-
-    collators = enif_alloc(sizeof(UCollator*) * numCollators);
-
-    if (collators == NULL) {
-        enif_mutex_destroy(collMutex);
-        return 4;
-    }
-
-    for (i = 0; i < numCollators; i++) {
-        collators[i] = ucol_open("", &status);
-
-        if (U_FAILURE(status)) {
-            for (j = 0; j < i; j++) {
-                ucol_close(collators[j]);
-            }
-
-            enif_free(collators);
-            enif_mutex_destroy(collMutex);
-
-            return 5;
-        }
-    }
-
-    ATOM_TRUE = enif_make_atom(env, "true");
-    ATOM_FALSE = enif_make_atom(env, "false");
-    ATOM_NULL = enif_make_atom(env, "null");
-
-    return 0;
-}
-
-
-void
-on_unload(ErlNifEnv* env, void* priv_data)
-{
-    if (collators != NULL) {
-        int i;
-
-        for (i = 0; i < numCollators; i++) {
-            ucol_close(collators[i]);
-        }
-
-        enif_free(collators);
-    }
-
-    if (collMutex != NULL) {
-        enif_mutex_destroy(collMutex);
-    }
-}
-
-
-static ErlNifFunc nif_functions[] = {
-    {"less_nif", 2, less_json_nif}
-};
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-ERL_NIF_INIT(couch_ejson_compare, nif_functions, &on_load, NULL, NULL, &on_unload);
-
-#ifdef __cplusplus
-}
-#endif

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/bfd6cbb5/priv/couch_ejson_compare/erl_nif_compat.h
----------------------------------------------------------------------
diff --git a/priv/couch_ejson_compare/erl_nif_compat.h b/priv/couch_ejson_compare/erl_nif_compat.h
deleted file mode 100644
index 0aa3ae6..0000000
--- a/priv/couch_ejson_compare/erl_nif_compat.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Copyright (c) 2010-2011 Basho Technologies, Inc.
- * With some minor modifications for Apache CouchDB.
- *
- * This file is provided to you 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 ERL_NIF_COMPAT_H_
-#define ERL_NIF_COMPAT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include "erl_nif.h"
-
-
-#if ERL_NIF_MAJOR_VERSION == 0 && ERL_NIF_MINOR_VERSION == 1
-#define OTP_R13B03
-#elif ERL_NIF_MAJOR_VERSION == 1 && ERL_NIF_MINOR_VERSION == 0
-#define OTP_R13B04
-#elif ERL_NIF_MAJOR_VERSION == 2 && ERL_NIF_MINOR_VERSION == 0
-#define OTP_R14A
-#define OTP_R14B
-#define OTP_R14B01
-#elif ERL_NIF_MAJOR_VERSION == 2 && ERL_NIF_MINOR_VERSION == 1
-#define OTP_R14B02
-#elif ERL_NIF_MAJOR_VERSION == 2 && ERL_NIF_MINOR_VERSION == 2
-#define OTP_R14B03
-#endif
-
-
-#ifdef OTP_R13B03
-
-#define enif_open_resource_type_compat enif_open_resource_type
-#define enif_alloc_resource_compat enif_alloc_resource
-#define enif_release_resource_compat enif_release_resource
-#define enif_alloc_binary_compat enif_alloc_binary
-#define enif_alloc_compat enif_alloc
-#define enif_release_binary_compat enif_release_binary
-#define enif_free_compat enif_free
-#define enif_get_atom_compat enif_get_atom
-#define enif_priv_data_compat enif_get_data
-#define enif_make_uint_compat enif_make_ulong
-
-#define enif_make_string_compat(E, B, Enc) \
-    enif_make_string(E, B)
-
-#define enif_compare_compat enif_compare
-
-#endif /* R13B03 */
-
-
-#ifdef OTP_R13B04
-
-#define enif_open_resource_type_compat enif_open_resource_type
-#define enif_alloc_resource_compat enif_alloc_resource
-#define enif_release_resource_compat enif_release_resource
-#define enif_alloc_binary_compat enif_alloc_binary
-#define enif_realloc_binary_compat enif_realloc_binary
-#define enif_release_binary_compat enif_release_binary
-#define enif_alloc_compat enif_alloc
-#define enif_free_compat enif_free
-#define enif_get_atom_compat enif_get_atom
-#define enif_priv_data_compat enif_priv_data
-#define enif_make_string_compat enif_make_string
-#define enif_make_uint_compat enif_make_uint
-#define enif_compare_compat enif_compare
-
-#endif /* R13B04 */
-
-
-/* OTP R14 and future releases */
-#if !defined(OTP_R13B03) && !defined(OTP_R13B04)
-
-#define enif_open_resource_type_compat(E, N, D, F, T) \
-    enif_open_resource_type(E, NULL, N, D, F, T)
-
-#define enif_alloc_resource_compat(E, T, S) \
-    enif_alloc_resource(T, S)
-
-#define enif_release_resource_compat(E, H) \
-    enif_release_resource(H)
-
-#define enif_alloc_binary_compat(E, S, B) \
-    enif_alloc_binary(S, B)
-
-#define enif_realloc_binary_compat(E, S, B) \
-    enif_realloc_binary(S, B)
-
-#define enif_release_binary_compat(E, B) \
-    enif_release_binary(B)
-
-#define enif_alloc_compat(E, S) \
-    enif_alloc(S)
-
-#define enif_free_compat(E, P) \
-    enif_free(P)
-
-#define enif_get_atom_compat(E, T, B, S) \
-    enif_get_atom(E, T, B, S, ERL_NIF_LATIN1)
-
-#define enif_priv_data_compat enif_priv_data
-#define enif_make_string_compat enif_make_string
-#define enif_make_uint_compat enif_make_uint
-
-#define enif_compare_compat(E, A, B) \
-    enif_compare(A, B)
-
-#endif  /* R14 and future releases */
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* ERL_NIF_COMPAT_H_ */

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/bfd6cbb5/priv/icu_driver/couch_icu_driver.c
----------------------------------------------------------------------
diff --git a/priv/icu_driver/couch_icu_driver.c b/priv/icu_driver/couch_icu_driver.c
deleted file mode 100644
index a59e8cb..0000000
--- a/priv/icu_driver/couch_icu_driver.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
-
-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 the C port driver for Erlang. It provides a low overhead
- * means of calling into C code, however coding errors in this module can
- * crash the entire Erlang server.
- */
-
-#ifdef DARWIN
-#define U_HIDE_DRAFT_API 1
-#define U_DISABLE_RENAMING 1
-#endif
-
-#include "erl_driver.h"
-#include "unicode/ucol.h"
-#include "unicode/ucasemap.h"
-#ifndef WIN32
-#include <string.h> /* for memcpy */
-#endif
-
-#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2
-typedef int COUCH_SSIZET;
-#else
-typedef ErlDrvSSizeT COUCH_SSIZET;
-#endif
-
-typedef struct {
-    ErlDrvPort port;
-    UCollator* collNoCase;
-    UCollator* coll;
-} couch_drv_data;
-
-static void couch_drv_stop(ErlDrvData data)
-{
-    couch_drv_data* pData = (couch_drv_data*)data;
-    if (pData->coll) {
-        ucol_close(pData->coll);
-    }
-    if (pData->collNoCase) {
-        ucol_close(pData->collNoCase);
-    }
-    driver_free((void*)pData);
-}
-
-static ErlDrvData couch_drv_start(ErlDrvPort port, char *buff)
-{
-    UErrorCode status = U_ZERO_ERROR;
-    couch_drv_data* pData = (couch_drv_data*)driver_alloc(sizeof(couch_drv_data));
-
-    if (pData == NULL)
-        return ERL_DRV_ERROR_GENERAL;
-
-    pData->port = port;
-
-    pData->coll = ucol_open("", &status);
-    if (U_FAILURE(status)) {
-        couch_drv_stop((ErlDrvData)pData);
-        return ERL_DRV_ERROR_GENERAL;
-    }
-
-    pData->collNoCase = ucol_open("", &status);
-    if (U_FAILURE(status)) {
-        couch_drv_stop((ErlDrvData)pData);
-        return ERL_DRV_ERROR_GENERAL;
-    }
-
-    ucol_setAttribute(pData->collNoCase, UCOL_STRENGTH, UCOL_PRIMARY, &status);
-    if (U_FAILURE(status)) {
-        couch_drv_stop((ErlDrvData)pData);
-        return ERL_DRV_ERROR_GENERAL;
-    }
-
-    return (ErlDrvData)pData;
-}
-
-COUCH_SSIZET
-return_control_result(void* pLocalResult, int localLen,
-            char **ppRetBuf, COUCH_SSIZET returnLen)
-{
-    if (*ppRetBuf == NULL || localLen > returnLen) {
-        *ppRetBuf = (char*)driver_alloc_binary(localLen);
-        if(*ppRetBuf == NULL) {
-            return -1;
-        }
-    }
-    memcpy(*ppRetBuf, pLocalResult, localLen);
-    return localLen;
-}
-
-static COUCH_SSIZET
-couch_drv_control(ErlDrvData drv_data, unsigned int command,
-        char *pBuf, COUCH_SSIZET bufLen,
-        char **rbuf, COUCH_SSIZET rlen)
-{
-
-    couch_drv_data* pData = (couch_drv_data*)drv_data;
-    switch(command) {
-    case 0: /* COLLATE */
-    case 1: /* COLLATE_NO_CASE: */
-        {
-        UErrorCode status = U_ZERO_ERROR;
-        int collResult;
-        char response;
-        UCharIterator iterA;
-        UCharIterator iterB;
-        int32_t length;
-
-        /* 2 strings are in the buffer, consecutively
-         * The strings begin first with a 32 bit integer byte length, then the actual
-         * string bytes follow.
-         */
-
-        /* first 32bits are the length */
-        memcpy(&length, pBuf, sizeof(length));
-        pBuf += sizeof(length);
-
-        /* point the iterator at it. */
-        uiter_setUTF8(&iterA, pBuf, length);
-
-        pBuf += length; /* now on to string b */
-
-        /* first 32bits are the length */
-        memcpy(&length, pBuf, sizeof(length));
-        pBuf += sizeof(length);
-
-        /* point the iterator at it. */
-        uiter_setUTF8(&iterB, pBuf, length);
-
-        if (command == 0) /* COLLATE */
-          collResult = ucol_strcollIter(pData->coll, &iterA, &iterB, &status);
-        else              /* COLLATE_NO_CASE */
-          collResult = ucol_strcollIter(pData->collNoCase, &iterA, &iterB, &status);
-
-        if (collResult < 0)
-          response = 0; /*lt*/
-        else if (collResult > 0)
-          response = 2; /*gt*/
-        else
-          response = 1; /*eq*/
-
-        return return_control_result(&response, sizeof(response), rbuf, rlen);
-        }
-
-    default:
-        return -1;
-    }
-}
-
-ErlDrvEntry couch_driver_entry = {
-        NULL,               /* F_PTR init, N/A */
-        couch_drv_start,    /* L_PTR start, called when port is opened */
-        couch_drv_stop,     /* F_PTR stop, called when port is closed */
-        NULL,               /* F_PTR output, called when erlang has sent */
-        NULL,               /* F_PTR ready_input, called when input descriptor ready */
-        NULL,               /* F_PTR ready_output, called when output descriptor ready */
-        "couch_icu_driver", /* char *driver_name, the argument to open_port */
-        NULL,               /* F_PTR finish, called when unloaded */
-        NULL,               /* Not used */
-        couch_drv_control,  /* F_PTR control, port_command callback */
-        NULL,               /* F_PTR timeout, reserved */
-        NULL,               /* F_PTR outputv, reserved */
-        NULL,               /* F_PTR ready_async */
-        NULL,               /* F_PTR flush */
-        NULL,               /* F_PTR call */
-        NULL,               /* F_PTR event */
-        ERL_DRV_EXTENDED_MARKER,
-        ERL_DRV_EXTENDED_MAJOR_VERSION,
-        ERL_DRV_EXTENDED_MINOR_VERSION,
-        ERL_DRV_FLAG_USE_PORT_LOCKING,
-        NULL,               /* Reserved -- Used by emulator internally */
-        NULL,               /* F_PTR process_exit */
-};
-
-DRIVER_INIT(couch_icu_driver) /* must match name in driver_entry */
-{
-        return &couch_driver_entry;
-}


[2/2] couch commit: updated refs/heads/1994-merge-rcouch to f9e3095

Posted by be...@apache.org.
Add validate_doc_read property to a design document.

Like validate_doc_update, this function validate if the document can be
read by the curreny user.

ex:

    function(doc, userCtx) {
        if ((typeof doc.name !== 'undefined') && (doc.name !=
userCtx.name)) {
            throw({unauthorized: doc.name + ' cannnot read ' +
doc._id});
        }
    }

will allow the current user to only read the documents where the
properties name is the name of the user.

Note: admins can always read the documents.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/f9e30951
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/f9e30951
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/f9e30951

Branch: refs/heads/1994-merge-rcouch
Commit: f9e3095195dd31fc55334e675d48f5e395d67b55
Parents: bfd6cbb
Author: benoitc <bc...@gmail.com>
Authored: Sun Feb 16 01:16:08 2014 +0100
Committer: benoitc <bc...@gmail.com>
Committed: Sun Feb 16 01:16:08 2014 +0100

----------------------------------------------------------------------
 include/couch_db.hrl        |  1 +
 src/couch_db.erl            | 32 +++++++++++++++++++++++++++++++-
 src/couch_db_updater.erl    | 27 +++++++++++++++++----------
 src/couch_doc.erl           | 15 ++++++++++++++-
 src/couch_query_servers.erl | 14 +++++++++++++-
 5 files changed, 76 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/f9e30951/include/couch_db.hrl
----------------------------------------------------------------------
diff --git a/include/couch_db.hrl b/include/couch_db.hrl
index e0a1c82..539dd4a 100644
--- a/include/couch_db.hrl
+++ b/include/couch_db.hrl
@@ -190,6 +190,7 @@
     name,
     filepath,
     validate_doc_funs = [],
+    validate_doc_read_funs = [],
     security = [],
     security_ptr = nil,
     user_ctx = #user_ctx{},

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/f9e30951/src/couch_db.erl
----------------------------------------------------------------------
diff --git a/src/couch_db.erl b/src/couch_db.erl
index 11ea0fd..a852cae 100644
--- a/src/couch_db.erl
+++ b/src/couch_db.erl
@@ -1321,7 +1321,9 @@ make_doc(#db{updater_fd = Fd} = Db, Id, Deleted, Bp, RevisionPath) ->
         atts = Atts,
         deleted = Deleted
     },
-    after_doc_read(Db, Doc).
+    Doc1 = after_doc_read(Db, Doc),
+    ok = validate_doc_read(Db, Doc1),
+    Doc1.
 
 
 after_doc_read(#db{after_doc_read = nil}, Doc) ->
@@ -1330,6 +1332,34 @@ after_doc_read(#db{after_doc_read = Fun} = Db, Doc) ->
     Fun(couch_doc:with_ejson_body(Doc), Db).
 
 
+validate_doc_read(#db{validate_doc_read_funs=[]}, _Doc) ->
+    ok;
+validate_doc_read(_Db, #doc{id= <<"_local/",_/binary>>}) ->
+    ok;
+validate_doc_read(Db, Doc) ->
+    case catch(check_is_admin(Db)) of
+        ok ->
+            ok;
+        _ ->
+            JsonCtx = couch_util:json_user_ctx(Db),
+            SecObj = get_security(Db),
+            try [case Fun(Doc, JsonCtx, SecObj) of
+                    ok -> ok;
+                    Error -> throw(Error)
+                end || Fun <- Db#db.validate_doc_read_funs],
+                ok
+            catch
+                throw:{forbidden, _}=Error ->
+                    throw(Error);
+                throw:{unauthorized, _}=Error ->
+                    throw(Error);
+                throw:Error ->
+                    ?LOG_ERROR("Error while validating read: ~p~n", [Error]),
+                    ok
+            end
+    end.
+
+
 increment_stat(#db{options = Options}, Stat) ->
     case lists:member(sys_db, Options) of
     true ->

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/f9e30951/src/couch_db_updater.erl
----------------------------------------------------------------------
diff --git a/src/couch_db_updater.erl b/src/couch_db_updater.erl
index 947669c..6a57c9b 100644
--- a/src/couch_db_updater.erl
+++ b/src/couch_db_updater.erl
@@ -503,16 +503,23 @@ close_db(#db{fd_ref_counter = RefCntr}) ->
 refresh_validate_doc_funs(Db0) ->
     Db = Db0#db{user_ctx = #user_ctx{roles=[<<"_admin">>]}},
     DesignDocs = couch_db:get_design_docs(Db),
-    ProcessDocFuns = lists:flatmap(
-        fun(DesignDocInfo) ->
-            {ok, DesignDoc} = couch_db:open_doc_int(
-                Db, DesignDocInfo, [ejson_body]),
-            case couch_doc:get_validate_doc_fun(DesignDoc) of
-            nil -> [];
-            Fun -> [Fun]
-            end
-        end, DesignDocs),
-    Db0#db{validate_doc_funs=ProcessDocFuns}.
+    {UpdateFuns, ReadFuns} = lists:foldl(
+            fun(DesignDocInfo, {UAcc, RAcc}) ->
+                    {ok, DesignDoc} = couch_db:open_doc_int(Db, DesignDocInfo,
+                                                            [ejson_body]),
+                    UAcc1 = case couch_doc:get_validate_doc_fun(DesignDoc) of
+                        nil -> UAcc;
+                        Fun -> [Fun|UAcc]
+                    end,
+                    RAcc1 = case couch_doc:get_validate_read_doc_fun(
+                            DesignDoc) of
+                        nil -> RAcc;
+                        Fun1 -> [Fun1|RAcc]
+                    end,
+                    {UAcc1, RAcc1}
+            end, {[], []}, DesignDocs),
+    Db0#db{validate_doc_funs=UpdateFuns, validate_doc_read_funs=ReadFuns}.
+
 
 % rev tree functions
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/f9e30951/src/couch_doc.erl
----------------------------------------------------------------------
diff --git a/src/couch_doc.erl b/src/couch_doc.erl
index 4047370..efde8c1 100644
--- a/src/couch_doc.erl
+++ b/src/couch_doc.erl
@@ -13,7 +13,8 @@
 -module(couch_doc).
 
 -export([to_doc_info/1,to_doc_info_path/1,parse_rev/1,parse_revs/1,rev_to_str/1,revs_to_strs/1]).
--export([att_foldl/3,range_att_foldl/5,att_foldl_decode/3,get_validate_doc_fun/1]).
+-export([att_foldl/3,range_att_foldl/5,att_foldl_decode/3,
+         get_validate_doc_fun/1,get_validate_read_doc_fun/1]).
 -export([from_json_obj/1,to_json_obj/2,has_stubs/1, merge_stubs/2]).
 -export([validate_docid/1]).
 -export([doc_from_multi_part_stream/2]).
@@ -412,6 +413,18 @@ get_validate_doc_fun(#doc{body={Props}}=DDoc) ->
     end.
 
 
+get_validate_read_doc_fun(#doc{body={Props}}=DDoc) ->
+    case couch_util:get_value(<<"validate_doc_read">>, Props) of
+        undefined ->
+            nil;
+        _Else ->
+            fun(Doc, Ctx, SecObj) ->
+                    couch_query_servers:validate_doc_read(DDoc, Doc, Ctx,
+                                                          SecObj)
+            end
+    end.
+
+
 has_stubs(#doc{atts=Atts}) ->
     has_stubs(Atts);
 has_stubs([]) ->

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/f9e30951/src/couch_query_servers.erl
----------------------------------------------------------------------
diff --git a/src/couch_query_servers.erl b/src/couch_query_servers.erl
index 3b58cbe..148cdba 100644
--- a/src/couch_query_servers.erl
+++ b/src/couch_query_servers.erl
@@ -17,7 +17,7 @@
 
 -export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2,code_change/3]).
 -export([start_doc_map/3, map_docs/2, map_doc_raw/2, stop_doc_map/1, raw_to_ejson/1]).
--export([reduce/3, rereduce/3,validate_doc_update/5]).
+-export([reduce/3, rereduce/3,validate_doc_update/5,validate_doc_read/4]).
 -export([filter_docs/5]).
 -export([filter_view/3]).
 
@@ -233,6 +233,18 @@ validate_doc_update(DDoc, EditDoc, DiskDoc, Ctx, SecObj) ->
             throw({unauthorized, Message})
     end.
 
+validate_doc_read(DDoc, Doc, Ctx, SecObj) ->
+    JsonDoc = couch_doc:to_json_obj(Doc, [revs]),
+    case ddoc_prompt(DDoc, [<<"validate_doc_read">>],
+                     [JsonDoc, Ctx, SecObj]) of
+        1 ->
+            ok;
+        {[{<<"forbidden">>, Message}]} ->
+            throw({forbidden, Message});
+        {[{<<"unauthorized">>, Message}]} ->
+            throw({unauthorized, Message})
+    end.
+
 json_doc(nil) -> null;
 json_doc(Doc) ->
     couch_doc:to_json_obj(Doc, [revs]).