@iobroker/db-objects-redis 7.2.3 → 8.0.0-alpha.2-20260923-99da17fcc

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/build/cjs/index.d.ts +1 -1
  2. package/build/cjs/index.js +5 -3
  3. package/build/cjs/index.js.map +2 -2
  4. package/build/cjs/lib/objects/constants.js.map +2 -2
  5. package/build/cjs/lib/objects/interview.js +2 -0
  6. package/build/cjs/lib/objects/interview.js.map +1 -1
  7. package/build/cjs/lib/objects/lua-v3/custom.lua +23 -1
  8. package/build/cjs/lib/objects/lua-v3/filter.lua +23 -1
  9. package/build/cjs/lib/objects/lua-v3/programs.lua +23 -1
  10. package/build/cjs/lib/objects/lua-v3/script.lua +23 -1
  11. package/build/cjs/lib/objects/lua-v3/variables.lua +23 -1
  12. package/build/cjs/lib/objects/lua-v4/custom.lua +23 -1
  13. package/build/cjs/lib/objects/lua-v4/filter.lua +23 -1
  14. package/build/cjs/lib/objects/lua-v4/programs.lua +23 -1
  15. package/build/cjs/lib/objects/lua-v4/script.lua +23 -1
  16. package/build/cjs/lib/objects/lua-v4/variables.lua +23 -1
  17. package/build/cjs/lib/objects/lua-v4-no-sets/custom.lua +23 -1
  18. package/build/cjs/lib/objects/lua-v4-no-sets/filter.lua +23 -1
  19. package/build/cjs/lib/objects/lua-v4-no-sets/programs.lua +23 -1
  20. package/build/cjs/lib/objects/lua-v4-no-sets/script.lua +23 -1
  21. package/build/cjs/lib/objects/lua-v4-no-sets/variables.lua +23 -1
  22. package/build/cjs/lib/objects/objectsInRedisClient.d.ts +961 -125
  23. package/build/cjs/lib/objects/objectsInRedisClient.js +1092 -776
  24. package/build/cjs/lib/objects/objectsInRedisClient.js.map +3 -3
  25. package/build/cjs/lib/objects/objectsUtils.d.ts +139 -17
  26. package/build/cjs/lib/objects/objectsUtils.js +212 -192
  27. package/build/cjs/lib/objects/objectsUtils.js.map +3 -3
  28. package/build/esm/index.d.ts +1 -1
  29. package/build/esm/index.d.ts.map +1 -1
  30. package/build/esm/index.js.map +1 -1
  31. package/build/esm/lib/objects/constants.d.ts.map +1 -1
  32. package/build/esm/lib/objects/constants.js.map +1 -1
  33. package/build/esm/lib/objects/lua-v3/custom.lua +23 -1
  34. package/build/esm/lib/objects/lua-v3/filter.lua +23 -1
  35. package/build/esm/lib/objects/lua-v3/programs.lua +23 -1
  36. package/build/esm/lib/objects/lua-v3/script.lua +23 -1
  37. package/build/esm/lib/objects/lua-v3/variables.lua +23 -1
  38. package/build/esm/lib/objects/lua-v4/custom.lua +23 -1
  39. package/build/esm/lib/objects/lua-v4/filter.lua +23 -1
  40. package/build/esm/lib/objects/lua-v4/programs.lua +23 -1
  41. package/build/esm/lib/objects/lua-v4/script.lua +23 -1
  42. package/build/esm/lib/objects/lua-v4/variables.lua +23 -1
  43. package/build/esm/lib/objects/lua-v4-no-sets/custom.lua +23 -1
  44. package/build/esm/lib/objects/lua-v4-no-sets/filter.lua +23 -1
  45. package/build/esm/lib/objects/lua-v4-no-sets/programs.lua +23 -1
  46. package/build/esm/lib/objects/lua-v4-no-sets/script.lua +23 -1
  47. package/build/esm/lib/objects/lua-v4-no-sets/variables.lua +23 -1
  48. package/build/esm/lib/objects/objectsInRedisClient.d.ts +961 -125
  49. package/build/esm/lib/objects/objectsInRedisClient.d.ts.map +1 -1
  50. package/build/esm/lib/objects/objectsInRedisClient.js +880 -571
  51. package/build/esm/lib/objects/objectsInRedisClient.js.map +1 -1
  52. package/build/esm/lib/objects/objectsUtils.d.ts +139 -17
  53. package/build/esm/lib/objects/objectsUtils.d.ts.map +1 -1
  54. package/build/esm/lib/objects/objectsUtils.js +273 -221
  55. package/build/esm/lib/objects/objectsUtils.js.map +1 -1
  56. package/build/tsconfig.build.tsbuildinfo +1 -1
  57. package/package.json +9 -9
@@ -5,7 +5,7 @@
5
5
  */
6
6
  export declare function getDefaultPort(host: string): number;
7
7
  export declare const Server: null;
8
- export { ObjectsInRedisClient as Client } from './lib/objects/objectsInRedisClient.js';
8
+ export { ObjectsInRedisClient as Client, type ObjectsSettings } from './lib/objects/objectsInRedisClient.js';
9
9
  export { interview } from './lib/objects/interview.js';
10
10
  export * as objectsUtils from './lib/objects/objectsUtils.js';
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -5,6 +5,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
9
  var __export = (target, all) => {
9
10
  for (var name in all)
10
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -26,21 +27,22 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
27
  mod
27
28
  ));
28
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var esm_exports = {};
30
- __export(esm_exports, {
30
+ var index_exports = {};
31
+ __export(index_exports, {
31
32
  Client: () => import_objectsInRedisClient.ObjectsInRedisClient,
32
33
  Server: () => Server,
33
34
  getDefaultPort: () => getDefaultPort,
34
35
  interview: () => import_interview.interview,
35
36
  objectsUtils: () => objectsUtils
36
37
  });
37
- module.exports = __toCommonJS(esm_exports);
38
+ module.exports = __toCommonJS(index_exports);
38
39
  var import_objectsInRedisClient = require("./lib/objects/objectsInRedisClient.js");
39
40
  var import_interview = require("./lib/objects/interview.js");
40
41
  var objectsUtils = __toESM(require("./lib/objects/objectsUtils.js"), 1);
41
42
  function getDefaultPort(host) {
42
43
  return host.includes(",") ? 26379 : 6379;
43
44
  }
45
+ __name(getDefaultPort, "getDefaultPort");
44
46
  const Server = null;
45
47
  // Annotate the CommonJS export names for ESM import in node:
46
48
  0 && (module.exports = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["/// <reference types=\"@iobroker/types-dev\" />\n/**\n * Get the default port for the database\n *\n * @param host string of host(s)\n */\nexport function getDefaultPort(host: string): number {\n return host.includes(',') ? 26379 : 6379;\n}\nexport const Server = null;\nexport { ObjectsInRedisClient as Client } from '@/lib/objects/objectsInRedisClient.js';\nexport { interview } from '@/lib/objects/interview.js';\nexport * as objectsUtils from '@/lib/objects/objectsUtils.js';\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;AAUA,kCAA+C;AAC/C,uBAA0B;AAC1B,mBAA8B;AANxB,SAAU,eAAe,MAAY;AACvC,SAAO,KAAK,SAAS,GAAG,IAAI,QAAQ;AACxC;AACO,MAAM,SAAS;",
4
+ "sourcesContent": ["/// <reference types=\"@iobroker/types-dev\" />\n/**\n * Get the default port for the database\n *\n * @param host string of host(s)\n */\nexport function getDefaultPort(host: string): number {\n return host.includes(',') ? 26379 : 6379;\n}\nexport const Server = null;\nexport { ObjectsInRedisClient as Client, type ObjectsSettings } from '@/lib/objects/objectsInRedisClient.js';\nexport { interview } from '@/lib/objects/interview.js';\nexport * as objectsUtils from '@/lib/objects/objectsUtils.js';\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;AAUA,kCAAqE;AACrE,uBAA0B;AAC1B,mBAA8B;AANxB,SAAU,eAAe,MAAY;AACvC,SAAO,KAAK,SAAS,GAAG,IAAI,QAAQ;AACxC;AAFgB;AAGT,MAAM,SAAS;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/objects/constants.ts"],
4
- "sourcesContent": ["export enum ERRORS {\n ERROR_PERMISSION = 'permissionError',\n ERROR_NOT_FOUND = 'Not exists',\n ERROR_DB_CLOSED = 'DB closed',\n}\n\nexport const SYSTEM_ADMIN_USER = 'system.user.admin';\nexport const SYSTEM_ADMIN_GROUP = 'system.group.administrator';\n\nexport const ACCESS_EVERY_EXEC = 0x1;\nexport const ACCESS_EVERY_WRITE = 0x2;\nexport const ACCESS_EVERY_READ = 0x4;\nexport const ACCESS_EVERY_RW = ACCESS_EVERY_WRITE | ACCESS_EVERY_READ;\nexport const ACCESS_EVERY_ALL = ACCESS_EVERY_WRITE | ACCESS_EVERY_READ | ACCESS_EVERY_EXEC;\n\nexport const ACCESS_GROUP_EXEC = 0x10;\nexport const ACCESS_GROUP_WRITE = 0x20;\nexport const ACCESS_GROUP_READ = 0x40;\nexport const ACCESS_GROUP_RW = ACCESS_GROUP_WRITE | ACCESS_GROUP_READ;\nexport const ACCESS_GROUP_ALL = ACCESS_GROUP_WRITE | ACCESS_GROUP_READ | ACCESS_GROUP_EXEC;\n\nexport const ACCESS_USER_EXEC = 0x100;\nexport const ACCESS_USER_WRITE = 0x200;\nexport const ACCESS_USER_READ = 0x400;\nexport const ACCESS_USER_RW = ACCESS_USER_WRITE | ACCESS_USER_READ;\nexport const ACCESS_USER_ALL = ACCESS_USER_WRITE | ACCESS_USER_READ | ACCESS_USER_EXEC;\n\nexport const ACCESS_WRITE = 0x2;\nexport const ACCESS_READ = 0x4;\nexport const ACCESS_LIST = 'list';\nexport const ACCESS_DELETE = 'delete';\nexport const ACCESS_CREATE = 'create';\n\nexport type GenericAccessFlags =\n | typeof ACCESS_WRITE\n | typeof ACCESS_READ\n | typeof ACCESS_LIST\n | typeof ACCESS_DELETE\n | typeof ACCESS_CREATE;\n\nexport const REG_CHECK_ID = /[*?[\\]]|\\$%\\$/;\n\nexport const USER_STARTS_WITH = 'system.user.';\nexport const GROUP_STARTS_WITH = 'system.group.';\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAY;CAAZ,SAAYA,SAAM;AACd,EAAAA,QAAA,kBAAA,IAAA;AACA,EAAAA,QAAA,iBAAA,IAAA;AACA,EAAAA,QAAA,iBAAA,IAAA;AACJ,GAJY,WAAA,SAAM,CAAA,EAAA;AAMX,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAE3B,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B,MAAM,oBAAoB;AAC1B,MAAM,kBAAkB,qBAAqB;AAC7C,MAAM,mBAAmB,qBAAqB,oBAAoB;AAElE,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B,MAAM,oBAAoB;AAC1B,MAAM,kBAAkB,qBAAqB;AAC7C,MAAM,mBAAmB,qBAAqB,oBAAoB;AAElE,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB;AACzB,MAAM,iBAAiB,oBAAoB;AAC3C,MAAM,kBAAkB,oBAAoB,mBAAmB;AAE/D,MAAM,eAAe;AACrB,MAAM,cAAc;AACpB,MAAM,cAAc;AACpB,MAAM,gBAAgB;AACtB,MAAM,gBAAgB;AAStB,MAAM,eAAe;AAErB,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;",
4
+ "sourcesContent": ["export enum ERRORS {\n ERROR_PERMISSION = 'permissionError',\n ERROR_NOT_FOUND = 'Not exists',\n ERROR_DB_CLOSED = 'DB closed',\n}\n\nexport const SYSTEM_ADMIN_USER = 'system.user.admin';\nexport const SYSTEM_ADMIN_GROUP = 'system.group.administrator';\n\nexport const ACCESS_EVERY_EXEC = 0x1;\nexport const ACCESS_EVERY_WRITE = 0x2;\nexport const ACCESS_EVERY_READ = 0x4;\nexport const ACCESS_EVERY_RW = ACCESS_EVERY_WRITE | ACCESS_EVERY_READ;\nexport const ACCESS_EVERY_ALL = ACCESS_EVERY_WRITE | ACCESS_EVERY_READ | ACCESS_EVERY_EXEC;\n\nexport const ACCESS_GROUP_EXEC = 0x10;\nexport const ACCESS_GROUP_WRITE = 0x20;\nexport const ACCESS_GROUP_READ = 0x40;\nexport const ACCESS_GROUP_RW = ACCESS_GROUP_WRITE | ACCESS_GROUP_READ;\nexport const ACCESS_GROUP_ALL = ACCESS_GROUP_WRITE | ACCESS_GROUP_READ | ACCESS_GROUP_EXEC;\n\nexport const ACCESS_USER_EXEC = 0x100;\nexport const ACCESS_USER_WRITE = 0x200;\nexport const ACCESS_USER_READ = 0x400;\nexport const ACCESS_USER_RW = ACCESS_USER_WRITE | ACCESS_USER_READ;\nexport const ACCESS_USER_ALL = ACCESS_USER_WRITE | ACCESS_USER_READ | ACCESS_USER_EXEC;\n\nexport const ACCESS_WRITE = 0x2;\nexport const ACCESS_READ = 0x4;\nexport const ACCESS_LIST = 'list';\nexport const ACCESS_DELETE = 'delete';\nexport const ACCESS_CREATE = 'create';\n\nexport type GenericAccessFlags =\n typeof ACCESS_WRITE | typeof ACCESS_READ | typeof ACCESS_LIST | typeof ACCESS_DELETE | typeof ACCESS_CREATE;\n\nexport const REG_CHECK_ID = /[*?[\\]]|\\$%\\$/;\n\nexport const USER_STARTS_WITH = 'system.user.';\nexport const GROUP_STARTS_WITH = 'system.group.';\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,IAAY;CAAZ,SAAYA,SAAM;AACd,EAAAA,QAAA,kBAAA,IAAA;AACA,EAAAA,QAAA,iBAAA,IAAA;AACA,EAAAA,QAAA,iBAAA,IAAA;AACJ,GAJY,WAAA,SAAM,CAAA,EAAA;AAMX,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAE3B,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B,MAAM,oBAAoB;AAC1B,MAAM,kBAAkB,qBAAqB;AAC7C,MAAM,mBAAmB,qBAAqB,oBAAoB;AAElE,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAC3B,MAAM,oBAAoB;AAC1B,MAAM,kBAAkB,qBAAqB;AAC7C,MAAM,mBAAmB,qBAAqB,oBAAoB;AAElE,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;AAC1B,MAAM,mBAAmB;AACzB,MAAM,iBAAiB,oBAAoB;AAC3C,MAAM,kBAAkB,oBAAoB,mBAAmB;AAE/D,MAAM,eAAe;AACrB,MAAM,cAAc;AACpB,MAAM,cAAc;AACpB,MAAM,gBAAgB;AACtB,MAAM,gBAAgB;AAKtB,MAAM,eAAe;AAErB,MAAM,mBAAmB;AACzB,MAAM,oBAAoB;",
6
6
  "names": ["ERRORS"]
7
7
  }
@@ -3,6 +3,7 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
7
  var __export = (target, all) => {
7
8
  for (var name in all)
8
9
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -25,6 +26,7 @@ var import_js_controller_common_db = require("@iobroker/js-controller-common-db"
25
26
  function interview(config) {
26
27
  return (0, import_js_controller_common_db.defaultRedisInterview)({ config, type: "objects" });
27
28
  }
29
+ __name(interview, "interview");
28
30
  // Annotate the CommonJS export names for ESM import in node:
29
31
  0 && (module.exports = {
30
32
  interview
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/lib/objects/interview.ts"],
4
4
  "sourcesContent": ["import { defaultRedisInterview } from '@iobroker/js-controller-common-db';\n\n/**\n * Custom interview during setup\n *\n * @param config the prefilled database config\n * @returns the database options obtained by the answered questionnaire\n */\nexport function interview(config: ioBroker.ObjectsDatabaseOptions): Promise<ioBroker.ObjectsDatabaseOptions> {\n return defaultRedisInterview<ioBroker.ObjectsDatabaseOptions>({ config, type: 'objects' });\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;;;;;AAAA,qCAAsC;AAQhC,SAAU,UAAU,QAAuC;AAC7D,aAAO,sDAAuD,EAAE,QAAQ,MAAM,UAAS,CAAE;AAC7F;",
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;;;;;AAAA,qCAAsC;AAQhC,SAAU,UAAU,QAAuC;AAC7D,aAAO,sDAAuD,EAAE,QAAQ,MAAM,UAAS,CAAE;AAC7F;AAFgB;",
6
6
  "names": []
7
7
  }
@@ -8,13 +8,35 @@ cursor = result[1]
8
8
  local keys = result[2]
9
9
  local argStart = KEYS[1] .. KEYS[2]
10
10
  local argEnd = KEYS[1] .. KEYS[3]
11
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
12
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
13
+ local sLen = #argStart
14
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
15
+ local function byteLess(a, b, from)
16
+ local la, lb = #a, #b
17
+ local i = from or 1
18
+ while i <= la and i <= lb do
19
+ local ca, cb = a:byte(i), b:byte(i)
20
+ if ca ~= cb then
21
+ return ca < cb
22
+ end
23
+ i = i + 1
24
+ end
25
+ return la < lb
26
+ end
27
+ local function inRange(key)
28
+ if endHasPrefix then
29
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
30
+ end
31
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
32
+ end
11
33
  local checkStr = string.format("%q:{", "custom")
12
34
  -- function(doc) {
13
35
  -- if (doc.type==="state" && (doc.common.custom || doc.common.history))
14
36
  -- emit(doc._id, doc.common.custom || doc.common.history)
15
37
  -- }
16
38
  for _, key in ipairs(keys) do
17
- if (key >= argStart and key < argEnd) then
39
+ if (inRange(key)) then
18
40
  local obj = redis.call("get", key)
19
41
  if (obj:find(checkStr) ~= nil) then
20
42
  local success, decoded = pcall(cjson.decode, obj)
@@ -7,12 +7,34 @@ cursor = result[1]
7
7
  local keys = result[2]
8
8
  local argStart = KEYS[1] .. KEYS[2]
9
9
  local argEnd = KEYS[1] .. KEYS[3]
10
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
11
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
12
+ local sLen = #argStart
13
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
14
+ local function byteLess(a, b, from)
15
+ local la, lb = #a, #b
16
+ local i = from or 1
17
+ while i <= la and i <= lb do
18
+ local ca, cb = a:byte(i), b:byte(i)
19
+ if ca ~= cb then
20
+ return ca < cb
21
+ end
22
+ i = i + 1
23
+ end
24
+ return la < lb
25
+ end
26
+ local function inRange(key)
27
+ if endHasPrefix then
28
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
29
+ end
30
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
31
+ end
10
32
  local type = KEYS[4]
11
33
  local checkStr = string.format("%q:%q", "type", type)
12
34
  local skipCheck = not (type == "channel" or type == "device" or type == "folder")
13
35
  -- function(doc) { if (doc.type === "chart") emit(doc._id, doc); }
14
36
  for _, key in ipairs(keys) do
15
- if (key >= argStart and key < argEnd) then
37
+ if (inRange(key)) then
16
38
  local obj = redis.call("get", key)
17
39
  if (skipCheck or obj:find(checkStr) ~= nil) then
18
40
  local success, decoded = pcall(cjson.decode, obj)
@@ -7,6 +7,28 @@ cursor = result[1]
7
7
  local keys = result[2]
8
8
  local argStart = KEYS[1] .. KEYS[2]
9
9
  local argEnd = KEYS[1] .. KEYS[3]
10
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
11
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
12
+ local sLen = #argStart
13
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
14
+ local function byteLess(a, b, from)
15
+ local la, lb = #a, #b
16
+ local i = from or 1
17
+ while i <= la and i <= lb do
18
+ local ca, cb = a:byte(i), b:byte(i)
19
+ if ca ~= cb then
20
+ return ca < cb
21
+ end
22
+ i = i + 1
23
+ end
24
+ return la < lb
25
+ end
26
+ local function inRange(key)
27
+ if endHasPrefix then
28
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
29
+ end
30
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
31
+ end
10
32
  local checkStr = string.format("%q:%q", "TypeName", "PROGRAM")
11
33
  -- function(doc) {
12
34
  -- if (doc._id.match(/^hm-rega\\.[0-9]+\\.[0-9,A-Z,a-z]+/) && (doc.native.TypeName === "PROGRAM")) {
@@ -14,7 +36,7 @@ local checkStr = string.format("%q:%q", "TypeName", "PROGRAM")
14
36
  -- }
15
37
  -- }
16
38
  for _, key in ipairs(keys) do
17
- if (key >= argStart and key < argEnd and key:sub(7, 13) == "hm-rega") then
39
+ if (inRange(key) and key:sub(7, 13) == "hm-rega") then
18
40
  local obj = redis.call("get", key)
19
41
  if (obj:find(checkStr) ~= nil) then
20
42
  local success, decoded = pcall(cjson.decode, obj)
@@ -7,11 +7,33 @@ cursor = result[1]
7
7
  local keys = result[2]
8
8
  local argStart = KEYS[1] .. KEYS[2]
9
9
  local argEnd = KEYS[1] .. KEYS[3]
10
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
11
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
12
+ local sLen = #argStart
13
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
14
+ local function byteLess(a, b, from)
15
+ local la, lb = #a, #b
16
+ local i = from or 1
17
+ while i <= la and i <= lb do
18
+ local ca, cb = a:byte(i), b:byte(i)
19
+ if ca ~= cb then
20
+ return ca < cb
21
+ end
22
+ i = i + 1
23
+ end
24
+ return la < lb
25
+ end
26
+ local function inRange(key)
27
+ if endHasPrefix then
28
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
29
+ end
30
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
31
+ end
10
32
  local checkStr = string.format("%q:%q", "type", "script")
11
33
  -- function(doc) {
12
34
  -- if (doc.type === "script" && doc.common.engineType.match(/^[jJ]ava[sS]cript|^[cC]offee[sS]cript|^[tT]ype[sS]cript|^Blockly/)) emit(doc.common.name, doc); }
13
35
  for _, key in ipairs(keys) do
14
- if (key >= argStart and key < argEnd) then
36
+ if (inRange(key)) then
15
37
  local obj = redis.call("get", key)
16
38
  if (obj:find(checkStr) ~= nil) then
17
39
  local success, decoded = pcall(cjson.decode, obj)
@@ -8,6 +8,28 @@ cursor = result[1]
8
8
  local keys = result[2]
9
9
  local argStart = KEYS[1] .. KEYS[2]
10
10
  local argEnd = KEYS[1] .. KEYS[3]
11
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
12
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
13
+ local sLen = #argStart
14
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
15
+ local function byteLess(a, b, from)
16
+ local la, lb = #a, #b
17
+ local i = from or 1
18
+ while i <= la and i <= lb do
19
+ local ca, cb = a:byte(i), b:byte(i)
20
+ if ca ~= cb then
21
+ return ca < cb
22
+ end
23
+ i = i + 1
24
+ end
25
+ return la < lb
26
+ end
27
+ local function inRange(key)
28
+ if endHasPrefix then
29
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
30
+ end
31
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
32
+ end
11
33
  local checkStr = string.format("%q:", "TypeName");
12
34
  -- function(doc) {
13
35
  -- if (doc._id.match(/^hm-rega\\.[0-9]+\\.[0-9,A-Z,a-z]+/) && (doc.native.TypeName === "ALARMDP" || doc.native.TypeName === "VARDP")) {
@@ -15,7 +37,7 @@ local checkStr = string.format("%q:", "TypeName");
15
37
  -- }
16
38
  -- }
17
39
  for _, key in ipairs(keys) do
18
- if (key >= argStart and key < argEnd and key:sub(7, 13) == "hm-rega") then
40
+ if (inRange(key) and key:sub(7, 13) == "hm-rega") then
19
41
  local obj = redis.call("get", key)
20
42
  if (obj:find(checkStr) ~= nil) then
21
43
  local success, decoded = pcall(cjson.decode, obj)
@@ -8,12 +8,34 @@ cursor = result[1]
8
8
  local keys = result[2]
9
9
  local argStart = KEYS[1] .. KEYS[2]
10
10
  local argEnd = KEYS[1] .. KEYS[3]
11
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
12
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
13
+ local sLen = #argStart
14
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
15
+ local function byteLess(a, b, from)
16
+ local la, lb = #a, #b
17
+ local i = from or 1
18
+ while i <= la and i <= lb do
19
+ local ca, cb = a:byte(i), b:byte(i)
20
+ if ca ~= cb then
21
+ return ca < cb
22
+ end
23
+ i = i + 1
24
+ end
25
+ return la < lb
26
+ end
27
+ local function inRange(key)
28
+ if endHasPrefix then
29
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
30
+ end
31
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
32
+ end
11
33
  -- function(doc) {
12
34
  -- if (doc.type==="state" && (doc.common.custom || doc.common.history))
13
35
  -- emit(doc._id, doc.common.custom || doc.common.history)
14
36
  -- }
15
37
  for _, key in ipairs(keys) do
16
- if (key >= argStart and key < argEnd) then
38
+ if (inRange(key)) then
17
39
  rep[#rep + 1] = redis.call("get", key)
18
40
  end
19
41
  end
@@ -7,9 +7,31 @@ cursor = result[1]
7
7
  local keys = result[2]
8
8
  local argStart = KEYS[1] .. KEYS[2]
9
9
  local argEnd = KEYS[1] .. KEYS[3]
10
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
11
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
12
+ local sLen = #argStart
13
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
14
+ local function byteLess(a, b, from)
15
+ local la, lb = #a, #b
16
+ local i = from or 1
17
+ while i <= la and i <= lb do
18
+ local ca, cb = a:byte(i), b:byte(i)
19
+ if ca ~= cb then
20
+ return ca < cb
21
+ end
22
+ i = i + 1
23
+ end
24
+ return la < lb
25
+ end
26
+ local function inRange(key)
27
+ if endHasPrefix then
28
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
29
+ end
30
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
31
+ end
10
32
  -- function(doc) { if (doc.type === "chart") emit(doc._id, doc); }
11
33
  for _, key in ipairs(keys) do
12
- if (key >= argStart and key < argEnd) then
34
+ if (inRange(key)) then
13
35
  rep[#rep + 1] = redis.call("get", key)
14
36
  end
15
37
  end
@@ -7,6 +7,28 @@ cursor = result[1]
7
7
  local keys = result[2]
8
8
  local argStart = KEYS[1] .. KEYS[2]
9
9
  local argEnd = KEYS[1] .. KEYS[3]
10
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
11
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
12
+ local sLen = #argStart
13
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
14
+ local function byteLess(a, b, from)
15
+ local la, lb = #a, #b
16
+ local i = from or 1
17
+ while i <= la and i <= lb do
18
+ local ca, cb = a:byte(i), b:byte(i)
19
+ if ca ~= cb then
20
+ return ca < cb
21
+ end
22
+ i = i + 1
23
+ end
24
+ return la < lb
25
+ end
26
+ local function inRange(key)
27
+ if endHasPrefix then
28
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
29
+ end
30
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
31
+ end
10
32
  local checkStr = string.format("%q:%q", "TypeName", "PROGRAM")
11
33
  -- function(doc) {
12
34
  -- if (doc._id.match(/^hm-rega\\.[0-9]+\\.[0-9,A-Z,a-z]+/) && (doc.native.TypeName === "PROGRAM")) {
@@ -14,7 +36,7 @@ local checkStr = string.format("%q:%q", "TypeName", "PROGRAM")
14
36
  -- }
15
37
  -- }
16
38
  for _, key in ipairs(keys) do
17
- if (key >= argStart and key < argEnd) then
39
+ if (inRange(key)) then
18
40
  local obj = redis.call("get", key)
19
41
  if (obj:find(checkStr) ~= nil) then
20
42
  local success, decoded = pcall(cjson.decode, obj)
@@ -7,10 +7,32 @@ cursor = result[1]
7
7
  local keys = result[2]
8
8
  local argStart = KEYS[1] .. KEYS[2]
9
9
  local argEnd = KEYS[1] .. KEYS[3]
10
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
11
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
12
+ local sLen = #argStart
13
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
14
+ local function byteLess(a, b, from)
15
+ local la, lb = #a, #b
16
+ local i = from or 1
17
+ while i <= la and i <= lb do
18
+ local ca, cb = a:byte(i), b:byte(i)
19
+ if ca ~= cb then
20
+ return ca < cb
21
+ end
22
+ i = i + 1
23
+ end
24
+ return la < lb
25
+ end
26
+ local function inRange(key)
27
+ if endHasPrefix then
28
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
29
+ end
30
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
31
+ end
10
32
  -- function(doc) {
11
33
  -- if (doc.type === "script" && doc.common.engineType.match(/^[jJ]ava[sS]cript|^[cC]offee[sS]cript|^[tT]ype[sS]cript|^Blockly/)) emit(doc.common.name, doc); }
12
34
  for _, key in ipairs(keys) do
13
- if (key >= argStart and key < argEnd) then
35
+ if (inRange(key)) then
14
36
  rep[#rep + 1] = redis.call("get", key)
15
37
  end
16
38
  end
@@ -8,6 +8,28 @@ cursor = result[1]
8
8
  local keys = result[2]
9
9
  local argStart = KEYS[1] .. KEYS[2]
10
10
  local argEnd = KEYS[1] .. KEYS[3]
11
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
12
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
13
+ local sLen = #argStart
14
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
15
+ local function byteLess(a, b, from)
16
+ local la, lb = #a, #b
17
+ local i = from or 1
18
+ while i <= la and i <= lb do
19
+ local ca, cb = a:byte(i), b:byte(i)
20
+ if ca ~= cb then
21
+ return ca < cb
22
+ end
23
+ i = i + 1
24
+ end
25
+ return la < lb
26
+ end
27
+ local function inRange(key)
28
+ if endHasPrefix then
29
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
30
+ end
31
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
32
+ end
11
33
  local checkStr = string.format("%q:", "TypeName");
12
34
  -- function(doc) {
13
35
  -- if (doc._id.match(/^hm-rega\\.[0-9]+\\.[0-9,A-Z,a-z]+/) && (doc.native.TypeName === "ALARMDP" || doc.native.TypeName === "VARDP")) {
@@ -15,7 +37,7 @@ local checkStr = string.format("%q:", "TypeName");
15
37
  -- }
16
38
  -- }
17
39
  for _, key in ipairs(keys) do
18
- if (key >= argStart and key < argEnd) then
40
+ if (inRange(key)) then
19
41
  local obj = redis.call("get", key)
20
42
  if (obj:find(checkStr) ~= nil) then
21
43
  local success, decoded = pcall(cjson.decode, obj)
@@ -8,13 +8,35 @@ cursor = result[1]
8
8
  local keys = result[2]
9
9
  local argStart = KEYS[1] .. KEYS[2]
10
10
  local argEnd = KEYS[1] .. KEYS[3]
11
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
12
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
13
+ local sLen = #argStart
14
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
15
+ local function byteLess(a, b, from)
16
+ local la, lb = #a, #b
17
+ local i = from or 1
18
+ while i <= la and i <= lb do
19
+ local ca, cb = a:byte(i), b:byte(i)
20
+ if ca ~= cb then
21
+ return ca < cb
22
+ end
23
+ i = i + 1
24
+ end
25
+ return la < lb
26
+ end
27
+ local function inRange(key)
28
+ if endHasPrefix then
29
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
30
+ end
31
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
32
+ end
11
33
  local checkStr = string.format("%q:{", "custom")
12
34
  -- function(doc) {
13
35
  -- if (doc.type==="state" && (doc.common.custom || doc.common.history))
14
36
  -- emit(doc._id, doc.common.custom || doc.common.history)
15
37
  -- }
16
38
  for _, key in ipairs(keys) do
17
- if (key >= argStart and key < argEnd) then
39
+ if (inRange(key)) then
18
40
  local obj = redis.call("get", key)
19
41
  if (obj:find(checkStr) ~= nil) then
20
42
  local success, decoded = pcall(cjson.decode, obj)
@@ -7,12 +7,34 @@ cursor = result[1]
7
7
  local keys = result[2]
8
8
  local argStart = KEYS[1] .. KEYS[2]
9
9
  local argEnd = KEYS[1] .. KEYS[3]
10
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
11
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
12
+ local sLen = #argStart
13
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
14
+ local function byteLess(a, b, from)
15
+ local la, lb = #a, #b
16
+ local i = from or 1
17
+ while i <= la and i <= lb do
18
+ local ca, cb = a:byte(i), b:byte(i)
19
+ if ca ~= cb then
20
+ return ca < cb
21
+ end
22
+ i = i + 1
23
+ end
24
+ return la < lb
25
+ end
26
+ local function inRange(key)
27
+ if endHasPrefix then
28
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
29
+ end
30
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
31
+ end
10
32
  local type = KEYS[4]
11
33
  local checkStr = string.format("%q:%q", "type", type)
12
34
  local skipCheck = not (type == "channel" or type == "device" or type == "folder")
13
35
  -- function(doc) { if (doc.type === "chart") emit(doc._id, doc); }
14
36
  for _, key in ipairs(keys) do
15
- if (key >= argStart and key < argEnd) then
37
+ if (inRange(key)) then
16
38
  local obj = redis.call("get", key)
17
39
  if (skipCheck or obj:find(checkStr) ~= nil) then
18
40
  local success, decoded = pcall(cjson.decode, obj)
@@ -7,6 +7,28 @@ cursor = result[1]
7
7
  local keys = result[2]
8
8
  local argStart = KEYS[1] .. KEYS[2]
9
9
  local argEnd = KEYS[1] .. KEYS[3]
10
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
11
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
12
+ local sLen = #argStart
13
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
14
+ local function byteLess(a, b, from)
15
+ local la, lb = #a, #b
16
+ local i = from or 1
17
+ while i <= la and i <= lb do
18
+ local ca, cb = a:byte(i), b:byte(i)
19
+ if ca ~= cb then
20
+ return ca < cb
21
+ end
22
+ i = i + 1
23
+ end
24
+ return la < lb
25
+ end
26
+ local function inRange(key)
27
+ if endHasPrefix then
28
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
29
+ end
30
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
31
+ end
10
32
  local checkStr = string.format("%q:%q", "TypeName", "PROGRAM")
11
33
  -- function(doc) {
12
34
  -- if (doc._id.match(/^hm-rega\\.[0-9]+\\.[0-9,A-Z,a-z]+/) && (doc.native.TypeName === "PROGRAM")) {
@@ -14,7 +36,7 @@ local checkStr = string.format("%q:%q", "TypeName", "PROGRAM")
14
36
  -- }
15
37
  -- }
16
38
  for _, key in ipairs(keys) do
17
- if (key >= argStart and key < argEnd and key:sub(7, 13) == "hm-rega") then
39
+ if (inRange(key) and key:sub(7, 13) == "hm-rega") then
18
40
  local obj = redis.call("get", key)
19
41
  if (obj:find(checkStr) ~= nil) then
20
42
  local success, decoded = pcall(cjson.decode, obj)
@@ -7,11 +7,33 @@ cursor = result[1]
7
7
  local keys = result[2]
8
8
  local argStart = KEYS[1] .. KEYS[2]
9
9
  local argEnd = KEYS[1] .. KEYS[3]
10
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
11
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
12
+ local sLen = #argStart
13
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
14
+ local function byteLess(a, b, from)
15
+ local la, lb = #a, #b
16
+ local i = from or 1
17
+ while i <= la and i <= lb do
18
+ local ca, cb = a:byte(i), b:byte(i)
19
+ if ca ~= cb then
20
+ return ca < cb
21
+ end
22
+ i = i + 1
23
+ end
24
+ return la < lb
25
+ end
26
+ local function inRange(key)
27
+ if endHasPrefix then
28
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
29
+ end
30
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
31
+ end
10
32
  local checkStr = string.format("%q:%q", "type", "script")
11
33
  -- function(doc) {
12
34
  -- if (doc.type === "script" && doc.common.engineType.match(/^[jJ]ava[sS]cript|^[cC]offee[sS]cript|^[tT]ype[sS]cript|^Blockly/)) emit(doc.common.name, doc); }
13
35
  for _, key in ipairs(keys) do
14
- if (key >= argStart and key < argEnd) then
36
+ if (inRange(key)) then
15
37
  local obj = redis.call("get", key)
16
38
  if (obj:find(checkStr) ~= nil) then
17
39
  local success, decoded = pcall(cjson.decode, obj)
@@ -8,6 +8,28 @@ cursor = result[1]
8
8
  local keys = result[2]
9
9
  local argStart = KEYS[1] .. KEYS[2]
10
10
  local argEnd = KEYS[1] .. KEYS[3]
11
+ -- Compare bytes: Lua's < uses strcoll(), so it depends on the locale the Redis
12
+ -- server was started with, and argEnd ends in the U+9999 sentinel.
13
+ local sLen = #argStart
14
+ local endHasPrefix = argEnd:sub(1, sLen) == argStart
15
+ local function byteLess(a, b, from)
16
+ local la, lb = #a, #b
17
+ local i = from or 1
18
+ while i <= la and i <= lb do
19
+ local ca, cb = a:byte(i), b:byte(i)
20
+ if ca ~= cb then
21
+ return ca < cb
22
+ end
23
+ i = i + 1
24
+ end
25
+ return la < lb
26
+ end
27
+ local function inRange(key)
28
+ if endHasPrefix then
29
+ return key:sub(1, sLen) == argStart and byteLess(key, argEnd, sLen + 1)
30
+ end
31
+ return not byteLess(key, argStart) and byteLess(key, argEnd)
32
+ end
11
33
  local checkStr = string.format("%q:", "TypeName");
12
34
  -- function(doc) {
13
35
  -- if (doc._id.match(/^hm-rega\\.[0-9]+\\.[0-9,A-Z,a-z]+/) && (doc.native.TypeName === "ALARMDP" || doc.native.TypeName === "VARDP")) {
@@ -15,7 +37,7 @@ local checkStr = string.format("%q:", "TypeName");
15
37
  -- }
16
38
  -- }
17
39
  for _, key in ipairs(keys) do
18
- if (key >= argStart and key < argEnd and key:sub(7, 13) == "hm-rega") then
40
+ if (inRange(key) and key:sub(7, 13) == "hm-rega") then
19
41
  local obj = redis.call("get", key)
20
42
  if (obj:find(checkStr) ~= nil) then
21
43
  local success, decoded = pcall(cjson.decode, obj)