private void StoreVariable(string name, MondValue value) { if (name.Length > MaxVariableNameSize) { throw new MondRuntimeException($"Variable name '{name}' is too long"); } var data = JsonModule.Serialize(_state, value); if (data.Length > MaxVariableContentSize) { throw new MondRuntimeException($"Variable '{name}' exceeds maximum size"); } var cmd = new SqlCommand(_connection, _transaction, @"INSERT INTO mondbot.variables (name, type, data, version) VALUES (:name, :type, :data, 2) ON CONFLICT (name) DO UPDATE SET type = :type, data = :data, version = 2;") { ["name"] = name, ["type"] = (int)VariableType.Serialized, ["data"] = data }; using (cmd) { cmd.ExecuteNonQuery().Wait(); } }
private (MondValue?value, bool isMethod) LoadVariable(string name) { VariableType type; string data; int version; var cmd = new SqlCommand(_connection, _transaction, @"SELECT type, data, version FROM mondbot.variables WHERE name = :name FOR UPDATE;") { ["name"] = name }; using (cmd) { var result = cmd.Execute().Result.SingleOrDefault(); if (result == null) { return(null, false); } type = (VariableType)(short)result.type; data = (string)result.data; version = (int)result.version; } switch (type) { case VariableType.Serialized: return(JsonModule.Deserialize(_state, data), false); case VariableType.Method: if (version == 1) { var code = "return " + data + ";"; return(_state.Run(code, name + ".mnd"), true); } else if (version == 2) { var code = data; if (char.IsLetterOrDigit(name[0]) || name[0] == '_') { code += $"\n;return {name};"; } else { code += $"\n;return global.__ops[\"{name}\"];"; } return(_state.Run(code, name + ".mnd"), true); } else { throw new NotSupportedException("Method Version"); } default: throw new MondRuntimeException($"Unhandled VariableType {type}"); } }
public static bool TrySerialize(MondState state, MondValue value, out MondValue serialized) { bool canSerialize = value[Serialize]; if (!canSerialize) { serialized = MondValue.Undefined; return(false); } serialized = JsonModule.Serialize(state, value); return(true); }