GRAPH.CONSTRAIN CREATE UNIQUE/MANDATORY [NODE label / RELATIONSHIP type] PROPERTIES prop_count prop0, prop1...
| 229 | |
| 230 | // GRAPH.CONSTRAIN <key> CREATE UNIQUE/MANDATORY [NODE label / RELATIONSHIP type] PROPERTIES prop_count prop0, prop1... |
| 231 | static bool _Constraint_Create |
| 232 | ( |
| 233 | RedisModuleCtx *ctx, // redis module context |
| 234 | RedisModuleString *key, // graph key to operate on |
| 235 | ConstraintType ct, // constraint type |
| 236 | GraphEntityType et, // entity type |
| 237 | const char *lbl, // label / rel-type |
| 238 | uint8_t n, // properties count |
| 239 | const char **props // properties |
| 240 | ) { |
| 241 | bool res = true; |
| 242 | const char *error_msg = "Constraint creation failed"; |
| 243 | |
| 244 | // get or create graph |
| 245 | GraphContext *gc = GraphContext_Retrieve(ctx, key, false, true); |
| 246 | if(gc == NULL) { |
| 247 | return false; |
| 248 | } |
| 249 | |
| 250 | // set graph context in query context TLS |
| 251 | // this is required in case the undo-log needs to be applied |
| 252 | // TODO: find a better way |
| 253 | QueryCtx_SetGraphCtx(gc); |
| 254 | |
| 255 | Graph *g = GraphContext_GetGraph(gc); |
| 256 | |
| 257 | // acquire graph write lock |
| 258 | Graph_AcquireWriteLock(gc->g); |
| 259 | |
| 260 | //-------------------------------------------------------------------------- |
| 261 | // convert attribute name to attribute ID |
| 262 | //-------------------------------------------------------------------------- |
| 263 | |
| 264 | Attribute_ID attr_ids[n]; |
| 265 | for(uint i = 0; i < n; i++) { |
| 266 | attr_ids[i] = FindOrAddAttribute(gc, props[i], true); |
| 267 | } |
| 268 | |
| 269 | //-------------------------------------------------------------------------- |
| 270 | // check for duplicates |
| 271 | //-------------------------------------------------------------------------- |
| 272 | |
| 273 | // sort the properties for an easy comparison later |
| 274 | bool dups = false; |
| 275 | qsort(attr_ids, n, sizeof(Attribute_ID), _cmp_Attribute_ID); |
| 276 | for(uint i = 0; i < n - 1; i++) { |
| 277 | if(attr_ids[i] == attr_ids[i+1]) { |
| 278 | dups = true; |
| 279 | break; |
| 280 | } |
| 281 | } |
| 282 | |
| 283 | // duplicates found, fail operation |
| 284 | if(dups) { |
| 285 | error_msg = "Properties cannot contain duplicates"; |
| 286 | res = false; |
| 287 | goto cleanup; |
| 288 | } |
no test coverage detected