mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 08:38:27 -05:00
Merge branch 'master' into brpoplpush
This commit is contained in:
commit
bc8ffafeb9
3
Makefile
3
Makefile
@ -16,4 +16,7 @@ clean:
|
|||||||
$(TARGETS):
|
$(TARGETS):
|
||||||
cd src && $(MAKE) $@
|
cd src && $(MAKE) $@
|
||||||
|
|
||||||
|
src/help.h:
|
||||||
|
@./utils/generate-command-help.rb > $@
|
||||||
|
|
||||||
dummy:
|
dummy:
|
||||||
|
9
deps/linenoise/example.c
vendored
9
deps/linenoise/example.c
vendored
@ -2,9 +2,18 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "linenoise.h"
|
#include "linenoise.h"
|
||||||
|
|
||||||
|
|
||||||
|
void completion(const char *buf, linenoiseCompletions *lc) {
|
||||||
|
if (buf[0] == 'h') {
|
||||||
|
linenoiseAddCompletion(lc,"hello");
|
||||||
|
linenoiseAddCompletion(lc,"hello there");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
char *line;
|
char *line;
|
||||||
|
|
||||||
|
linenoiseSetCompletionCallback(completion);
|
||||||
linenoiseHistoryLoad("history.txt"); /* Load the history at startup */
|
linenoiseHistoryLoad("history.txt"); /* Load the history at startup */
|
||||||
while((line = linenoise("hello> ")) != NULL) {
|
while((line = linenoise("hello> ")) != NULL) {
|
||||||
if (line[0] != '\0') {
|
if (line[0] != '\0') {
|
||||||
|
115
deps/linenoise/linenoise.c
vendored
115
deps/linenoise/linenoise.c
vendored
@ -9,6 +9,8 @@
|
|||||||
* the 2010 UNIX computers around.
|
* the 2010 UNIX computers around.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
* Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||||
|
* Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
||||||
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -67,6 +69,17 @@
|
|||||||
* Sequence: ESC [ n C
|
* Sequence: ESC [ n C
|
||||||
* Effect: moves cursor forward of n chars
|
* Effect: moves cursor forward of n chars
|
||||||
*
|
*
|
||||||
|
* The following are used to clear the screen: ESC [ H ESC [ 2 J
|
||||||
|
* This is actually composed of two sequences:
|
||||||
|
*
|
||||||
|
* cursorhome
|
||||||
|
* Sequence: ESC [ H
|
||||||
|
* Effect: moves the cursor to upper left corner
|
||||||
|
*
|
||||||
|
* ED2 (Clear entire screen)
|
||||||
|
* Sequence: ESC [ 2 J
|
||||||
|
* Effect: clear the whole screen
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
@ -79,10 +92,12 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include "linenoise.h"
|
||||||
|
|
||||||
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
|
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
|
||||||
#define LINENOISE_MAX_LINE 4096
|
#define LINENOISE_MAX_LINE 4096
|
||||||
static char *unsupported_term[] = {"dumb","cons25",NULL};
|
static char *unsupported_term[] = {"dumb","cons25",NULL};
|
||||||
|
static linenoiseCompletionCallback *completionCallback = NULL;
|
||||||
|
|
||||||
static struct termios orig_termios; /* in order to restore at exit */
|
static struct termios orig_termios; /* in order to restore at exit */
|
||||||
static int rawmode = 0; /* for atexit() function to check if restore is needed*/
|
static int rawmode = 0; /* for atexit() function to check if restore is needed*/
|
||||||
@ -195,6 +210,78 @@ static void refreshLine(int fd, const char *prompt, char *buf, size_t len, size_
|
|||||||
if (write(fd,seq,strlen(seq)) == -1) return;
|
if (write(fd,seq,strlen(seq)) == -1) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void beep() {
|
||||||
|
fprintf(stderr, "\x7");
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeCompletions(linenoiseCompletions *lc) {
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < lc->len; i++)
|
||||||
|
free(lc->cvec[i]);
|
||||||
|
if (lc->cvec != NULL)
|
||||||
|
free(lc->cvec);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int completeLine(int fd, const char *prompt, char *buf, size_t buflen, size_t *len, size_t *pos, size_t cols) {
|
||||||
|
linenoiseCompletions lc = { 0, NULL };
|
||||||
|
int nread, nwritten;
|
||||||
|
char c = 0;
|
||||||
|
|
||||||
|
completionCallback(buf,&lc);
|
||||||
|
if (lc.len == 0) {
|
||||||
|
beep();
|
||||||
|
} else {
|
||||||
|
size_t stop = 0, i = 0;
|
||||||
|
size_t clen;
|
||||||
|
|
||||||
|
while(!stop) {
|
||||||
|
/* Show completion or original buffer */
|
||||||
|
if (i < lc.len) {
|
||||||
|
clen = strlen(lc.cvec[i]);
|
||||||
|
refreshLine(fd,prompt,lc.cvec[i],clen,clen,cols);
|
||||||
|
} else {
|
||||||
|
refreshLine(fd,prompt,buf,*len,*pos,cols);
|
||||||
|
}
|
||||||
|
|
||||||
|
nread = read(fd,&c,1);
|
||||||
|
if (nread <= 0) {
|
||||||
|
freeCompletions(&lc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(c) {
|
||||||
|
case 9: /* tab */
|
||||||
|
i = (i+1) % (lc.len+1);
|
||||||
|
if (i == lc.len) beep();
|
||||||
|
break;
|
||||||
|
case 27: /* escape */
|
||||||
|
/* Re-show original buffer */
|
||||||
|
if (i < lc.len) {
|
||||||
|
refreshLine(fd,prompt,buf,*len,*pos,cols);
|
||||||
|
}
|
||||||
|
stop = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Update buffer and return */
|
||||||
|
if (i < lc.len) {
|
||||||
|
nwritten = snprintf(buf,buflen,"%s",lc.cvec[i]);
|
||||||
|
*len = *pos = nwritten;
|
||||||
|
}
|
||||||
|
stop = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freeCompletions(&lc);
|
||||||
|
return c; /* Return last read character */
|
||||||
|
}
|
||||||
|
|
||||||
|
void linenoiseClearScreen(void) {
|
||||||
|
write(STDIN_FILENO,"\x1b[H\x1b[2J",7);
|
||||||
|
}
|
||||||
|
|
||||||
static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt) {
|
static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt) {
|
||||||
size_t plen = strlen(prompt);
|
size_t plen = strlen(prompt);
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
@ -217,6 +304,18 @@ static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt)
|
|||||||
|
|
||||||
nread = read(fd,&c,1);
|
nread = read(fd,&c,1);
|
||||||
if (nread <= 0) return len;
|
if (nread <= 0) return len;
|
||||||
|
|
||||||
|
/* Only autocomplete when the callback is set. It returns < 0 when
|
||||||
|
* there was an error reading from fd. Otherwise it will return the
|
||||||
|
* character that should be handled next. */
|
||||||
|
if (c == 9 && completionCallback != NULL) {
|
||||||
|
c = completeLine(fd,prompt,buf,buflen,&len,&pos,cols);
|
||||||
|
/* Return on errors */
|
||||||
|
if (c < 0) return len;
|
||||||
|
/* Read next character when 0 */
|
||||||
|
if (c == 0) continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 13: /* enter */
|
case 13: /* enter */
|
||||||
case 4: /* ctrl-d */
|
case 4: /* ctrl-d */
|
||||||
@ -350,6 +449,9 @@ up_down_arrow:
|
|||||||
pos = len;
|
pos = len;
|
||||||
refreshLine(fd,prompt,buf,len,pos,cols);
|
refreshLine(fd,prompt,buf,len,pos,cols);
|
||||||
break;
|
break;
|
||||||
|
case 12: /* ctrl+l, clear screen */
|
||||||
|
linenoiseClearScreen();
|
||||||
|
refreshLine(fd,prompt,buf,len,pos,cols);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
@ -402,6 +504,19 @@ char *linenoise(const char *prompt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Register a callback function to be called for tab-completion. */
|
||||||
|
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) {
|
||||||
|
completionCallback = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void linenoiseAddCompletion(linenoiseCompletions *lc, char *str) {
|
||||||
|
size_t len = strlen(str);
|
||||||
|
char *copy = malloc(len+1);
|
||||||
|
memcpy(copy,str,len+1);
|
||||||
|
lc->cvec = realloc(lc->cvec,sizeof(char*)*(lc->len+1));
|
||||||
|
lc->cvec[lc->len++] = copy;
|
||||||
|
}
|
||||||
|
|
||||||
/* Using a circular buffer is smarter, but a bit more complex to handle. */
|
/* Using a circular buffer is smarter, but a bit more complex to handle. */
|
||||||
int linenoiseHistoryAdd(const char *line) {
|
int linenoiseHistoryAdd(const char *line) {
|
||||||
char *linecopy;
|
char *linecopy;
|
||||||
|
12
deps/linenoise/linenoise.h
vendored
12
deps/linenoise/linenoise.h
vendored
@ -4,6 +4,8 @@
|
|||||||
* See linenoise.c for more information.
|
* See linenoise.c for more information.
|
||||||
*
|
*
|
||||||
* Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
* Copyright (c) 2010, Salvatore Sanfilippo <antirez at gmail dot com>
|
||||||
|
* Copyright (c) 2010, Pieter Noordhuis <pcnoordhuis at gmail dot com>
|
||||||
|
*
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -34,10 +36,20 @@
|
|||||||
#ifndef __LINENOISE_H
|
#ifndef __LINENOISE_H
|
||||||
#define __LINENOISE_H
|
#define __LINENOISE_H
|
||||||
|
|
||||||
|
typedef struct linenoiseCompletions {
|
||||||
|
size_t len;
|
||||||
|
char **cvec;
|
||||||
|
} linenoiseCompletions;
|
||||||
|
|
||||||
|
typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *);
|
||||||
|
void linenoiseSetCompletionCallback(linenoiseCompletionCallback *);
|
||||||
|
void linenoiseAddCompletion(linenoiseCompletions *, char *);
|
||||||
|
|
||||||
char *linenoise(const char *prompt);
|
char *linenoise(const char *prompt);
|
||||||
int linenoiseHistoryAdd(const char *line);
|
int linenoiseHistoryAdd(const char *line);
|
||||||
int linenoiseHistorySetMaxLen(int len);
|
int linenoiseHistorySetMaxLen(int len);
|
||||||
int linenoiseHistorySave(char *filename);
|
int linenoiseHistorySave(char *filename);
|
||||||
int linenoiseHistoryLoad(char *filename);
|
int linenoiseHistoryLoad(char *filename);
|
||||||
|
void linenoiseClearScreen(void);
|
||||||
|
|
||||||
#endif /* __LINENOISE_H */
|
#endif /* __LINENOISE_H */
|
||||||
|
608
src/help.h
Normal file
608
src/help.h
Normal file
@ -0,0 +1,608 @@
|
|||||||
|
/* Automatically generated by utils/generate-command-help.rb, do not edit. */
|
||||||
|
|
||||||
|
#ifndef __REDIS_HELP_H
|
||||||
|
#define __REDIS_HELP_H
|
||||||
|
|
||||||
|
static char *commandGroups[] = {
|
||||||
|
"generic",
|
||||||
|
"string",
|
||||||
|
"list",
|
||||||
|
"set",
|
||||||
|
"sorted_set",
|
||||||
|
"hash",
|
||||||
|
"pubsub",
|
||||||
|
"transactions",
|
||||||
|
"connection",
|
||||||
|
"server"
|
||||||
|
};
|
||||||
|
|
||||||
|
struct commandHelp {
|
||||||
|
char *name;
|
||||||
|
char *params;
|
||||||
|
char *summary;
|
||||||
|
int group;
|
||||||
|
char *since;
|
||||||
|
} commandHelp[] = {
|
||||||
|
{ "APPEND",
|
||||||
|
"key value",
|
||||||
|
"Append a value to a key",
|
||||||
|
1,
|
||||||
|
"1.3.3" },
|
||||||
|
{ "AUTH",
|
||||||
|
"password",
|
||||||
|
"Authenticate to the server",
|
||||||
|
8,
|
||||||
|
"0.08" },
|
||||||
|
{ "BGREWRITEAOF",
|
||||||
|
"-",
|
||||||
|
"Asynchronously rewrite the append-only file",
|
||||||
|
9,
|
||||||
|
"1.07" },
|
||||||
|
{ "BGSAVE",
|
||||||
|
"-",
|
||||||
|
"Asynchronously save the dataset to disk",
|
||||||
|
9,
|
||||||
|
"0.07" },
|
||||||
|
{ "BLPOP",
|
||||||
|
"key [key ...] timeout",
|
||||||
|
"Remove and get the first element in a list, or block until one is available",
|
||||||
|
2,
|
||||||
|
"1.3.1" },
|
||||||
|
{ "BRPOP",
|
||||||
|
"key [key ...] timeout",
|
||||||
|
"Remove and get the last element in a list, or block until one is available",
|
||||||
|
2,
|
||||||
|
"1.3.1" },
|
||||||
|
{ "CONFIG GET",
|
||||||
|
"parameter",
|
||||||
|
"Get the value of a configuration parameter",
|
||||||
|
9,
|
||||||
|
"2.0" },
|
||||||
|
{ "CONFIG SET",
|
||||||
|
"parameter value",
|
||||||
|
"Set a configuration parameter to the given value",
|
||||||
|
9,
|
||||||
|
"2.0" },
|
||||||
|
{ "DBSIZE",
|
||||||
|
"-",
|
||||||
|
"Return the number of keys in the selected database",
|
||||||
|
9,
|
||||||
|
"0.07" },
|
||||||
|
{ "DEBUG OBJECT",
|
||||||
|
"key",
|
||||||
|
"Get debugging information about a key",
|
||||||
|
9,
|
||||||
|
"0.101" },
|
||||||
|
{ "DEBUG SEGFAULT",
|
||||||
|
"-",
|
||||||
|
"Make the server crash",
|
||||||
|
9,
|
||||||
|
"0.101" },
|
||||||
|
{ "DECR",
|
||||||
|
"key decrement",
|
||||||
|
"Decrement the integer value of a key by one",
|
||||||
|
1,
|
||||||
|
"0.07" },
|
||||||
|
{ "DECRBY",
|
||||||
|
"key decrement",
|
||||||
|
"Decrement the integer value of a key by the given number",
|
||||||
|
1,
|
||||||
|
"0.07" },
|
||||||
|
{ "DEL",
|
||||||
|
"key [key ...]",
|
||||||
|
"Delete a key",
|
||||||
|
0,
|
||||||
|
"0.07" },
|
||||||
|
{ "DISCARD",
|
||||||
|
"-",
|
||||||
|
"Discard all commands issued after MULTI",
|
||||||
|
7,
|
||||||
|
"1.3.3" },
|
||||||
|
{ "ECHO",
|
||||||
|
"message",
|
||||||
|
"Echo the given string",
|
||||||
|
8,
|
||||||
|
"0.07" },
|
||||||
|
{ "EXEC",
|
||||||
|
"-",
|
||||||
|
"Execute all commands issued after MULTI",
|
||||||
|
7,
|
||||||
|
"1.1.95" },
|
||||||
|
{ "EXISTS",
|
||||||
|
"key",
|
||||||
|
"Determine if a key exists",
|
||||||
|
9,
|
||||||
|
"0.07" },
|
||||||
|
{ "EXPIRE",
|
||||||
|
"key seconds",
|
||||||
|
"Set a key's time to live in seconds",
|
||||||
|
0,
|
||||||
|
"0.09" },
|
||||||
|
{ "EXPIREAT",
|
||||||
|
"key timestamp",
|
||||||
|
"Set the expiration for a key as a UNIX timestamp",
|
||||||
|
0,
|
||||||
|
"1.1" },
|
||||||
|
{ "FLUSHALL",
|
||||||
|
"-",
|
||||||
|
"Remove all keys from all databases",
|
||||||
|
9,
|
||||||
|
"0.07" },
|
||||||
|
{ "FLUSHDB",
|
||||||
|
"-",
|
||||||
|
"Remove all keys from the current database",
|
||||||
|
9,
|
||||||
|
"0.07" },
|
||||||
|
{ "GET",
|
||||||
|
"key",
|
||||||
|
"Get the value of a key",
|
||||||
|
1,
|
||||||
|
"0.07" },
|
||||||
|
{ "GETSET",
|
||||||
|
"key value",
|
||||||
|
"Set the string value of a key and return its old value",
|
||||||
|
1,
|
||||||
|
"0.091" },
|
||||||
|
{ "HDEL",
|
||||||
|
"key field",
|
||||||
|
"Delete a hash field",
|
||||||
|
5,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "HEXISTS",
|
||||||
|
"key field",
|
||||||
|
"Determine if a hash field exists",
|
||||||
|
5,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "HGET",
|
||||||
|
"key field",
|
||||||
|
"Get the value of a hash field",
|
||||||
|
5,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "HGETALL",
|
||||||
|
"key",
|
||||||
|
"Get all the fields and values in a hash",
|
||||||
|
5,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "HINCRBY",
|
||||||
|
"key field increment",
|
||||||
|
"Increment the integer value of a hash field by the given number",
|
||||||
|
5,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "HKEYS",
|
||||||
|
"key",
|
||||||
|
"Get all the fields in a hash",
|
||||||
|
5,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "HLEN",
|
||||||
|
"key",
|
||||||
|
"Get the number of fields in a hash",
|
||||||
|
5,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "HMGET",
|
||||||
|
"key field [field ...]",
|
||||||
|
"Get the values of all the given hash fields",
|
||||||
|
5,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "HMSET",
|
||||||
|
"key field value [field value ...]",
|
||||||
|
"Set multiple hash fields to multiple values",
|
||||||
|
5,
|
||||||
|
"1.3.8" },
|
||||||
|
{ "HSET",
|
||||||
|
"key field value",
|
||||||
|
"Set the string value of a hash field",
|
||||||
|
5,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "HSETNX",
|
||||||
|
"key field value",
|
||||||
|
"Set the value of a hash field, only if the field does not exist",
|
||||||
|
5,
|
||||||
|
"1.3.8" },
|
||||||
|
{ "HVALS",
|
||||||
|
"key",
|
||||||
|
"Get all the values in a hash",
|
||||||
|
5,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "INCR",
|
||||||
|
"key",
|
||||||
|
"Increment the integer value of a key by one",
|
||||||
|
1,
|
||||||
|
"0.07" },
|
||||||
|
{ "INCRBY",
|
||||||
|
"key increment",
|
||||||
|
"Increment the integer value of a key by the given number",
|
||||||
|
1,
|
||||||
|
"0.07" },
|
||||||
|
{ "INFO",
|
||||||
|
"-",
|
||||||
|
"Get information and statistics about the server",
|
||||||
|
9,
|
||||||
|
"0.07" },
|
||||||
|
{ "KEYS",
|
||||||
|
"pattern",
|
||||||
|
"Find all keys matching the given pattern",
|
||||||
|
0,
|
||||||
|
"0.07" },
|
||||||
|
{ "LASTSAVE",
|
||||||
|
"-",
|
||||||
|
"Get the UNIX time stamp of the last successful save to disk",
|
||||||
|
9,
|
||||||
|
"0.07" },
|
||||||
|
{ "LINDEX",
|
||||||
|
"key index",
|
||||||
|
"Get an element from a list by its index",
|
||||||
|
2,
|
||||||
|
"0.07" },
|
||||||
|
{ "LINSERT",
|
||||||
|
"key BEFORE|AFTER pivot value",
|
||||||
|
"Insert an element before or after another element in a list",
|
||||||
|
2,
|
||||||
|
"2.1.1" },
|
||||||
|
{ "LLEN",
|
||||||
|
"key",
|
||||||
|
"Get the length of a list",
|
||||||
|
2,
|
||||||
|
"0.07" },
|
||||||
|
{ "LPOP",
|
||||||
|
"key",
|
||||||
|
"Remove and get the first element in a list",
|
||||||
|
2,
|
||||||
|
"0.07" },
|
||||||
|
{ "LPUSH",
|
||||||
|
"key value",
|
||||||
|
"Prepend a value to a list",
|
||||||
|
2,
|
||||||
|
"0.07" },
|
||||||
|
{ "LPUSHX",
|
||||||
|
"key value",
|
||||||
|
"Prepend a value to a list, only if the list exists",
|
||||||
|
2,
|
||||||
|
"2.1.1" },
|
||||||
|
{ "LRANGE",
|
||||||
|
"key start stop",
|
||||||
|
"Get a range of elements from a list",
|
||||||
|
2,
|
||||||
|
"0.07" },
|
||||||
|
{ "LREM",
|
||||||
|
"key count value",
|
||||||
|
"Remove elements from a list",
|
||||||
|
2,
|
||||||
|
"0.07" },
|
||||||
|
{ "LSET",
|
||||||
|
"key index value",
|
||||||
|
"Set the value of an element in a list by its index",
|
||||||
|
2,
|
||||||
|
"0.07" },
|
||||||
|
{ "LTRIM",
|
||||||
|
"key start stop",
|
||||||
|
"Trim a list to the specified range",
|
||||||
|
2,
|
||||||
|
"0.07" },
|
||||||
|
{ "MGET",
|
||||||
|
"key [key ...]",
|
||||||
|
"Get the values of all the given keys",
|
||||||
|
1,
|
||||||
|
"0.07" },
|
||||||
|
{ "MONITOR",
|
||||||
|
"-",
|
||||||
|
"Listen for all requests received by the server in real time",
|
||||||
|
9,
|
||||||
|
"0.07" },
|
||||||
|
{ "MOVE",
|
||||||
|
"key db",
|
||||||
|
"Move a key to another database",
|
||||||
|
0,
|
||||||
|
"0.07" },
|
||||||
|
{ "MSET",
|
||||||
|
"key value [key value ...]",
|
||||||
|
"Set multiple keys to multiple values",
|
||||||
|
1,
|
||||||
|
"1.001" },
|
||||||
|
{ "MSETNX",
|
||||||
|
"key value [key value ...]",
|
||||||
|
"Set multiple keys to multiple values, only if none of the keys exist",
|
||||||
|
1,
|
||||||
|
"1.001" },
|
||||||
|
{ "MULTI",
|
||||||
|
"-",
|
||||||
|
"Mark the start of a transaction block",
|
||||||
|
7,
|
||||||
|
"1.1.95" },
|
||||||
|
{ "PERSIST",
|
||||||
|
"key",
|
||||||
|
"Remove the expiration from a key",
|
||||||
|
0,
|
||||||
|
"2.1.2" },
|
||||||
|
{ "PING",
|
||||||
|
"-",
|
||||||
|
"Ping the server",
|
||||||
|
8,
|
||||||
|
"0.07" },
|
||||||
|
{ "PSUBSCRIBE",
|
||||||
|
"pattern",
|
||||||
|
"Listen for messages published to channels matching the given patterns",
|
||||||
|
6,
|
||||||
|
"1.3.8" },
|
||||||
|
{ "PUBLISH",
|
||||||
|
"channel message",
|
||||||
|
"Post a message to a channel",
|
||||||
|
6,
|
||||||
|
"1.3.8" },
|
||||||
|
{ "PUNSUBSCRIBE",
|
||||||
|
"[pattern [pattern ...]]",
|
||||||
|
"Stop listening for messages posted to channels matching the given patterns",
|
||||||
|
6,
|
||||||
|
"1.3.8" },
|
||||||
|
{ "QUIT",
|
||||||
|
"-",
|
||||||
|
"Close the connection",
|
||||||
|
8,
|
||||||
|
"0.07" },
|
||||||
|
{ "RANDOMKEY",
|
||||||
|
"-",
|
||||||
|
"Return a random key from the keyspace",
|
||||||
|
0,
|
||||||
|
"0.07" },
|
||||||
|
{ "RENAME",
|
||||||
|
"old new",
|
||||||
|
"Rename a key",
|
||||||
|
0,
|
||||||
|
"0.07" },
|
||||||
|
{ "RENAMENX",
|
||||||
|
"old new",
|
||||||
|
"Rename a key, only if the new key does not exist",
|
||||||
|
0,
|
||||||
|
"0.07" },
|
||||||
|
{ "RPOP",
|
||||||
|
"key",
|
||||||
|
"Remove and get the last element in a list",
|
||||||
|
2,
|
||||||
|
"0.07" },
|
||||||
|
{ "RPOPLPUSH",
|
||||||
|
"source destination",
|
||||||
|
"Remove the last element in a list, append it to another list and return it",
|
||||||
|
2,
|
||||||
|
"1.1" },
|
||||||
|
{ "RPUSH",
|
||||||
|
"key value",
|
||||||
|
"Append a value to a list",
|
||||||
|
2,
|
||||||
|
"0.07" },
|
||||||
|
{ "RPUSHX",
|
||||||
|
"key value",
|
||||||
|
"Append a value to a list, only if the list exists",
|
||||||
|
2,
|
||||||
|
"2.1.1" },
|
||||||
|
{ "SADD",
|
||||||
|
"key member",
|
||||||
|
"Add a member to a set",
|
||||||
|
3,
|
||||||
|
"0.07" },
|
||||||
|
{ "SAVE",
|
||||||
|
"-",
|
||||||
|
"Synchronously save the dataset to disk",
|
||||||
|
9,
|
||||||
|
"0.07" },
|
||||||
|
{ "SCARD",
|
||||||
|
"key",
|
||||||
|
"Get the number of members in a set",
|
||||||
|
3,
|
||||||
|
"0.07" },
|
||||||
|
{ "SDIFF",
|
||||||
|
"key [key ...]",
|
||||||
|
"Subtract multiple sets",
|
||||||
|
3,
|
||||||
|
"0.100" },
|
||||||
|
{ "SDIFFSTORE",
|
||||||
|
"destination key [key ...]",
|
||||||
|
"Subtract multiple sets and store the resulting set in a key",
|
||||||
|
3,
|
||||||
|
"0.100" },
|
||||||
|
{ "SELECT",
|
||||||
|
"index",
|
||||||
|
"Change the selected database for the current connection",
|
||||||
|
8,
|
||||||
|
"0.07" },
|
||||||
|
{ "SET",
|
||||||
|
"key value",
|
||||||
|
"Set the string value of a key",
|
||||||
|
1,
|
||||||
|
"0.07" },
|
||||||
|
{ "SETEX",
|
||||||
|
"key timestamp value",
|
||||||
|
"Set the value and expiration of a key",
|
||||||
|
1,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "SETNX",
|
||||||
|
"key value",
|
||||||
|
"Set the value of a key, only if the key does not exist",
|
||||||
|
1,
|
||||||
|
"0.07" },
|
||||||
|
{ "SHUTDOWN",
|
||||||
|
"-",
|
||||||
|
"Synchronously save the dataset to disk and then shut down the server",
|
||||||
|
9,
|
||||||
|
"0.07" },
|
||||||
|
{ "SINTER",
|
||||||
|
"key [key ...]",
|
||||||
|
"Intersect multiple sets",
|
||||||
|
3,
|
||||||
|
"0.07" },
|
||||||
|
{ "SINTERSTORE",
|
||||||
|
"destination key [key ...]",
|
||||||
|
"Intersect multiple sets and store the resulting set in a key",
|
||||||
|
3,
|
||||||
|
"0.07" },
|
||||||
|
{ "SISMEMBER",
|
||||||
|
"key member",
|
||||||
|
"Determine if a given value is a member of a set",
|
||||||
|
3,
|
||||||
|
"0.07" },
|
||||||
|
{ "SLAVEOF",
|
||||||
|
"host port",
|
||||||
|
"Make the server a slave of another instance, or promote it as master",
|
||||||
|
9,
|
||||||
|
"0.100" },
|
||||||
|
{ "SMEMBERS",
|
||||||
|
"key",
|
||||||
|
"Get all the members in a set",
|
||||||
|
3,
|
||||||
|
"0.07" },
|
||||||
|
{ "SMOVE",
|
||||||
|
"source destination member",
|
||||||
|
"Move a member from one set to another",
|
||||||
|
3,
|
||||||
|
"0.091" },
|
||||||
|
{ "SORT",
|
||||||
|
"key [BY pattern] [LIMIT start count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]",
|
||||||
|
"Sort the elements in a list, set or sorted set",
|
||||||
|
0,
|
||||||
|
"0.07" },
|
||||||
|
{ "SPOP",
|
||||||
|
"key",
|
||||||
|
"Remove and return a random member from a set",
|
||||||
|
3,
|
||||||
|
"0.101" },
|
||||||
|
{ "SRANDMEMBER",
|
||||||
|
"key",
|
||||||
|
"Get a random member from a set",
|
||||||
|
3,
|
||||||
|
"1.001" },
|
||||||
|
{ "SREM",
|
||||||
|
"key member",
|
||||||
|
"Remove a member from a set",
|
||||||
|
3,
|
||||||
|
"0.07" },
|
||||||
|
{ "STRLEN",
|
||||||
|
"key",
|
||||||
|
"Get the length of the value stored in a key",
|
||||||
|
1,
|
||||||
|
"2.1.2" },
|
||||||
|
{ "SUBSCRIBE",
|
||||||
|
"channel",
|
||||||
|
"Listen for messages published to the given channels",
|
||||||
|
6,
|
||||||
|
"1.3.8" },
|
||||||
|
{ "SUBSTR",
|
||||||
|
"key start stop",
|
||||||
|
"Get a substring of the string stored at a key",
|
||||||
|
1,
|
||||||
|
"1.3.4" },
|
||||||
|
{ "SUNION",
|
||||||
|
"key [key ...]",
|
||||||
|
"Add multiple sets",
|
||||||
|
3,
|
||||||
|
"0.091" },
|
||||||
|
{ "SUNIONSTORE",
|
||||||
|
"destination key [key ...]",
|
||||||
|
"Add multiple sets and store the resulting set in a key",
|
||||||
|
3,
|
||||||
|
"0.091" },
|
||||||
|
{ "SYNC",
|
||||||
|
"-",
|
||||||
|
"Internal command used for replication",
|
||||||
|
9,
|
||||||
|
"0.07" },
|
||||||
|
{ "TTL",
|
||||||
|
"key",
|
||||||
|
"Get the time to live for a key",
|
||||||
|
0,
|
||||||
|
"0.100" },
|
||||||
|
{ "TYPE",
|
||||||
|
"key",
|
||||||
|
"Determine the type stored at key",
|
||||||
|
0,
|
||||||
|
"0.07" },
|
||||||
|
{ "UNSUBSCRIBE",
|
||||||
|
"[channel [channel ...]]",
|
||||||
|
"Stop listening for messages posted to the given channels",
|
||||||
|
6,
|
||||||
|
"1.3.8" },
|
||||||
|
{ "UNWATCH",
|
||||||
|
"-",
|
||||||
|
"Forget about all watched keys",
|
||||||
|
7,
|
||||||
|
"2.1.0" },
|
||||||
|
{ "WATCH",
|
||||||
|
"key [key ...]",
|
||||||
|
"Watch the given keys to determine execution of the MULTI/EXEC block",
|
||||||
|
7,
|
||||||
|
"2.1.0" },
|
||||||
|
{ "ZADD",
|
||||||
|
"key score member",
|
||||||
|
"Add a member to a sorted set, or update its score if it already exists",
|
||||||
|
4,
|
||||||
|
"1.1" },
|
||||||
|
{ "ZCARD",
|
||||||
|
"key",
|
||||||
|
"Get the number of members in a sorted set",
|
||||||
|
4,
|
||||||
|
"1.1" },
|
||||||
|
{ "ZCOUNT",
|
||||||
|
"key min max",
|
||||||
|
"Count the members in a sorted set with scores within the given values",
|
||||||
|
4,
|
||||||
|
"1.3.3" },
|
||||||
|
{ "ZINCRBY",
|
||||||
|
"key increment member",
|
||||||
|
"Increment the score of a member in a sorted set",
|
||||||
|
4,
|
||||||
|
"1.1" },
|
||||||
|
{ "ZINTERSTORE",
|
||||||
|
"destination key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]",
|
||||||
|
"Intersect multiple sorted sets and store the resulting sorted set in a new key",
|
||||||
|
4,
|
||||||
|
"1.3.10" },
|
||||||
|
{ "ZRANGE",
|
||||||
|
"key start stop",
|
||||||
|
"Return a range of members in a sorted set, by index",
|
||||||
|
4,
|
||||||
|
"1.1" },
|
||||||
|
{ "ZRANGEBYSCORE",
|
||||||
|
"key min max",
|
||||||
|
"Return a range of members in a sorted set, by score",
|
||||||
|
4,
|
||||||
|
"1.050" },
|
||||||
|
{ "ZRANK",
|
||||||
|
"key member",
|
||||||
|
"Determine the index of a member in a sorted set",
|
||||||
|
4,
|
||||||
|
"1.3.4" },
|
||||||
|
{ "ZREM",
|
||||||
|
"key member",
|
||||||
|
"Remove a member from a sorted set",
|
||||||
|
4,
|
||||||
|
"1.1" },
|
||||||
|
{ "ZREMRANGEBYRANK",
|
||||||
|
"key start stop",
|
||||||
|
"Remove all members in a sorted set within the given indexes",
|
||||||
|
4,
|
||||||
|
"1.3.4" },
|
||||||
|
{ "ZREMRANGEBYSCORE",
|
||||||
|
"key min max",
|
||||||
|
"Remove all members in a sorted set within the given scores",
|
||||||
|
4,
|
||||||
|
"1.1" },
|
||||||
|
{ "ZREVRANGE",
|
||||||
|
"key start stop",
|
||||||
|
"Return a range of members in a sorted set, by index, with scores ordered from high to low",
|
||||||
|
4,
|
||||||
|
"1.1" },
|
||||||
|
{ "ZREVRANK",
|
||||||
|
"key member",
|
||||||
|
"Determine the index of a member in a sorted set, with scores ordered from high to low",
|
||||||
|
4,
|
||||||
|
"1.3.4" },
|
||||||
|
{ "ZSCORE",
|
||||||
|
"key member",
|
||||||
|
"Get the score associated with the given member in a sorted set",
|
||||||
|
4,
|
||||||
|
"1.1" },
|
||||||
|
{ "ZUNIONSTORE",
|
||||||
|
"destination key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]",
|
||||||
|
"Add multiple sorted sets and store the resulting sorted set in a new key",
|
||||||
|
4,
|
||||||
|
"1.3.10" }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
170
src/redis-cli.c
170
src/redis-cli.c
@ -39,11 +39,13 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "hiredis.h"
|
#include "hiredis.h"
|
||||||
#include "sds.h"
|
#include "sds.h"
|
||||||
#include "zmalloc.h"
|
#include "zmalloc.h"
|
||||||
#include "linenoise.h"
|
#include "linenoise.h"
|
||||||
|
#include "help.h"
|
||||||
|
|
||||||
#define REDIS_NOTUSED(V) ((void) V)
|
#define REDIS_NOTUSED(V) ((void) V)
|
||||||
|
|
||||||
@ -83,6 +85,149 @@ static long long mstime(void) {
|
|||||||
return mst;
|
return mst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* Help functions
|
||||||
|
*--------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define CLI_HELP_COMMAND 1
|
||||||
|
#define CLI_HELP_GROUP 2
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int type;
|
||||||
|
int argc;
|
||||||
|
sds *argv;
|
||||||
|
sds full;
|
||||||
|
|
||||||
|
/* Only used for help on commands */
|
||||||
|
struct commandHelp *org;
|
||||||
|
} helpEntry;
|
||||||
|
|
||||||
|
static helpEntry *helpEntries;
|
||||||
|
static int helpEntriesLen;
|
||||||
|
|
||||||
|
static void cliInitHelp() {
|
||||||
|
int commandslen = sizeof(commandHelp)/sizeof(struct commandHelp);
|
||||||
|
int groupslen = sizeof(commandGroups)/sizeof(char*);
|
||||||
|
int i, len, pos = 0;
|
||||||
|
helpEntry tmp;
|
||||||
|
|
||||||
|
helpEntriesLen = len = commandslen+groupslen;
|
||||||
|
helpEntries = malloc(sizeof(helpEntry)*len);
|
||||||
|
|
||||||
|
for (i = 0; i < groupslen; i++) {
|
||||||
|
tmp.argc = 1;
|
||||||
|
tmp.argv = malloc(sizeof(sds));
|
||||||
|
tmp.argv[0] = sdscatprintf(sdsempty(),"@%s",commandGroups[i]);
|
||||||
|
tmp.full = tmp.argv[0];
|
||||||
|
tmp.type = CLI_HELP_GROUP;
|
||||||
|
tmp.org = NULL;
|
||||||
|
helpEntries[pos++] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < commandslen; i++) {
|
||||||
|
tmp.argv = sdssplitargs(commandHelp[i].name,&tmp.argc);
|
||||||
|
tmp.full = sdsnew(commandHelp[i].name);
|
||||||
|
tmp.type = CLI_HELP_COMMAND;
|
||||||
|
tmp.org = &commandHelp[i];
|
||||||
|
helpEntries[pos++] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output command help to stdout. */
|
||||||
|
static void cliOutputCommandHelp(struct commandHelp *help, int group) {
|
||||||
|
printf("\r\n \x1b[1m%s\x1b[0m \x1b[90m%s\x1b[0m\r\n", help->name, help->params);
|
||||||
|
printf(" \x1b[33msummary:\x1b[0m %s\r\n", help->summary);
|
||||||
|
printf(" \x1b[33msince:\x1b[0m %s\r\n", help->since);
|
||||||
|
if (group) {
|
||||||
|
printf(" \x1b[33mgroup:\x1b[0m %s\r\n", commandGroups[help->group]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print generic help. */
|
||||||
|
static void cliOutputGenericHelp() {
|
||||||
|
printf(
|
||||||
|
"redis-cli %s\r\n"
|
||||||
|
"Type: \"help @<group>\" to get a list of commands in <group>\r\n"
|
||||||
|
" \"help <command>\" for help on <command>\r\n"
|
||||||
|
" \"help <tab>\" to get a list of possible help topics\r\n"
|
||||||
|
" \"quit\" to exit\r\n",
|
||||||
|
REDIS_VERSION
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output all command help, filtering by group or command name. */
|
||||||
|
static void cliOutputHelp(int argc, char **argv) {
|
||||||
|
int i, j, len;
|
||||||
|
int group = -1;
|
||||||
|
helpEntry *entry;
|
||||||
|
struct commandHelp *help;
|
||||||
|
|
||||||
|
if (argc == 0) {
|
||||||
|
cliOutputGenericHelp();
|
||||||
|
return;
|
||||||
|
} else if (argc > 0 && argv[0][0] == '@') {
|
||||||
|
len = sizeof(commandGroups)/sizeof(char*);
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if (strcasecmp(argv[0]+1,commandGroups[i]) == 0) {
|
||||||
|
group = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(argc > 0);
|
||||||
|
for (i = 0; i < helpEntriesLen; i++) {
|
||||||
|
entry = &helpEntries[i];
|
||||||
|
if (entry->type != CLI_HELP_COMMAND) continue;
|
||||||
|
|
||||||
|
help = entry->org;
|
||||||
|
if (group == -1) {
|
||||||
|
/* Compare all arguments */
|
||||||
|
if (argc == entry->argc) {
|
||||||
|
for (j = 0; j < argc; j++) {
|
||||||
|
if (strcasecmp(argv[j],entry->argv[j]) != 0) break;
|
||||||
|
}
|
||||||
|
if (j == argc) {
|
||||||
|
cliOutputCommandHelp(help,1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (group == help->group) {
|
||||||
|
cliOutputCommandHelp(help,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void completionCallback(const char *buf, linenoiseCompletions *lc) {
|
||||||
|
size_t startpos = 0;
|
||||||
|
int mask;
|
||||||
|
int i;
|
||||||
|
size_t matchlen;
|
||||||
|
sds tmp;
|
||||||
|
|
||||||
|
if (strncasecmp(buf,"help ",5) == 0) {
|
||||||
|
startpos = 5;
|
||||||
|
while (isspace(buf[startpos])) startpos++;
|
||||||
|
mask = CLI_HELP_COMMAND | CLI_HELP_GROUP;
|
||||||
|
} else {
|
||||||
|
mask = CLI_HELP_COMMAND;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < helpEntriesLen; i++) {
|
||||||
|
if (!(helpEntries[i].type & mask)) continue;
|
||||||
|
|
||||||
|
matchlen = strlen(buf+startpos);
|
||||||
|
if (strncasecmp(buf+startpos,helpEntries[i].full,matchlen) == 0) {
|
||||||
|
tmp = sdsnewlen(buf,startpos);
|
||||||
|
tmp = sdscat(tmp,helpEntries[i].full);
|
||||||
|
linenoiseAddCompletion(lc,tmp);
|
||||||
|
sdsfree(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Networking / parsing
|
* Networking / parsing
|
||||||
*--------------------------------------------------------------------------- */
|
*--------------------------------------------------------------------------- */
|
||||||
@ -252,22 +397,6 @@ static int cliReadReply() {
|
|||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void showInteractiveHelp(void) {
|
|
||||||
printf(
|
|
||||||
"\n"
|
|
||||||
"Welcome to redis-cli " REDIS_VERSION "!\n"
|
|
||||||
"Just type any valid Redis command to see a pretty printed output.\n"
|
|
||||||
"\n"
|
|
||||||
"It is possible to quote strings, like in:\n"
|
|
||||||
" set \"my key\" \"some string \\xff\\n\"\n"
|
|
||||||
"\n"
|
|
||||||
"You can find a list of valid Redis commands at\n"
|
|
||||||
" http://code.google.com/p/redis/wiki/CommandReference\n"
|
|
||||||
"\n"
|
|
||||||
"Note: redis-cli supports line editing, use up/down arrows for history."
|
|
||||||
"\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static int cliSendCommand(int argc, char **argv, int repeat) {
|
static int cliSendCommand(int argc, char **argv, int repeat) {
|
||||||
char *command = argv[0];
|
char *command = argv[0];
|
||||||
size_t *argvlen;
|
size_t *argvlen;
|
||||||
@ -279,8 +408,8 @@ static int cliSendCommand(int argc, char **argv, int repeat) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config.raw_output = !strcasecmp(command,"info");
|
config.raw_output = !strcasecmp(command,"info");
|
||||||
if (!strcasecmp(command,"help")) {
|
if (!strcasecmp(command,"help") || !strcasecmp(command,"?")) {
|
||||||
showInteractiveHelp();
|
cliOutputHelp(--argc, ++argv);
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
if (!strcasecmp(command,"shutdown")) config.shutdown = 1;
|
if (!strcasecmp(command,"shutdown")) config.shutdown = 1;
|
||||||
@ -412,6 +541,8 @@ static void repl() {
|
|||||||
sds *argv;
|
sds *argv;
|
||||||
|
|
||||||
config.interactive = 1;
|
config.interactive = 1;
|
||||||
|
linenoiseSetCompletionCallback(completionCallback);
|
||||||
|
|
||||||
while((line = linenoise(context ? "redis> " : "not connected> ")) != NULL) {
|
while((line = linenoise(context ? "redis> " : "not connected> ")) != NULL) {
|
||||||
if (line[0] != '\0') {
|
if (line[0] != '\0') {
|
||||||
argv = sdssplitargs(line,&argc);
|
argv = sdssplitargs(line,&argc);
|
||||||
@ -430,6 +561,8 @@ static void repl() {
|
|||||||
config.hostip = sdsnew(argv[1]);
|
config.hostip = sdsnew(argv[1]);
|
||||||
config.hostport = atoi(argv[2]);
|
config.hostport = atoi(argv[2]);
|
||||||
cliConnect(1);
|
cliConnect(1);
|
||||||
|
} else if (argc == 1 && !strcasecmp(argv[0],"clear")) {
|
||||||
|
linenoiseClearScreen();
|
||||||
} else {
|
} else {
|
||||||
long long start_time = mstime(), elapsed;
|
long long start_time = mstime(), elapsed;
|
||||||
|
|
||||||
@ -489,6 +622,7 @@ int main(int argc, char **argv) {
|
|||||||
config.historyfile = NULL;
|
config.historyfile = NULL;
|
||||||
config.tty = isatty(fileno(stdout)) || (getenv("FAKETTY") != NULL);
|
config.tty = isatty(fileno(stdout)) || (getenv("FAKETTY") != NULL);
|
||||||
config.mb_sep = '\n';
|
config.mb_sep = '\n';
|
||||||
|
cliInitHelp();
|
||||||
|
|
||||||
if (getenv("HOME") != NULL) {
|
if (getenv("HOME") != NULL) {
|
||||||
config.historyfile = malloc(256);
|
config.historyfile = malloc(256);
|
||||||
|
111
utils/generate-command-help.rb
Executable file
111
utils/generate-command-help.rb
Executable file
@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
GROUPS = [
|
||||||
|
"generic",
|
||||||
|
"string",
|
||||||
|
"list",
|
||||||
|
"set",
|
||||||
|
"sorted_set",
|
||||||
|
"hash",
|
||||||
|
"pubsub",
|
||||||
|
"transactions",
|
||||||
|
"connection",
|
||||||
|
"server"
|
||||||
|
].freeze
|
||||||
|
|
||||||
|
GROUPS_BY_NAME = Hash[*
|
||||||
|
GROUPS.each_with_index.map do |n,i|
|
||||||
|
[n,i]
|
||||||
|
end.flatten
|
||||||
|
].freeze
|
||||||
|
|
||||||
|
def argument arg
|
||||||
|
name = arg["name"].is_a?(Array) ? arg["name"].join(" ") : arg["name"]
|
||||||
|
name = arg["enum"].join "|" if "enum" == arg["type"]
|
||||||
|
name = arg["command"] + " " + name if arg["command"]
|
||||||
|
if arg["multiple"]
|
||||||
|
name = "#{name} [#{name} ...]"
|
||||||
|
end
|
||||||
|
if arg["optional"]
|
||||||
|
name = "[#{name}]"
|
||||||
|
end
|
||||||
|
name
|
||||||
|
end
|
||||||
|
|
||||||
|
def arguments command
|
||||||
|
return "-" unless command["arguments"]
|
||||||
|
command["arguments"].map do |arg|
|
||||||
|
argument arg
|
||||||
|
end.join " "
|
||||||
|
end
|
||||||
|
|
||||||
|
def commands
|
||||||
|
return @commands if @commands
|
||||||
|
|
||||||
|
require "net/http"
|
||||||
|
require "net/https"
|
||||||
|
require "json"
|
||||||
|
require "uri"
|
||||||
|
|
||||||
|
url = URI.parse "https://github.com/antirez/redis-doc/raw/master/commands.json"
|
||||||
|
client = Net::HTTP.new url.host, url.port
|
||||||
|
client.use_ssl = true
|
||||||
|
response = client.get url.path
|
||||||
|
if response.is_a?(Net::HTTPSuccess)
|
||||||
|
@commands = JSON.parse(response.body)
|
||||||
|
else
|
||||||
|
response.error!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_groups
|
||||||
|
GROUPS.map do |n|
|
||||||
|
"\"#{n}\""
|
||||||
|
end.join(",\n ");
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_commands
|
||||||
|
commands.to_a.sort do |x,y|
|
||||||
|
x[0] <=> y[0]
|
||||||
|
end.map do |key, command|
|
||||||
|
group = GROUPS_BY_NAME[command["group"]]
|
||||||
|
if group.nil?
|
||||||
|
STDERR.puts "Please update groups array in #{__FILE__}"
|
||||||
|
raise "Unknown group #{command["group"]}"
|
||||||
|
end
|
||||||
|
|
||||||
|
ret = <<-SPEC
|
||||||
|
{ "#{key}",
|
||||||
|
"#{arguments(command)}",
|
||||||
|
"#{command["summary"]}",
|
||||||
|
#{group},
|
||||||
|
"#{command["since"]}" }
|
||||||
|
SPEC
|
||||||
|
ret.strip
|
||||||
|
end.join(",\n ")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Write to stdout
|
||||||
|
puts <<-HELP_H
|
||||||
|
/* Automatically generated by #{__FILE__}, do not edit. */
|
||||||
|
|
||||||
|
#ifndef __REDIS_HELP_H
|
||||||
|
#define __REDIS_HELP_H
|
||||||
|
|
||||||
|
static char *commandGroups[] = {
|
||||||
|
#{generate_groups}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct commandHelp {
|
||||||
|
char *name;
|
||||||
|
char *params;
|
||||||
|
char *summary;
|
||||||
|
int group;
|
||||||
|
char *since;
|
||||||
|
} commandHelp[] = {
|
||||||
|
#{generate_commands}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
HELP_H
|
||||||
|
|
Loading…
Reference in New Issue
Block a user