1
0
forked from joey/godottest
Joey Eamigh 9989fab018
addons?
2025-10-10 14:07:23 -04:00

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)