forked from joey/godottest
568 lines
18 KiB
GDScript
568 lines
18 KiB
GDScript
class_name Gedis extends Node
|
|
|
|
# Component instances
|
|
var _core: GedisCore
|
|
var _expiry: GedisExpiry
|
|
var _time_source: GedisTimeSource
|
|
var _strings: GedisStrings
|
|
var _hashes: GedisHashes
|
|
var _lists: GedisLists
|
|
var _sets: GedisSets
|
|
var _sorted_sets: GedisSortedSets
|
|
var _pubsub: GedisPubSub
|
|
var _debugger_component: GedisDebugger
|
|
var _utils: GedisUtils
|
|
var _persistence_backends: Dictionary = {}
|
|
var _default_persistence_backend: String = ""
|
|
|
|
# Instance registry
|
|
static var _instances: Array = []
|
|
static var _next_instance_id: int = 0
|
|
var _instance_id: int = -1
|
|
var _instance_name: String = ""
|
|
static var _debugger_registered = false
|
|
|
|
func _init() -> void:
|
|
# assign id and register
|
|
_instance_id = _next_instance_id
|
|
_next_instance_id += 1
|
|
_instance_name = "Gedis_%d" % _instance_id
|
|
_instances.append(self)
|
|
|
|
# Instantiate components
|
|
_core = GedisCore.new(self)
|
|
_utils = GedisUtils.new()
|
|
_expiry = GedisExpiry.new(self)
|
|
_strings = GedisStrings.new(self)
|
|
_hashes = GedisHashes.new(self)
|
|
_lists = GedisLists.new(self)
|
|
_sets = GedisSets.new(self)
|
|
_sorted_sets = GedisSortedSets.new(self)
|
|
_pubsub = GedisPubSub.new(self)
|
|
_debugger_component = GedisDebugger.new(self)
|
|
|
|
_time_source = GedisUnixTimeSource.new()
|
|
_time_source.instance = self
|
|
|
|
_pubsub.pubsub_message.connect(_on_pubsub_message)
|
|
_pubsub.psub_message.connect(_on_psub_message)
|
|
|
|
GedisDebugger._ensure_debugger_is_registered()
|
|
|
|
func _on_pubsub_message(channel: String, message: Variant) -> void:
|
|
pubsub_message.emit(channel, message)
|
|
|
|
func _on_psub_message(pattern: String, channel: String, message: Variant) -> void:
|
|
psub_message.emit(pattern, channel, message)
|
|
|
|
func _exit_tree() -> void:
|
|
# unregister instance
|
|
for i in range(_instances.size()):
|
|
if _instances[i] == self:
|
|
_instances.remove_at(i)
|
|
break
|
|
|
|
func _process(delta: float) -> void:
|
|
_time_source.tick(delta)
|
|
|
|
# --- Time Source ---
|
|
func set_time_source(p_time_source: GedisTimeSource) -> void:
|
|
p_time_source.instance = self
|
|
_time_source = p_time_source
|
|
|
|
func get_time_source() -> GedisTimeSource:
|
|
return _time_source
|
|
|
|
# --- Public API ---
|
|
|
|
signal pubsub_message(channel, message)
|
|
signal psub_message(pattern, channel, message)
|
|
|
|
## Sets a value for a key
|
|
func set_value(key: StringName, value: Variant) -> void:
|
|
_strings.set_value(key, value)
|
|
|
|
## Sets a key to a value with an expiration time in seconds.
|
|
func setex(key: StringName, seconds: int, value: Variant) -> void:
|
|
set_value(key, value)
|
|
expire(key, seconds)
|
|
|
|
## Gets the string value of a key.
|
|
func get_value(key: StringName, default_value: Variant = null) -> Variant:
|
|
return _strings.get_value(key, default_value)
|
|
|
|
## Deletes one or more keys.
|
|
func del(keys) -> int:
|
|
return _strings.del(keys)
|
|
|
|
## Checks if one or more keys exist.
|
|
func exists(keys) -> Variant:
|
|
return _strings.exists(keys)
|
|
|
|
## Checks if a key exists.
|
|
func key_exists(key: String) -> bool:
|
|
return _strings.key_exists(key)
|
|
|
|
## Increments the integer value of a key by a given amount.
|
|
func incrby(key: String, amount: int = 1) -> int:
|
|
return _strings.incrby(key, amount)
|
|
|
|
## Decrements the integer value of a key by a given amount.
|
|
func decrby(key: String, amount: int = 1) -> int:
|
|
return _strings.decrby(key, amount)
|
|
|
|
## Gets all keys matching a pattern.
|
|
func keys(pattern: String = "*") -> Array:
|
|
return _strings.keys(pattern)
|
|
|
|
## Sets multiple keys to multiple values.
|
|
func mset(dict: Dictionary) -> void:
|
|
_strings.mset(dict)
|
|
|
|
## Gets the values of all specified keys.
|
|
func mget(keys: Array) -> Array:
|
|
return _strings.mget(keys)
|
|
|
|
## Appends a value to a key.
|
|
func append(key: String, value: String) -> int:
|
|
return _strings.append(key, value)
|
|
|
|
## Atomically sets a key to a value and returns the old value.
|
|
func getset(key: String, value: Variant) -> Variant:
|
|
return _strings.getset(key, value)
|
|
|
|
## Gets the length of the string value of a key.
|
|
func strlen(key: String) -> int:
|
|
return _strings.strlen(key)
|
|
|
|
## Sets a key to a value, only if the key does not exist.
|
|
func setnx(key: String, value: Variant) -> int:
|
|
return _strings.setnx(key, value)
|
|
|
|
## Renames a key to newkey, only if newkey does not exist.
|
|
func rename(key: String, newkey: String) -> int:
|
|
return _core.rename(key, newkey)
|
|
|
|
## Moves a key to another key.
|
|
func move(key: String, newkey: String) -> int:
|
|
return _core.move(key, newkey)
|
|
|
|
## Returns a random key from the database.
|
|
func randomkey() -> String:
|
|
var all_keys = _core._get_all_keys().keys()
|
|
if all_keys.is_empty():
|
|
return ""
|
|
return all_keys.pick_random()
|
|
|
|
## Returns the number of keys in the database.
|
|
func dbsize() -> int:
|
|
return _core._get_all_keys().size()
|
|
|
|
## Adds the keyspace prefix to a key
|
|
func ks(key: String) -> String:
|
|
return _core.ks(key)
|
|
|
|
## Removes the keyspace prefix from a key if present, otherwise returns the key unchanged
|
|
func rks(key: String) -> String:
|
|
return _core.rks(key)
|
|
|
|
# Hashes
|
|
## Sets the string value of a hash field.
|
|
func hset(key: String, field: String, value) -> int:
|
|
return _hashes.hset(key, field, value)
|
|
|
|
## Gets the value of a hash field.
|
|
func hget(key: String, field: String, default_value: Variant = null):
|
|
return _hashes.hget(key, field, default_value)
|
|
|
|
## Gets the values of all the given hash fields.
|
|
func hmget(key: String, fields: Array) -> Array:
|
|
return _hashes.hmget(key, fields)
|
|
|
|
## Sets multiple hash fields to multiple values.
|
|
func hmset(key: String, field_value_pairs: Dictionary) -> void:
|
|
_hashes.hmset(key, field_value_pairs)
|
|
|
|
## Increments the integer value of a hash field by the given amount.
|
|
func hincrby(key: String, field: String, amount: int) -> Variant:
|
|
return _hashes.hincrby(key, field, amount)
|
|
|
|
## Increments the float value of a hash field by the given amount.
|
|
func hincrbyfloat(key: String, field: String, amount: float) -> Variant:
|
|
return _hashes.hincrbyfloat(key, field, amount)
|
|
|
|
## Deletes one or more hash fields.
|
|
func hdel(key: String, fields) -> int:
|
|
return _hashes.hdel(key, fields)
|
|
|
|
## Gets all the fields and values in a hash.
|
|
func hgetall(key: String) -> Dictionary:
|
|
return _hashes.hgetall(key)
|
|
|
|
## Checks if a hash field exists.
|
|
func hexists(key: String, field = null) -> bool:
|
|
return _hashes.hexists(key, field)
|
|
|
|
## Gets all the fields in a hash.
|
|
func hkeys(key: String) -> Array:
|
|
return _hashes.hkeys(key)
|
|
|
|
## Gets all the values in a hash.
|
|
func hvals(key: String) -> Array:
|
|
return _hashes.hvals(key)
|
|
|
|
## Gets the number of fields in a hash.
|
|
func hlen(key: String) -> int:
|
|
return _hashes.hlen(key)
|
|
|
|
# Lists
|
|
## Prepends one or multiple values to a list.
|
|
func lpush(key: String, value) -> int:
|
|
return _lists.lpush(key, value)
|
|
|
|
## Appends one or multiple values to a list.
|
|
func rpush(key: String, value) -> int:
|
|
return _lists.rpush(key, value)
|
|
|
|
## Removes and gets the first element in a list.
|
|
func lpop(key: String):
|
|
return _lists.lpop(key)
|
|
|
|
## Removes and gets the last element in a list.
|
|
func rpop(key: String):
|
|
return _lists.rpop(key)
|
|
|
|
## Gets the length of a list.
|
|
func llen(key: String) -> int:
|
|
return _lists.llen(key)
|
|
|
|
## Checks if a list exists.
|
|
func lexists(key: String) -> bool:
|
|
return _lists.lexists(key)
|
|
|
|
## Gets all elements from a list.
|
|
func lget(key: String) -> Array:
|
|
return _lists.lget(key)
|
|
|
|
## Gets a range of elements from a list.
|
|
func lrange(key: String, start: int, stop: int) -> Array:
|
|
return _lists.lrange(key, start, stop)
|
|
|
|
## Gets an element from a list by index.
|
|
func lindex(key: String, index: int):
|
|
return _lists.lindex(key, index)
|
|
|
|
## Sets the value of an element in a list by index.
|
|
func lset(key: String, index: int, value) -> bool:
|
|
return _lists.lset(key, index, value)
|
|
|
|
## Removes elements from a list.
|
|
func lrem(key: String, count: int, value) -> int:
|
|
return _lists.lrem(key, count, value)
|
|
|
|
## Trims a list to the specified range of indices.
|
|
func ltrim(key: String, start: int, stop: int) -> bool:
|
|
return _lists.ltrim(key, start, stop)
|
|
|
|
## Inserts a value into a list before or after a pivot value.
|
|
func linsert(key: String, position: String, pivot, value) -> int:
|
|
return _lists.linsert(key, position, pivot, value)
|
|
|
|
## Atomically returns and removes the first/last element of the list stored at source and pushes the element at the first/last element of the list stored at destination.
|
|
func lmove(source: String, destination: String, from: String, to: String):
|
|
return _lists.lmove(source, destination, from, to)
|
|
|
|
# Sets
|
|
## Adds one or more members to a set.
|
|
func sadd(key: String, member) -> int:
|
|
return _sets.sadd(key, member)
|
|
|
|
## Removes one or more members from a set.
|
|
func srem(key: String, member) -> int:
|
|
return _sets.srem(key, member)
|
|
|
|
## Gets all the members in a set.
|
|
func smembers(key: String) -> Array:
|
|
return _sets.smembers(key)
|
|
|
|
## Checks if a member is in a set.
|
|
func sismember(key: String, member) -> bool:
|
|
return _sets.sismember(key, member)
|
|
|
|
## Gets the number of members in a set.
|
|
func scard(key: String) -> int:
|
|
return _sets.scard(key)
|
|
|
|
## Checks if a set exists.
|
|
func sexists(key: String) -> bool:
|
|
return _sets.sexists(key)
|
|
|
|
## Removes and returns a random member from a set.
|
|
func spop(key: String):
|
|
return _sets.spop(key)
|
|
|
|
## Moves a member from one set to another.
|
|
func smove(source: String, destination: String, member) -> bool:
|
|
return _sets.smove(source, destination, member)
|
|
|
|
## Returns the union of the sets stored at the given keys.
|
|
func sunion(keys: Array) -> Array:
|
|
return _sets.sunion(keys)
|
|
|
|
## Returns the intersection of the sets stored at the given keys.
|
|
func sinter(keys: Array) -> Array:
|
|
return _sets.sinter(keys)
|
|
|
|
## Returns the difference of the sets stored at the given keys.
|
|
func sdiff(keys: Array) -> Array:
|
|
return _sets.sdiff(keys)
|
|
|
|
## Stores the union of the sets at keys in the destination key.
|
|
func sunionstore(destination: String, keys: Array) -> int:
|
|
return _sets.sunionstore(destination, keys)
|
|
|
|
## Stores the intersection of the sets at keys in the destination key.
|
|
func sinterstore(destination: String, keys: Array) -> int:
|
|
return _sets.sinterstore(destination, keys)
|
|
|
|
## Stores the difference of the sets at keys in the destination key.
|
|
func sdiffstore(destination: String, keys: Array) -> int:
|
|
return _sets.sdiffstore(destination, keys)
|
|
|
|
## Returns one or more random members from the set at key.
|
|
func srandmember(key: String, count: int = 1) -> Variant:
|
|
return _sets.srandmember(key, count)
|
|
|
|
# Sorted Sets
|
|
## Adds a member with a score to a sorted set.
|
|
func zadd(key: String, member: String, score: int):
|
|
return _sorted_sets.add(key, member, score)
|
|
|
|
## Checks if a sorted set exists.
|
|
func zexists(key: String) -> bool:
|
|
return _sorted_sets.zexists(key)
|
|
|
|
## Gets the number of members in a sorted set.
|
|
func zcard(key: String) -> int:
|
|
return _sorted_sets.zcard(key)
|
|
|
|
## Removes a member from a sorted set.
|
|
func zrem(key: String, member: String):
|
|
return _sorted_sets.remove(key, member)
|
|
|
|
## Gets members from a sorted set within a score range.
|
|
func zrange(key: String, start, stop, withscores: bool = false):
|
|
return _sorted_sets.zrange(key, start, stop, withscores)
|
|
|
|
## Gets members from a sorted set within a score range, in reverse order.
|
|
func zrevrange(key: String, start, stop, withscores: bool = false):
|
|
return _sorted_sets.zrevrange(key, start, stop, withscores)
|
|
|
|
## Removes and returns members with scores up to a certain value.
|
|
func zpopready(key: String, now: int):
|
|
return _sorted_sets.pop_ready(key, now)
|
|
|
|
## Returns the score of member in the sorted set at key.
|
|
func zscore(key: String, member: String) -> Variant:
|
|
return _sorted_sets.zscore(key, member)
|
|
|
|
## Returns the rank of member in the sorted set at key.
|
|
func zrank(key: String, member: String) -> Variant:
|
|
return _sorted_sets.zrank(key, member)
|
|
|
|
## Returns the rank of member in the sorted set at key, with scores ordered from high to low.
|
|
func zrevrank(key: String, member: String) -> Variant:
|
|
return _sorted_sets.zrevrank(key, member)
|
|
|
|
## Returns the number of elements in the sorted set at key with a score between min and max.
|
|
func zcount(key: String, min_score, max_score) -> int:
|
|
return _sorted_sets.zcount(key, min_score, max_score)
|
|
|
|
## Increments the score of member in the sorted set at key by increment.
|
|
func zincrby(key: String, increment, member: String) -> Variant:
|
|
return _sorted_sets.zincrby(key, increment, member)
|
|
|
|
## Returns a range of members in a sorted set, by score.
|
|
func zrangebyscore(key: String, min_score, max_score, withscores: bool = false) -> Array:
|
|
return _sorted_sets.zrangebyscore(key, min_score, max_score, withscores)
|
|
|
|
## Returns a range of members in a sorted set, by score, in reverse order.
|
|
func zrevrangebyscore(key: String, min_score, max_score, withscores: bool = false) -> Array:
|
|
return _sorted_sets.zrevrangebyscore(key, min_score, max_score, withscores)
|
|
|
|
## Computes the union of sorted sets and stores the result in a new key.
|
|
func zunionstore(destination: String, keys: Array, aggregate: String = "SUM") -> int:
|
|
return _sorted_sets.zunionstore(destination, keys, aggregate)
|
|
|
|
## Computes the intersection of sorted sets and stores the result in a new key.
|
|
func zinterstore(destination: String, keys: Array, aggregate: String = "SUM") -> int:
|
|
return _sorted_sets.zinterstore(destination, keys, aggregate)
|
|
|
|
# Pub/Sub
|
|
## Posts a message to a channel.
|
|
func publish(channel: String, message) -> void:
|
|
_pubsub.publish.call_deferred(channel, message)
|
|
|
|
## Subscribes to a channel.
|
|
func subscribe(channel: String, subscriber: Object) -> void:
|
|
_pubsub.subscribe(channel, subscriber)
|
|
|
|
## Unsubscribes from a channel.
|
|
func unsubscribe(channel: String, subscriber: Object) -> void:
|
|
_pubsub.unsubscribe(channel, subscriber)
|
|
|
|
## Subscribes to channels matching a pattern.
|
|
func psubscribe(pattern: String, subscriber: Object) -> void:
|
|
_pubsub.psubscribe(pattern, subscriber)
|
|
|
|
## Unsubscribes from channels matching a pattern.
|
|
func punsubscribe(pattern: String, subscriber: Object) -> void:
|
|
_pubsub.punsubscribe(pattern, subscriber)
|
|
|
|
## Returns a list of all active channels.
|
|
func list_channels() -> Array:
|
|
return _pubsub.list_channels()
|
|
|
|
## Returns a list of subscribers for a given channel.
|
|
func list_subscribers(channel: String) -> Array:
|
|
return _pubsub.list_subscribers(channel)
|
|
|
|
## Returns a list of all active patterns.
|
|
func list_patterns() -> Array:
|
|
return _pubsub.list_patterns()
|
|
|
|
## Returns a list of subscribers for a given pattern.
|
|
func list_pattern_subscribers(pattern: String) -> Array:
|
|
return _pubsub.list_pattern_subscribers(pattern)
|
|
|
|
# Expiry
|
|
## Sets a key's time to live in seconds.
|
|
func expire(key: String, seconds: int) -> bool:
|
|
return _expiry.expire(key, seconds)
|
|
|
|
## Gets the remaining time to live of a key.
|
|
func ttl(key: String) -> int:
|
|
return _expiry.ttl(key)
|
|
|
|
## Removes the expiration from a key.
|
|
func persist(key: String) -> bool:
|
|
return _expiry.persist(key)
|
|
|
|
## Purges all expired keys
|
|
func purge_expired() -> void:
|
|
_expiry._purge_expired()
|
|
|
|
# Admin
|
|
## Deletes all keys from the database.
|
|
func flushall() -> void:
|
|
_core.flushall()
|
|
|
|
# Persistence
|
|
## Registers a new persistence backend.
|
|
func register_persistence_backend(name: String, backend: GedisPersistenceBackend) -> void:
|
|
_persistence_backends[name] = backend
|
|
|
|
## Sets the default persistence backend.
|
|
func set_default_persistence_backend(name: String) -> bool:
|
|
if _persistence_backends.has(name):
|
|
_default_persistence_backend = name
|
|
return true
|
|
return false
|
|
|
|
## Saves the current state to a file using the default persistence backend.
|
|
func save(path: String, options: Dictionary = {}) -> int:
|
|
if _default_persistence_backend.is_empty():
|
|
register_persistence_backend("json", GedisJSONSnapshotBackend.new())
|
|
set_default_persistence_backend("json")
|
|
|
|
var backend: GedisPersistenceBackend = _persistence_backends[_default_persistence_backend]
|
|
var dump_options = options.duplicate()
|
|
if dump_options.has("path"):
|
|
dump_options.erase("path")
|
|
|
|
var data = _core.dump_all(dump_options)
|
|
|
|
var save_options = {"path": path}
|
|
return backend.save(data, save_options)
|
|
|
|
## Loads the state from a file using the default persistence backend.
|
|
func load(path: String, options: Dictionary = {}) -> int:
|
|
if _default_persistence_backend.is_empty():
|
|
register_persistence_backend("json", GedisJSONSnapshotBackend.new())
|
|
set_default_persistence_backend("json")
|
|
|
|
var backend: GedisPersistenceBackend = _persistence_backends[_default_persistence_backend]
|
|
var load_options = {"path": path}
|
|
var data = backend.load(load_options)
|
|
|
|
if data.is_empty():
|
|
return FAILED
|
|
|
|
_core.restore_all(data)
|
|
return OK
|
|
|
|
## Dumps the entire dataset to a variable.
|
|
func dump_all(options: Dictionary = {}) -> Dictionary:
|
|
return _core.dump_all(options)
|
|
|
|
## Restores the entire dataset from a variable.
|
|
func restore_all(data: Dictionary) -> void:
|
|
_core.restore_all(data)
|
|
|
|
## Restores a key from a serialized value.
|
|
func restore(key: String, data: String, backend: String = "") -> int:
|
|
var persistence_backend: GedisPersistenceBackend
|
|
if backend.is_empty():
|
|
if _default_persistence_backend.is_empty():
|
|
register_persistence_backend("json", GedisJSONSnapshotBackend.new())
|
|
set_default_persistence_backend("json")
|
|
persistence_backend = _persistence_backends[_default_persistence_backend]
|
|
elif _persistence_backends.has(backend):
|
|
persistence_backend = _persistence_backends[backend]
|
|
else:
|
|
return FAILED
|
|
|
|
var deserialized_data = persistence_backend.deserialize(data)
|
|
if deserialized_data.is_empty():
|
|
return FAILED
|
|
|
|
_core.restore_key(key, deserialized_data)
|
|
return OK
|
|
|
|
# Debugger
|
|
## Returns the type of the value stored at a key.
|
|
func type(key: String) -> String:
|
|
return _debugger_component.type(key)
|
|
|
|
## Returns a dictionary representation of the value stored at a key.
|
|
func dump_key(key: String) -> Dictionary:
|
|
return _debugger_component.dump(key)
|
|
|
|
## Returns a snapshot of the database for keys matching a pattern.
|
|
func snapshot(pattern: String = "*") -> Dictionary:
|
|
return _debugger_component.snapshot(pattern)
|
|
|
|
# Instance helpers
|
|
## Sets the name for this Gedis instance.
|
|
func set_instance_name(name: String) -> void:
|
|
_instance_name = name
|
|
|
|
## Gets the name for this Gedis instance.
|
|
func get_instance_name() -> String:
|
|
return _instance_name
|
|
|
|
## Gets all active Gedis instances.
|
|
static func get_all_instances() -> Array:
|
|
var result: Array = []
|
|
for inst in _instances:
|
|
if is_instance_valid(inst):
|
|
var info: Dictionary = {}
|
|
info["id"] = inst._instance_id
|
|
info["name"] = inst.name if inst.name else inst._instance_name
|
|
info["object"] = inst
|
|
result.append(info)
|
|
return result
|
|
|
|
static func _on_debugger_message(message: String, data: Array) -> bool:
|
|
return GedisDebugger._on_debugger_message(message, data)
|