XADD key [(MAXLEN [~|=] | MINID [~|=] ) [LIMIT ]] [NOMKSTREAM] [field value] [field value] ... */
| 1785 | |
| 1786 | /* XADD key [(MAXLEN [~|=] <count> | MINID [~|=] <id>) [LIMIT <entries>]] [NOMKSTREAM] <ID or *> [field value] [field value] ... */ |
| 1787 | void xaddCommand(client *c) { |
| 1788 | /* Parse options. */ |
| 1789 | streamAddTrimArgs parsed_args; |
| 1790 | int idpos = streamParseAddOrTrimArgsOrReply(c, &parsed_args, 1); |
| 1791 | if (idpos < 0) |
| 1792 | return; /* streamParseAddOrTrimArgsOrReply already replied. */ |
| 1793 | int field_pos = idpos+1; /* The ID is always one argument before the first field */ |
| 1794 | |
| 1795 | /* Check arity. */ |
| 1796 | if ((c->argc - field_pos) < 2 || ((c->argc-field_pos) % 2) == 1) { |
| 1797 | addReplyError(c,"wrong number of arguments for XADD"); |
| 1798 | return; |
| 1799 | } |
| 1800 | |
| 1801 | /* Return ASAP if minimal ID (0-0) was given so we avoid possibly creating |
| 1802 | * a new stream and have streamAppendItem fail, leaving an empty key in the |
| 1803 | * database. */ |
| 1804 | if (parsed_args.id_given && |
| 1805 | parsed_args.id.ms == 0 && parsed_args.id.seq == 0) |
| 1806 | { |
| 1807 | addReplyError(c,"The ID specified in XADD must be greater than 0-0"); |
| 1808 | return; |
| 1809 | } |
| 1810 | |
| 1811 | /* Lookup the stream at key. */ |
| 1812 | robj *o; |
| 1813 | stream *s; |
| 1814 | if ((o = streamTypeLookupWriteOrCreate(c,c->argv[1],parsed_args.no_mkstream)) == NULL) return; |
| 1815 | s = (stream*)ptrFromObj(o); |
| 1816 | |
| 1817 | /* Return ASAP if the stream has reached the last possible ID */ |
| 1818 | if (s->last_id.ms == UINT64_MAX && s->last_id.seq == UINT64_MAX) { |
| 1819 | addReplyError(c,"The stream has exhausted the last possible ID, " |
| 1820 | "unable to add more items"); |
| 1821 | return; |
| 1822 | } |
| 1823 | |
| 1824 | /* Append using the low level function and return the ID. */ |
| 1825 | streamID id; |
| 1826 | if (streamAppendItem(s,c->argv+field_pos,(c->argc-field_pos)/2, |
| 1827 | &id, parsed_args.id_given ? &parsed_args.id : NULL) == C_ERR) |
| 1828 | { |
| 1829 | if (errno == EDOM) |
| 1830 | addReplyError(c,"The ID specified in XADD is equal or smaller than " |
| 1831 | "the target stream top item"); |
| 1832 | else |
| 1833 | addReplyError(c,"Elements are too large to be stored"); |
| 1834 | return; |
| 1835 | } |
| 1836 | addReplyStreamID(c,&id); |
| 1837 | |
| 1838 | signalModifiedKey(c,c->db,c->argv[1]); |
| 1839 | notifyKeyspaceEvent(NOTIFY_STREAM,"xadd",c->argv[1],c->db->id); |
| 1840 | g_pserver->dirty++; |
| 1841 | |
| 1842 | /* Trim if needed. */ |
| 1843 | if (parsed_args.trim_strategy != TRIM_STRATEGY_NONE) { |
| 1844 | if (streamTrim(s, &parsed_args)) { |
nothing calls this directly
no test coverage detected