XGROUP CREATE [MKSTREAM] * XGROUP SETID * XGROUP DESTROY * XGROUP CREATECONSUMER * XGROUP DELCONSUMER */
| 2356 | * XGROUP CREATECONSUMER <key> <groupname> <consumer> |
| 2357 | * XGROUP DELCONSUMER <key> <groupname> <consumername> */ |
| 2358 | void xgroupCommand(client *c) { |
| 2359 | stream *s = NULL; |
| 2360 | sds grpname = NULL; |
| 2361 | streamCG *cg = NULL; |
| 2362 | char *opt = szFromObj(c->argv[1]); /* Subcommand name. */ |
| 2363 | int mkstream = 0; |
| 2364 | robj *o; |
| 2365 | |
| 2366 | /* CREATE has an MKSTREAM option that creates the stream if it |
| 2367 | * does not exist. */ |
| 2368 | if (c->argc == 6 && !strcasecmp(opt,"CREATE")) { |
| 2369 | if (strcasecmp(szFromObj(c->argv[5]),"MKSTREAM")) { |
| 2370 | addReplySubcommandSyntaxError(c); |
| 2371 | return; |
| 2372 | } |
| 2373 | mkstream = 1; |
| 2374 | grpname = szFromObj(c->argv[3]); |
| 2375 | } |
| 2376 | |
| 2377 | /* Everything but the "HELP" option requires a key and group name. */ |
| 2378 | if (c->argc >= 4) { |
| 2379 | o = lookupKeyWrite(c->db,c->argv[2]); |
| 2380 | if (o) { |
| 2381 | if (checkType(c,o,OBJ_STREAM)) return; |
| 2382 | s = (stream*)ptrFromObj(o); |
| 2383 | } |
| 2384 | grpname = szFromObj(c->argv[3]); |
| 2385 | } |
| 2386 | |
| 2387 | /* Check for missing key/group. */ |
| 2388 | if (c->argc >= 4 && !mkstream) { |
| 2389 | /* At this point key must exist, or there is an error. */ |
| 2390 | if (s == NULL) { |
| 2391 | addReplyError(c, |
| 2392 | "The XGROUP subcommand requires the key to exist. " |
| 2393 | "Note that for CREATE you may want to use the MKSTREAM " |
| 2394 | "option to create an empty stream automatically."); |
| 2395 | return; |
| 2396 | } |
| 2397 | |
| 2398 | /* Certain subcommands require the group to exist. */ |
| 2399 | if ((cg = streamLookupCG(s,grpname)) == NULL && |
| 2400 | (!strcasecmp(opt,"SETID") || |
| 2401 | !strcasecmp(opt,"CREATECONSUMER") || |
| 2402 | !strcasecmp(opt,"DELCONSUMER"))) |
| 2403 | { |
| 2404 | addReplyErrorFormat(c, "-NOGROUP No such consumer group '%s' " |
| 2405 | "for key name '%s'", |
| 2406 | (char*)grpname, (char*)ptrFromObj(c->argv[2])); |
| 2407 | return; |
| 2408 | } |
| 2409 | } |
| 2410 | |
| 2411 | /* Dispatch the different subcommands. */ |
| 2412 | if (c->argc == 2 && !strcasecmp(opt,"HELP")) { |
| 2413 | const char *help[] = { |
| 2414 | "CREATE <key> <groupname> <id|$> [option]", |
| 2415 | " Create a new consumer group. Options are:", |
nothing calls this directly
no test coverage detected