LlUpdateKeyValue
首页 | 函数 | 事件 | 类型 | 操作符 | 常数 | Flow Control | Script Library | Categorized Library | Tutorials |
函数名 |
---|
Function: key llUpdateKeyValue( string k, string v, integer checked, string original_value ); |
参数:•字符串k(string k)–键值对的键
•字符串v(string v)–键值对的值。最多2047个字符,如果使用单声道,则为4095个字符。 •整数已检查(integer checked)–如果为真,则只有原始_值与键值存储区中的值匹配时才会进行更新。 •字符串原始值(string original_value)–要与键值存储区中的当前值进行比较的值。 如果checked设置为TRUE,则只有当原始值与键值存储区中的当前值匹配时,才会进行更新,否则数据服务器将返回失败,并返回错误XP_error_RETRY_update。这可以用来创建一个正在使用的标志,这样就可以实现原子性。 |
返回值:返回一个句柄(键),该句柄可用于标识相应的数据服务器事件,以确定此命令是成功还是失败以及结果。
截至2016年1月1日,LSO和Mono脚本的最大字节数分别为1011和4095。 使用llUpdateKeyValue更新不存在的密钥将不会生成XP\u ERROR\u key unt\u FOUND。相反,它将生成一个具有指定值的新键,就像您使用了llCreateKeyValue一样。 要使此功能正常工作,必须将脚本编译为一个体验Experience。 |
注意事项 |
---|
数据服务器回调参数为:
包含从llUpdateKeyValue返回的句柄的键 包含逗号分隔列表(cdl)的字符串。llDumpList2String([integer success]+组件); 组件根据请求的成功或失败而变化。 失败:cdl=llDumpList2String([0,整数错误],“,”) 成功:cdl=llDumpList2String([1,字符串值],“,”) 字符串组件 •整数成功–一个布尔值,指定事务是否成功(1)或否(0)。 •整数错误–描述操作失败原因的XP_error_x标志。 •字符串值–键值对的值。最多2047个字符,如果使用单声道,则为4095个字符。注意!此值可能包含逗号。 如果重新编译以前与体验相关联的脚本,但对缺乏将脚本编译为体验能力的客户端执行此操作,则该脚本将丢失关联的体验。 由于llKeysKeyValue以CSV格式返回密钥,建议密钥不包含逗号。 |
示例 |
---|
示例1
key trans; default { state_entry() { trans = llUpdateKeyValue("FOO", "BLAH", TRUE, "BAR"); } dataserver(key t, string value) { if (t == trans) { // our llUpdateKeyValue transaction is done list result = llCSV2List(value); if (llList2Integer(result, 0) == 1) { // the key-value pair was successfully updated llSay(0, "New key-value pair was successfully updated"); } else { integer error = llList2Integer(result, 1); if(error == XP_ERROR_RETRY_UPDATE) llSay(0, "Key-value update failed, checked value is out of date"); else llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(error) ); } } } } This script demonstrates how to avoid update conflicts (two scripts updating the store at the same time), performing fully atomic updates is more complicated. If all scripts writing to the key-value store abide by the virtual lock ($DB_Lock), and only do updates in update_db state, then all writes will be atomic. key tid; list tids; default { state_entry() { state lock_db; } } state lock_db { state_entry() { tid = llUpdateKeyValue("$DB_Lock", "LOCK", TRUE, "unlock"); } dataserver(key did, string value) { if(did == tid) { string payload = llDeleteSubString(value, 0, 1); if(llGetSubString(value+",", 0, 1) == "1,"){ llUpdateKeyValue("$DB_LockedBy", llDumpList2String([llGetOwner(),llGetKey(),llGetLinkKey(!!llGetLinkNumber()),llGetRegionName(),llGetPos(),llGetAttached()],":"), FALSE, ""); state update_db; } else { integer err = (integer)payload; if(err == XP_ERROR_RETRY_UPDATE) { llSay(0, "Database is already locked!"); } else { llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(err) ); } state error; } } } } state update_db { state_entry() { tids = [ llUpdateKeyValue("CatsPermissable", "5", FALSE, ""), llUpdateKeyValue("MonkeyMutations", "3", FALSE, ""), llUpdateKeyValue("CodFlavorSupport", "NEVER", FALSE, "") ]; } dataserver(key did, string value) { integer i = llListFindList(tid, [did]); if(~i) { string payload = llDeleteSubString(value, 0, 1); if(llGetSubString(value+",", 0, 1) == "1,"){ tids = llDeleteSubList(tids, i, i); if(tids == []) { state unlock_db; } } else { llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage((integer)payload) ); state error; } } } } state unlock_db { state_entry() { tid = llUpdateKeyValue("$DB_Lock", "unlock", TRUE, "LOCK"); } dataserver(key did, string value) { if(did == tid) { string payload = llDeleteSubString(value, 0, 1); if(llGetSubString(value+",", 0, 1) == "1,"){ state done; } else { integer err = (integer)payload; if(err == XP_ERROR_RETRY_UPDATE) { llSay(0, "Someone has violated the database lock!"); } else { llSay(0, "Key-value update failed: " + llGetExperienceErrorMessage(err) ); } state error; } } } } state done { state_entry(){;} } state error { state_entry(){;} } |
相关函数 |
---|
llGetExperienceErrorMessage |
相关事件 |
---|
无 |