This is simple key-value database made specially for SecondLife LSL scripts.
https://sldb.app/key?password=pass
- or -
https://sldb.app/avatar-uuid/key?password=pass
HTTP methods:
Response HTTP status codes:
If you use DB from SecondLife script using llHTTPRequest, you can use short URL - your object's owner will be auto-detected.
All records can be read from Internet with full URL, but no update or delete allowed.
There's special key: __list. It allows you to see all keys (via GET request) or delete them (via DELETE request). No POST or PUT methods allowed for this key.
Password is optional and should be set for single key. Password-protected records cannot be read without password. You can send password as query parameter or in X-Password header.
Password can be set with POST and PUT requests. If you set new password with PUT request, old data will be cleared.
Max key size: 256 bytes. Keys can include only latin letters, numbers, dash and underdash characters (/^[\w\d\-_]+$/i).
Max value size: 32kb. But please don't overuse it. Any UTF-8 characters, binary data is not supported.
Max password size: 256 bytes.
24.02.2019 Added links and timestamps (braced, at begin of lines) formatting for web viewer.
25.07.2018 Using owner key instead of object key now. Behavior changed, because found unexpected and undocumented behavior: attached object key is changed after relog. Using owner key is not secure and can cause intersections, but it will be more convenient in same time.
20.02.2022 I am very sorry. There were problems in datacenter and whole SLDB was lost. The project was rewritten from zero and deployed to a cloud with regular backups to prevent such outages again.
string g_sPassword = "";
string g_sKey;
string g_sCommand;
key g_kRequestId;
string dbURL(string sKey) {
return "https://sldb.app/" + llEscapeURL(sKey) + "?password=" + llEscapeURL(g_sPassword);
}
default
{
state_entry() {
llListen(11, "", llGetOwner(), "");
}
listen(integer iChannel, string sName, key kId, string sMsg) {
list lParams = llParseStringKeepNulls(sMsg, [" "], []);
string sCmd = llList2String(lParams, 0);
string sKey = llList2String(lParams, 1);
if (sCmd == "password") {
g_sPassword = sKey;
} else if (sCmd == "get") {
g_sKey = sKey;
g_sCommand = "get";
g_kRequestId = llHTTPRequest(dbURL(sKey), [HTTP_METHOD, "GET"], "");
} else if (sCmd == "set") {
string sValue = llDumpList2String(llDeleteSubList(lParams, 0, 1), " ");
g_sKey = sKey;
g_sCommand = "set";
g_kRequestId = llHTTPRequest(dbURL(sKey), [HTTP_METHOD, "POST"], sValue);
} else if (sCmd == "append") {
string sValue = llDumpList2String(llDeleteSubList(lParams, 0, 1), " ");
g_sKey = sKey;
g_sCommand = "append";
g_kRequestId = llHTTPRequest(dbURL(sKey), [HTTP_METHOD, "PUT"], sValue);
} else if (sCmd == "delete") {
g_sKey = sKey;
g_sCommand = "delete";
g_kRequestId = llHTTPRequest(dbURL(sKey), [HTTP_METHOD, "DELETE"], "");
}
}
http_response(key kRequestId, integer iStatus, list lMetaData, string sBody) {
if (kRequestId != g_kRequestId)
return;
string sStatus = "";
if (iStatus == 200) sStatus = "OK";
else if (iStatus == 400) sStatus = "invalid request";
else if (iStatus == 403) sStatus = "invalid password";
else if (iStatus == 404) sStatus = "record not found";
else if (iStatus == 500) sStatus = "server-side error";
else sStatus = (string)iStatus;
llOwnerSay("Done. Command: " + g_sCommand + ", key: " + g_sKey + ", status: " + sStatus + ".\nData:\n" + sBody);
}
}