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]).