今天来看看select命令。我现在是感觉Redis博大精深,想要在短期内完全搞透这个软件不是那么容易啊!!!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我之前就很纳闷,server.db有16个成员,为啥每次client提交的请求,server都用第0号成员,
现在看到了select命令,我和我的小伙伴们终于被惊呆了!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void selectCommand(redisClient *c)
{
long id;
if (getLongFromObjectOrReply(c, c->argv[1], &id,
"invalid DB index") != REDIS_OK)
return;
if (selectDb(c,id) == REDIS_ERR)
{
addReplyError(c,"invalid DB index");
}
else
{
addReply(c,shared.ok);
}
}
//自定义检查点: 1 2 3
long id;
//定义一个整型变量
//自定义检查点: 1 2 3
~~~~~~~~~~~~~~~~~~~~~~~~
然后看一下getLongFromObjectOrReply函数,这个函数是调用了getLongLongFromObjectOrReply
好吧,再看看getLongLongFromObjectOrReply函数,要命,这个函数调用了getLongLongFromObject
~~~~~~~~~~~~~~~~~~~
int getLongLongFromObject(robj *o, long long *target)
{
//自定义检查点: 1 2 3
long long value;
//--->值
char *eptr;
//自定义检查点: 1 2 3
if (o == NULL)
{
value = 0;
}
//对无效的指针,设置返回值为 0
//自定义检查点: 1 2 3
else
{
redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);
//有效性验证
if (o->encoding == REDIS_ENCODING_RAW)
{ //如果是RAW方式的对象
errno = 0;
value = strtoll(o->ptr, &eptr, 10);
//提取值
if (isspace(((char*)o->ptr)[0]) || eptr[0] != '\0' ||
errno == ERANGE)
return REDIS_ERR;
//自定义检查点: 1 2 3
}
else if (o->encoding == REDIS_ENCODING_INT)
{
value = (long)o->ptr;
//直接做一个转化,指针转化成数字
//这个方法我以前在单位写平台也用过
//自定义检查点: 1 2 3
}
else
{
redisPanic("Unknown string encoding");
}
}
if (target) *target = value;
//把值设置给返回值
return REDIS_OK;
//自定义检查点: 1 2 3
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
回到函数getLongLongFromObjectOrReply
剩下的没啥好说的了。
回到函数getLongFromObjectOrReply
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
getLongFromObjectOrReply剩下的代码也没啥好说的了。
好,终于回到selectCommand函数来。
则,id存储了参数数字
然后调用selectDb函数
~~~~~~~~~~~~~~·
核心代码就一行:c->db = &server.db[id];
总结:select命令的用法
client: select id(0,1,2...)
server: "+OK\r\n"
啊,生活如此美好!