keyvalue.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. package datastruct
  2. import (
  3. lua "github.com/xyproto/gopher-lua"
  4. "github.com/xyproto/pinterface"
  5. log "github.com/sirupsen/logrus"
  6. )
  7. // Identifier for the Set class in Lua
  8. const lKeyValueClass = "KEYVALUE"
  9. // Get the first argument, "self", and cast it from userdata to a key/value
  10. func checkKeyValue(L *lua.LState) pinterface.IKeyValue {
  11. ud := L.CheckUserData(1)
  12. if kv, ok := ud.Value.(pinterface.IKeyValue); ok {
  13. return kv
  14. }
  15. L.ArgError(1, "keyvalue expected")
  16. return nil
  17. }
  18. // Create a new KeyValue collection.
  19. // id is the name of the KeyValue collection.
  20. // dbindex is the Redis database index (typically 0).
  21. func newKeyValue(L *lua.LState, creator pinterface.ICreator, id string) (*lua.LUserData, error) {
  22. // Create a new key/value
  23. kv, err := creator.NewKeyValue(id)
  24. if err != nil {
  25. return nil, err
  26. }
  27. // Create a new userdata struct
  28. ud := L.NewUserData()
  29. ud.Value = kv
  30. L.SetMetatable(ud, L.GetTypeMetatable(lKeyValueClass))
  31. return ud, nil
  32. }
  33. // String representation
  34. // Returns the name of the KeyValue collection
  35. // tostring(kv) -> string
  36. func kvToString(L *lua.LState) int {
  37. L.Push(lua.LString("keyvalue"))
  38. return 1 // Number of returned values
  39. }
  40. // Set a key and value. Returns true if successful.
  41. // kv:set(string, string) -> bool
  42. func kvSet(L *lua.LState) int {
  43. kv := checkKeyValue(L) // arg 1
  44. key := L.CheckString(2)
  45. value := L.ToString(3)
  46. L.Push(lua.LBool(nil == kv.Set(key, value)))
  47. return 1 // Number of returned values
  48. }
  49. // Takes a key, returns a value. May return an empty string.
  50. // kv:get(string) -> string
  51. func kvGet(L *lua.LState) int {
  52. kv := checkKeyValue(L) // arg 1
  53. key := L.CheckString(2)
  54. retval, err := kv.Get(key)
  55. if err != nil {
  56. retval = ""
  57. }
  58. L.Push(lua.LString(retval))
  59. return 1 // Number of returned values
  60. }
  61. // Takes a key, returns the value+1.
  62. // Creates a key/value and returns "1" if it did not already exist.
  63. // May return an empty string.
  64. // kv:inc(string) -> string
  65. func kvInc(L *lua.LState) int {
  66. kv := checkKeyValue(L) // arg 1
  67. key := L.CheckString(2)
  68. increased, err := kv.Inc(key)
  69. if err != nil {
  70. log.Error(err.Error())
  71. L.Push(lua.LString("0"))
  72. return 1
  73. }
  74. L.Push(lua.LString(increased))
  75. return 1 // Number of returned values
  76. }
  77. // Remove a key. Returns true if successful.
  78. // kv:del(string) -> bool
  79. func kvDel(L *lua.LState) int {
  80. kv := checkKeyValue(L) // arg 1
  81. value := L.CheckString(2)
  82. L.Push(lua.LBool(nil == kv.Del(value)))
  83. return 1 // Number of returned values
  84. }
  85. // Remove the keyvalue itself. Returns true if successful.
  86. // kv:remove() -> bool
  87. func kvRemove(L *lua.LState) int {
  88. kv := checkKeyValue(L) // arg 1
  89. L.Push(lua.LBool(nil == kv.Remove()))
  90. return 1 // Number of returned values
  91. }
  92. // Clear the keyvalue. Returns true if successful.
  93. // kv:clear() -> bool
  94. func kvClear(L *lua.LState) int {
  95. kv := checkKeyValue(L) // arg 1
  96. L.Push(lua.LBool(nil == kv.Clear()))
  97. return 1 // Number of returned values
  98. }
  99. // The keyvalue methods that are to be registered
  100. var kvMethods = map[string]lua.LGFunction{
  101. "__tostring": kvToString,
  102. "set": kvSet,
  103. "get": kvGet,
  104. "inc": kvInc,
  105. "del": kvDel,
  106. "remove": kvRemove,
  107. "clear": kvClear,
  108. }
  109. // LoadKeyValue makes functions related to HTTP requests and responses available to Lua scripts
  110. func LoadKeyValue(L *lua.LState, creator pinterface.ICreator) {
  111. // Register the KeyValue class and the methods that belongs with it.
  112. mt := L.NewTypeMetatable(lKeyValueClass)
  113. mt.RawSetH(lua.LString("__index"), mt)
  114. L.SetFuncs(mt, kvMethods)
  115. // The constructor for new KeyValues takes a name and an optional redis db index
  116. L.SetGlobal("KeyValue", L.NewFunction(func(L *lua.LState) int {
  117. name := L.CheckString(1)
  118. // Check if the optional argument is given
  119. if L.GetTop() == 2 {
  120. localDBIndex := L.ToInt(2)
  121. // Set the DB index, if possible
  122. switch rh := creator.(type) {
  123. case pinterface.IRedisCreator:
  124. rh.SelectDatabase(localDBIndex)
  125. }
  126. }
  127. // Create a new keyvalue in Lua
  128. userdata, err := newKeyValue(L, creator, name)
  129. if err != nil {
  130. L.Push(lua.LNil)
  131. L.Push(lua.LString(err.Error()))
  132. L.Push(lua.LNumber(1))
  133. return 3 // Number of returned values
  134. }
  135. // Return the keyvalue object
  136. L.Push(userdata)
  137. return 1 // Number of returned values
  138. }))
  139. }