Set the field of the specified hash field to the specified value. * If the key is an empty key open for writing, it is created with an empty * hash value, in order to set the specified field. * * The function is variadic and the user must specify pairs of field * names and values, both as RedisModuleString pointers (unless the * CFIELD option is set, see later). At the end of the field/value
| 3117 | * the Redis version and handle it accordingly. |
| 3118 | */ |
| 3119 | int RM_HashSet(RedisModuleKey *key, int flags, ...) { |
| 3120 | va_list ap; |
| 3121 | if (!key || (flags & ~(REDISMODULE_HASH_NX | |
| 3122 | REDISMODULE_HASH_XX | |
| 3123 | REDISMODULE_HASH_CFIELDS | |
| 3124 | REDISMODULE_HASH_COUNT_ALL))) { |
| 3125 | errno = EINVAL; |
| 3126 | return 0; |
| 3127 | } else if (key->value && key->value->type != OBJ_HASH) { |
| 3128 | errno = ENOTSUP; |
| 3129 | return 0; |
| 3130 | } else if (!(key->mode & REDISMODULE_WRITE)) { |
| 3131 | errno = EBADF; |
| 3132 | return 0; |
| 3133 | } |
| 3134 | if (key->value == NULL) moduleCreateEmptyKey(key,REDISMODULE_KEYTYPE_HASH); |
| 3135 | |
| 3136 | int count = 0; |
| 3137 | va_start(ap, flags); |
| 3138 | while(1) { |
| 3139 | RedisModuleString *field, *value; |
| 3140 | /* Get the field and value objects. */ |
| 3141 | if (flags & REDISMODULE_HASH_CFIELDS) { |
| 3142 | char *cfield = va_arg(ap,char*); |
| 3143 | if (cfield == NULL) break; |
| 3144 | field = createRawStringObject(cfield,strlen(cfield)); |
| 3145 | } else { |
| 3146 | field = va_arg(ap,RedisModuleString*); |
| 3147 | if (field == NULL) break; |
| 3148 | } |
| 3149 | value = va_arg(ap,RedisModuleString*); |
| 3150 | |
| 3151 | /* Handle XX and NX */ |
| 3152 | if (flags & (REDISMODULE_HASH_XX|REDISMODULE_HASH_NX)) { |
| 3153 | int exists = hashTypeExists(key->value, field->ptr); |
| 3154 | if (((flags & REDISMODULE_HASH_XX) && !exists) || |
| 3155 | ((flags & REDISMODULE_HASH_NX) && exists)) |
| 3156 | { |
| 3157 | if (flags & REDISMODULE_HASH_CFIELDS) decrRefCount(field); |
| 3158 | continue; |
| 3159 | } |
| 3160 | } |
| 3161 | |
| 3162 | /* Handle deletion if value is REDISMODULE_HASH_DELETE. */ |
| 3163 | if (value == REDISMODULE_HASH_DELETE) { |
| 3164 | count += hashTypeDelete(key->value, field->ptr); |
| 3165 | if (flags & REDISMODULE_HASH_CFIELDS) decrRefCount(field); |
| 3166 | continue; |
| 3167 | } |
| 3168 | |
| 3169 | int low_flags = HASH_SET_COPY; |
| 3170 | /* If CFIELDS is active, we can pass the ownership of the |
| 3171 | * SDS object to the low level function that sets the field |
| 3172 | * to avoid a useless copy. */ |
| 3173 | if (flags & REDISMODULE_HASH_CFIELDS) |
| 3174 | low_flags |= HASH_SET_TAKE_FIELD; |
| 3175 | |
| 3176 | robj *argv[2] = {field,value}; |
nothing calls this directly
no test coverage detected