http urls monitor.

commands.go 61KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500
  1. package redis
  2. import (
  3. "errors"
  4. "io"
  5. "time"
  6. "github.com/go-redis/redis/internal"
  7. )
  8. func readTimeout(timeout time.Duration) time.Duration {
  9. if timeout == 0 {
  10. return 0
  11. }
  12. return timeout + 10*time.Second
  13. }
  14. func usePrecise(dur time.Duration) bool {
  15. return dur < time.Second || dur%time.Second != 0
  16. }
  17. func formatMs(dur time.Duration) int64 {
  18. if dur > 0 && dur < time.Millisecond {
  19. internal.Logf(
  20. "specified duration is %s, but minimal supported value is %s",
  21. dur, time.Millisecond,
  22. )
  23. }
  24. return int64(dur / time.Millisecond)
  25. }
  26. func formatSec(dur time.Duration) int64 {
  27. if dur > 0 && dur < time.Second {
  28. internal.Logf(
  29. "specified duration is %s, but minimal supported value is %s",
  30. dur, time.Second,
  31. )
  32. }
  33. return int64(dur / time.Second)
  34. }
  35. func appendArgs(dst, src []interface{}) []interface{} {
  36. if len(src) == 1 {
  37. if ss, ok := src[0].([]string); ok {
  38. for _, s := range ss {
  39. dst = append(dst, s)
  40. }
  41. return dst
  42. }
  43. }
  44. for _, v := range src {
  45. dst = append(dst, v)
  46. }
  47. return dst
  48. }
  49. type Cmdable interface {
  50. Pipeline() Pipeliner
  51. Pipelined(fn func(Pipeliner) error) ([]Cmder, error)
  52. TxPipelined(fn func(Pipeliner) error) ([]Cmder, error)
  53. TxPipeline() Pipeliner
  54. Command() *CommandsInfoCmd
  55. ClientGetName() *StringCmd
  56. Echo(message interface{}) *StringCmd
  57. Ping() *StatusCmd
  58. Quit() *StatusCmd
  59. Del(keys ...string) *IntCmd
  60. Unlink(keys ...string) *IntCmd
  61. Dump(key string) *StringCmd
  62. Exists(keys ...string) *IntCmd
  63. Expire(key string, expiration time.Duration) *BoolCmd
  64. ExpireAt(key string, tm time.Time) *BoolCmd
  65. Keys(pattern string) *StringSliceCmd
  66. Migrate(host, port, key string, db int64, timeout time.Duration) *StatusCmd
  67. Move(key string, db int64) *BoolCmd
  68. ObjectRefCount(key string) *IntCmd
  69. ObjectEncoding(key string) *StringCmd
  70. ObjectIdleTime(key string) *DurationCmd
  71. Persist(key string) *BoolCmd
  72. PExpire(key string, expiration time.Duration) *BoolCmd
  73. PExpireAt(key string, tm time.Time) *BoolCmd
  74. PTTL(key string) *DurationCmd
  75. RandomKey() *StringCmd
  76. Rename(key, newkey string) *StatusCmd
  77. RenameNX(key, newkey string) *BoolCmd
  78. Restore(key string, ttl time.Duration, value string) *StatusCmd
  79. RestoreReplace(key string, ttl time.Duration, value string) *StatusCmd
  80. Sort(key string, sort *Sort) *StringSliceCmd
  81. SortStore(key, store string, sort *Sort) *IntCmd
  82. SortInterfaces(key string, sort *Sort) *SliceCmd
  83. Touch(keys ...string) *IntCmd
  84. TTL(key string) *DurationCmd
  85. Type(key string) *StatusCmd
  86. Scan(cursor uint64, match string, count int64) *ScanCmd
  87. SScan(key string, cursor uint64, match string, count int64) *ScanCmd
  88. HScan(key string, cursor uint64, match string, count int64) *ScanCmd
  89. ZScan(key string, cursor uint64, match string, count int64) *ScanCmd
  90. Append(key, value string) *IntCmd
  91. BitCount(key string, bitCount *BitCount) *IntCmd
  92. BitOpAnd(destKey string, keys ...string) *IntCmd
  93. BitOpOr(destKey string, keys ...string) *IntCmd
  94. BitOpXor(destKey string, keys ...string) *IntCmd
  95. BitOpNot(destKey string, key string) *IntCmd
  96. BitPos(key string, bit int64, pos ...int64) *IntCmd
  97. Decr(key string) *IntCmd
  98. DecrBy(key string, decrement int64) *IntCmd
  99. Get(key string) *StringCmd
  100. GetBit(key string, offset int64) *IntCmd
  101. GetRange(key string, start, end int64) *StringCmd
  102. GetSet(key string, value interface{}) *StringCmd
  103. Incr(key string) *IntCmd
  104. IncrBy(key string, value int64) *IntCmd
  105. IncrByFloat(key string, value float64) *FloatCmd
  106. MGet(keys ...string) *SliceCmd
  107. MSet(pairs ...interface{}) *StatusCmd
  108. MSetNX(pairs ...interface{}) *BoolCmd
  109. Set(key string, value interface{}, expiration time.Duration) *StatusCmd
  110. SetBit(key string, offset int64, value int) *IntCmd
  111. SetNX(key string, value interface{}, expiration time.Duration) *BoolCmd
  112. SetXX(key string, value interface{}, expiration time.Duration) *BoolCmd
  113. SetRange(key string, offset int64, value string) *IntCmd
  114. StrLen(key string) *IntCmd
  115. HDel(key string, fields ...string) *IntCmd
  116. HExists(key, field string) *BoolCmd
  117. HGet(key, field string) *StringCmd
  118. HGetAll(key string) *StringStringMapCmd
  119. HIncrBy(key, field string, incr int64) *IntCmd
  120. HIncrByFloat(key, field string, incr float64) *FloatCmd
  121. HKeys(key string) *StringSliceCmd
  122. HLen(key string) *IntCmd
  123. HMGet(key string, fields ...string) *SliceCmd
  124. HMSet(key string, fields map[string]interface{}) *StatusCmd
  125. HSet(key, field string, value interface{}) *BoolCmd
  126. HSetNX(key, field string, value interface{}) *BoolCmd
  127. HVals(key string) *StringSliceCmd
  128. BLPop(timeout time.Duration, keys ...string) *StringSliceCmd
  129. BRPop(timeout time.Duration, keys ...string) *StringSliceCmd
  130. BRPopLPush(source, destination string, timeout time.Duration) *StringCmd
  131. LIndex(key string, index int64) *StringCmd
  132. LInsert(key, op string, pivot, value interface{}) *IntCmd
  133. LInsertBefore(key string, pivot, value interface{}) *IntCmd
  134. LInsertAfter(key string, pivot, value interface{}) *IntCmd
  135. LLen(key string) *IntCmd
  136. LPop(key string) *StringCmd
  137. LPush(key string, values ...interface{}) *IntCmd
  138. LPushX(key string, value interface{}) *IntCmd
  139. LRange(key string, start, stop int64) *StringSliceCmd
  140. LRem(key string, count int64, value interface{}) *IntCmd
  141. LSet(key string, index int64, value interface{}) *StatusCmd
  142. LTrim(key string, start, stop int64) *StatusCmd
  143. RPop(key string) *StringCmd
  144. RPopLPush(source, destination string) *StringCmd
  145. RPush(key string, values ...interface{}) *IntCmd
  146. RPushX(key string, value interface{}) *IntCmd
  147. SAdd(key string, members ...interface{}) *IntCmd
  148. SCard(key string) *IntCmd
  149. SDiff(keys ...string) *StringSliceCmd
  150. SDiffStore(destination string, keys ...string) *IntCmd
  151. SInter(keys ...string) *StringSliceCmd
  152. SInterStore(destination string, keys ...string) *IntCmd
  153. SIsMember(key string, member interface{}) *BoolCmd
  154. SMembers(key string) *StringSliceCmd
  155. SMembersMap(key string) *StringStructMapCmd
  156. SMove(source, destination string, member interface{}) *BoolCmd
  157. SPop(key string) *StringCmd
  158. SPopN(key string, count int64) *StringSliceCmd
  159. SRandMember(key string) *StringCmd
  160. SRandMemberN(key string, count int64) *StringSliceCmd
  161. SRem(key string, members ...interface{}) *IntCmd
  162. SUnion(keys ...string) *StringSliceCmd
  163. SUnionStore(destination string, keys ...string) *IntCmd
  164. XAdd(a *XAddArgs) *StringCmd
  165. XLen(stream string) *IntCmd
  166. XRange(stream, start, stop string) *XMessageSliceCmd
  167. XRangeN(stream, start, stop string, count int64) *XMessageSliceCmd
  168. XRevRange(stream string, start, stop string) *XMessageSliceCmd
  169. XRevRangeN(stream string, start, stop string, count int64) *XMessageSliceCmd
  170. XRead(a *XReadArgs) *XStreamSliceCmd
  171. XReadStreams(streams ...string) *XStreamSliceCmd
  172. XGroupCreate(stream, group, start string) *StatusCmd
  173. XGroupSetID(stream, group, start string) *StatusCmd
  174. XGroupDestroy(stream, group string) *IntCmd
  175. XGroupDelConsumer(stream, group, consumer string) *IntCmd
  176. XReadGroup(a *XReadGroupArgs) *XStreamSliceCmd
  177. XAck(stream, group string, ids ...string) *IntCmd
  178. XPending(stream, group string) *XPendingCmd
  179. XPendingExt(a *XPendingExtArgs) *XPendingExtCmd
  180. XClaim(a *XClaimArgs) *XMessageSliceCmd
  181. XClaimJustID(a *XClaimArgs) *StringSliceCmd
  182. XTrim(key string, maxLen int64) *IntCmd
  183. XTrimApprox(key string, maxLen int64) *IntCmd
  184. ZAdd(key string, members ...Z) *IntCmd
  185. ZAddNX(key string, members ...Z) *IntCmd
  186. ZAddXX(key string, members ...Z) *IntCmd
  187. ZAddCh(key string, members ...Z) *IntCmd
  188. ZAddNXCh(key string, members ...Z) *IntCmd
  189. ZAddXXCh(key string, members ...Z) *IntCmd
  190. ZIncr(key string, member Z) *FloatCmd
  191. ZIncrNX(key string, member Z) *FloatCmd
  192. ZIncrXX(key string, member Z) *FloatCmd
  193. ZCard(key string) *IntCmd
  194. ZCount(key, min, max string) *IntCmd
  195. ZLexCount(key, min, max string) *IntCmd
  196. ZIncrBy(key string, increment float64, member string) *FloatCmd
  197. ZInterStore(destination string, store ZStore, keys ...string) *IntCmd
  198. ZPopMax(key string, count ...int64) *ZSliceCmd
  199. ZPopMin(key string, count ...int64) *ZSliceCmd
  200. ZRange(key string, start, stop int64) *StringSliceCmd
  201. ZRangeWithScores(key string, start, stop int64) *ZSliceCmd
  202. ZRangeByScore(key string, opt ZRangeBy) *StringSliceCmd
  203. ZRangeByLex(key string, opt ZRangeBy) *StringSliceCmd
  204. ZRangeByScoreWithScores(key string, opt ZRangeBy) *ZSliceCmd
  205. ZRank(key, member string) *IntCmd
  206. ZRem(key string, members ...interface{}) *IntCmd
  207. ZRemRangeByRank(key string, start, stop int64) *IntCmd
  208. ZRemRangeByScore(key, min, max string) *IntCmd
  209. ZRemRangeByLex(key, min, max string) *IntCmd
  210. ZRevRange(key string, start, stop int64) *StringSliceCmd
  211. ZRevRangeWithScores(key string, start, stop int64) *ZSliceCmd
  212. ZRevRangeByScore(key string, opt ZRangeBy) *StringSliceCmd
  213. ZRevRangeByLex(key string, opt ZRangeBy) *StringSliceCmd
  214. ZRevRangeByScoreWithScores(key string, opt ZRangeBy) *ZSliceCmd
  215. ZRevRank(key, member string) *IntCmd
  216. ZScore(key, member string) *FloatCmd
  217. ZUnionStore(dest string, store ZStore, keys ...string) *IntCmd
  218. PFAdd(key string, els ...interface{}) *IntCmd
  219. PFCount(keys ...string) *IntCmd
  220. PFMerge(dest string, keys ...string) *StatusCmd
  221. BgRewriteAOF() *StatusCmd
  222. BgSave() *StatusCmd
  223. ClientKill(ipPort string) *StatusCmd
  224. ClientKillByFilter(keys ...string) *IntCmd
  225. ClientList() *StringCmd
  226. ClientPause(dur time.Duration) *BoolCmd
  227. ConfigGet(parameter string) *SliceCmd
  228. ConfigResetStat() *StatusCmd
  229. ConfigSet(parameter, value string) *StatusCmd
  230. ConfigRewrite() *StatusCmd
  231. DBSize() *IntCmd
  232. FlushAll() *StatusCmd
  233. FlushAllAsync() *StatusCmd
  234. FlushDB() *StatusCmd
  235. FlushDBAsync() *StatusCmd
  236. Info(section ...string) *StringCmd
  237. LastSave() *IntCmd
  238. Save() *StatusCmd
  239. Shutdown() *StatusCmd
  240. ShutdownSave() *StatusCmd
  241. ShutdownNoSave() *StatusCmd
  242. SlaveOf(host, port string) *StatusCmd
  243. Time() *TimeCmd
  244. Eval(script string, keys []string, args ...interface{}) *Cmd
  245. EvalSha(sha1 string, keys []string, args ...interface{}) *Cmd
  246. ScriptExists(hashes ...string) *BoolSliceCmd
  247. ScriptFlush() *StatusCmd
  248. ScriptKill() *StatusCmd
  249. ScriptLoad(script string) *StringCmd
  250. DebugObject(key string) *StringCmd
  251. Publish(channel string, message interface{}) *IntCmd
  252. PubSubChannels(pattern string) *StringSliceCmd
  253. PubSubNumSub(channels ...string) *StringIntMapCmd
  254. PubSubNumPat() *IntCmd
  255. ClusterSlots() *ClusterSlotsCmd
  256. ClusterNodes() *StringCmd
  257. ClusterMeet(host, port string) *StatusCmd
  258. ClusterForget(nodeID string) *StatusCmd
  259. ClusterReplicate(nodeID string) *StatusCmd
  260. ClusterResetSoft() *StatusCmd
  261. ClusterResetHard() *StatusCmd
  262. ClusterInfo() *StringCmd
  263. ClusterKeySlot(key string) *IntCmd
  264. ClusterCountFailureReports(nodeID string) *IntCmd
  265. ClusterCountKeysInSlot(slot int) *IntCmd
  266. ClusterDelSlots(slots ...int) *StatusCmd
  267. ClusterDelSlotsRange(min, max int) *StatusCmd
  268. ClusterSaveConfig() *StatusCmd
  269. ClusterSlaves(nodeID string) *StringSliceCmd
  270. ClusterFailover() *StatusCmd
  271. ClusterAddSlots(slots ...int) *StatusCmd
  272. ClusterAddSlotsRange(min, max int) *StatusCmd
  273. GeoAdd(key string, geoLocation ...*GeoLocation) *IntCmd
  274. GeoPos(key string, members ...string) *GeoPosCmd
  275. GeoRadius(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd
  276. GeoRadiusRO(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd
  277. GeoRadiusByMember(key, member string, query *GeoRadiusQuery) *GeoLocationCmd
  278. GeoRadiusByMemberRO(key, member string, query *GeoRadiusQuery) *GeoLocationCmd
  279. GeoDist(key string, member1, member2, unit string) *FloatCmd
  280. GeoHash(key string, members ...string) *StringSliceCmd
  281. ReadOnly() *StatusCmd
  282. ReadWrite() *StatusCmd
  283. MemoryUsage(key string, samples ...int) *IntCmd
  284. }
  285. type StatefulCmdable interface {
  286. Cmdable
  287. Auth(password string) *StatusCmd
  288. Select(index int) *StatusCmd
  289. SwapDB(index1, index2 int) *StatusCmd
  290. ClientSetName(name string) *BoolCmd
  291. }
  292. var _ Cmdable = (*Client)(nil)
  293. var _ Cmdable = (*Tx)(nil)
  294. var _ Cmdable = (*Ring)(nil)
  295. var _ Cmdable = (*ClusterClient)(nil)
  296. type cmdable struct {
  297. process func(cmd Cmder) error
  298. }
  299. func (c *cmdable) setProcessor(fn func(Cmder) error) {
  300. c.process = fn
  301. }
  302. type statefulCmdable struct {
  303. cmdable
  304. process func(cmd Cmder) error
  305. }
  306. func (c *statefulCmdable) setProcessor(fn func(Cmder) error) {
  307. c.process = fn
  308. c.cmdable.setProcessor(fn)
  309. }
  310. //------------------------------------------------------------------------------
  311. func (c *statefulCmdable) Auth(password string) *StatusCmd {
  312. cmd := NewStatusCmd("auth", password)
  313. c.process(cmd)
  314. return cmd
  315. }
  316. func (c *cmdable) Echo(message interface{}) *StringCmd {
  317. cmd := NewStringCmd("echo", message)
  318. c.process(cmd)
  319. return cmd
  320. }
  321. func (c *cmdable) Ping() *StatusCmd {
  322. cmd := NewStatusCmd("ping")
  323. c.process(cmd)
  324. return cmd
  325. }
  326. func (c *cmdable) Wait(numSlaves int, timeout time.Duration) *IntCmd {
  327. cmd := NewIntCmd("wait", numSlaves, int(timeout/time.Millisecond))
  328. c.process(cmd)
  329. return cmd
  330. }
  331. func (c *cmdable) Quit() *StatusCmd {
  332. panic("not implemented")
  333. }
  334. func (c *statefulCmdable) Select(index int) *StatusCmd {
  335. cmd := NewStatusCmd("select", index)
  336. c.process(cmd)
  337. return cmd
  338. }
  339. func (c *statefulCmdable) SwapDB(index1, index2 int) *StatusCmd {
  340. cmd := NewStatusCmd("swapdb", index1, index2)
  341. c.process(cmd)
  342. return cmd
  343. }
  344. //------------------------------------------------------------------------------
  345. func (c *cmdable) Command() *CommandsInfoCmd {
  346. cmd := NewCommandsInfoCmd("command")
  347. c.process(cmd)
  348. return cmd
  349. }
  350. func (c *cmdable) Del(keys ...string) *IntCmd {
  351. args := make([]interface{}, 1+len(keys))
  352. args[0] = "del"
  353. for i, key := range keys {
  354. args[1+i] = key
  355. }
  356. cmd := NewIntCmd(args...)
  357. c.process(cmd)
  358. return cmd
  359. }
  360. func (c *cmdable) Unlink(keys ...string) *IntCmd {
  361. args := make([]interface{}, 1+len(keys))
  362. args[0] = "unlink"
  363. for i, key := range keys {
  364. args[1+i] = key
  365. }
  366. cmd := NewIntCmd(args...)
  367. c.process(cmd)
  368. return cmd
  369. }
  370. func (c *cmdable) Dump(key string) *StringCmd {
  371. cmd := NewStringCmd("dump", key)
  372. c.process(cmd)
  373. return cmd
  374. }
  375. func (c *cmdable) Exists(keys ...string) *IntCmd {
  376. args := make([]interface{}, 1+len(keys))
  377. args[0] = "exists"
  378. for i, key := range keys {
  379. args[1+i] = key
  380. }
  381. cmd := NewIntCmd(args...)
  382. c.process(cmd)
  383. return cmd
  384. }
  385. func (c *cmdable) Expire(key string, expiration time.Duration) *BoolCmd {
  386. cmd := NewBoolCmd("expire", key, formatSec(expiration))
  387. c.process(cmd)
  388. return cmd
  389. }
  390. func (c *cmdable) ExpireAt(key string, tm time.Time) *BoolCmd {
  391. cmd := NewBoolCmd("expireat", key, tm.Unix())
  392. c.process(cmd)
  393. return cmd
  394. }
  395. func (c *cmdable) Keys(pattern string) *StringSliceCmd {
  396. cmd := NewStringSliceCmd("keys", pattern)
  397. c.process(cmd)
  398. return cmd
  399. }
  400. func (c *cmdable) Migrate(host, port, key string, db int64, timeout time.Duration) *StatusCmd {
  401. cmd := NewStatusCmd(
  402. "migrate",
  403. host,
  404. port,
  405. key,
  406. db,
  407. formatMs(timeout),
  408. )
  409. cmd.setReadTimeout(timeout)
  410. c.process(cmd)
  411. return cmd
  412. }
  413. func (c *cmdable) Move(key string, db int64) *BoolCmd {
  414. cmd := NewBoolCmd("move", key, db)
  415. c.process(cmd)
  416. return cmd
  417. }
  418. func (c *cmdable) ObjectRefCount(key string) *IntCmd {
  419. cmd := NewIntCmd("object", "refcount", key)
  420. c.process(cmd)
  421. return cmd
  422. }
  423. func (c *cmdable) ObjectEncoding(key string) *StringCmd {
  424. cmd := NewStringCmd("object", "encoding", key)
  425. c.process(cmd)
  426. return cmd
  427. }
  428. func (c *cmdable) ObjectIdleTime(key string) *DurationCmd {
  429. cmd := NewDurationCmd(time.Second, "object", "idletime", key)
  430. c.process(cmd)
  431. return cmd
  432. }
  433. func (c *cmdable) Persist(key string) *BoolCmd {
  434. cmd := NewBoolCmd("persist", key)
  435. c.process(cmd)
  436. return cmd
  437. }
  438. func (c *cmdable) PExpire(key string, expiration time.Duration) *BoolCmd {
  439. cmd := NewBoolCmd("pexpire", key, formatMs(expiration))
  440. c.process(cmd)
  441. return cmd
  442. }
  443. func (c *cmdable) PExpireAt(key string, tm time.Time) *BoolCmd {
  444. cmd := NewBoolCmd(
  445. "pexpireat",
  446. key,
  447. tm.UnixNano()/int64(time.Millisecond),
  448. )
  449. c.process(cmd)
  450. return cmd
  451. }
  452. func (c *cmdable) PTTL(key string) *DurationCmd {
  453. cmd := NewDurationCmd(time.Millisecond, "pttl", key)
  454. c.process(cmd)
  455. return cmd
  456. }
  457. func (c *cmdable) RandomKey() *StringCmd {
  458. cmd := NewStringCmd("randomkey")
  459. c.process(cmd)
  460. return cmd
  461. }
  462. func (c *cmdable) Rename(key, newkey string) *StatusCmd {
  463. cmd := NewStatusCmd("rename", key, newkey)
  464. c.process(cmd)
  465. return cmd
  466. }
  467. func (c *cmdable) RenameNX(key, newkey string) *BoolCmd {
  468. cmd := NewBoolCmd("renamenx", key, newkey)
  469. c.process(cmd)
  470. return cmd
  471. }
  472. func (c *cmdable) Restore(key string, ttl time.Duration, value string) *StatusCmd {
  473. cmd := NewStatusCmd(
  474. "restore",
  475. key,
  476. formatMs(ttl),
  477. value,
  478. )
  479. c.process(cmd)
  480. return cmd
  481. }
  482. func (c *cmdable) RestoreReplace(key string, ttl time.Duration, value string) *StatusCmd {
  483. cmd := NewStatusCmd(
  484. "restore",
  485. key,
  486. formatMs(ttl),
  487. value,
  488. "replace",
  489. )
  490. c.process(cmd)
  491. return cmd
  492. }
  493. type Sort struct {
  494. By string
  495. Offset, Count int64
  496. Get []string
  497. Order string
  498. Alpha bool
  499. }
  500. func (sort *Sort) args(key string) []interface{} {
  501. args := []interface{}{"sort", key}
  502. if sort.By != "" {
  503. args = append(args, "by", sort.By)
  504. }
  505. if sort.Offset != 0 || sort.Count != 0 {
  506. args = append(args, "limit", sort.Offset, sort.Count)
  507. }
  508. for _, get := range sort.Get {
  509. args = append(args, "get", get)
  510. }
  511. if sort.Order != "" {
  512. args = append(args, sort.Order)
  513. }
  514. if sort.Alpha {
  515. args = append(args, "alpha")
  516. }
  517. return args
  518. }
  519. func (c *cmdable) Sort(key string, sort *Sort) *StringSliceCmd {
  520. cmd := NewStringSliceCmd(sort.args(key)...)
  521. c.process(cmd)
  522. return cmd
  523. }
  524. func (c *cmdable) SortStore(key, store string, sort *Sort) *IntCmd {
  525. args := sort.args(key)
  526. if store != "" {
  527. args = append(args, "store", store)
  528. }
  529. cmd := NewIntCmd(args...)
  530. c.process(cmd)
  531. return cmd
  532. }
  533. func (c *cmdable) SortInterfaces(key string, sort *Sort) *SliceCmd {
  534. cmd := NewSliceCmd(sort.args(key)...)
  535. c.process(cmd)
  536. return cmd
  537. }
  538. func (c *cmdable) Touch(keys ...string) *IntCmd {
  539. args := make([]interface{}, len(keys)+1)
  540. args[0] = "touch"
  541. for i, key := range keys {
  542. args[i+1] = key
  543. }
  544. cmd := NewIntCmd(args...)
  545. c.process(cmd)
  546. return cmd
  547. }
  548. func (c *cmdable) TTL(key string) *DurationCmd {
  549. cmd := NewDurationCmd(time.Second, "ttl", key)
  550. c.process(cmd)
  551. return cmd
  552. }
  553. func (c *cmdable) Type(key string) *StatusCmd {
  554. cmd := NewStatusCmd("type", key)
  555. c.process(cmd)
  556. return cmd
  557. }
  558. func (c *cmdable) Scan(cursor uint64, match string, count int64) *ScanCmd {
  559. args := []interface{}{"scan", cursor}
  560. if match != "" {
  561. args = append(args, "match", match)
  562. }
  563. if count > 0 {
  564. args = append(args, "count", count)
  565. }
  566. cmd := NewScanCmd(c.process, args...)
  567. c.process(cmd)
  568. return cmd
  569. }
  570. func (c *cmdable) SScan(key string, cursor uint64, match string, count int64) *ScanCmd {
  571. args := []interface{}{"sscan", key, cursor}
  572. if match != "" {
  573. args = append(args, "match", match)
  574. }
  575. if count > 0 {
  576. args = append(args, "count", count)
  577. }
  578. cmd := NewScanCmd(c.process, args...)
  579. c.process(cmd)
  580. return cmd
  581. }
  582. func (c *cmdable) HScan(key string, cursor uint64, match string, count int64) *ScanCmd {
  583. args := []interface{}{"hscan", key, cursor}
  584. if match != "" {
  585. args = append(args, "match", match)
  586. }
  587. if count > 0 {
  588. args = append(args, "count", count)
  589. }
  590. cmd := NewScanCmd(c.process, args...)
  591. c.process(cmd)
  592. return cmd
  593. }
  594. func (c *cmdable) ZScan(key string, cursor uint64, match string, count int64) *ScanCmd {
  595. args := []interface{}{"zscan", key, cursor}
  596. if match != "" {
  597. args = append(args, "match", match)
  598. }
  599. if count > 0 {
  600. args = append(args, "count", count)
  601. }
  602. cmd := NewScanCmd(c.process, args...)
  603. c.process(cmd)
  604. return cmd
  605. }
  606. //------------------------------------------------------------------------------
  607. func (c *cmdable) Append(key, value string) *IntCmd {
  608. cmd := NewIntCmd("append", key, value)
  609. c.process(cmd)
  610. return cmd
  611. }
  612. type BitCount struct {
  613. Start, End int64
  614. }
  615. func (c *cmdable) BitCount(key string, bitCount *BitCount) *IntCmd {
  616. args := []interface{}{"bitcount", key}
  617. if bitCount != nil {
  618. args = append(
  619. args,
  620. bitCount.Start,
  621. bitCount.End,
  622. )
  623. }
  624. cmd := NewIntCmd(args...)
  625. c.process(cmd)
  626. return cmd
  627. }
  628. func (c *cmdable) bitOp(op, destKey string, keys ...string) *IntCmd {
  629. args := make([]interface{}, 3+len(keys))
  630. args[0] = "bitop"
  631. args[1] = op
  632. args[2] = destKey
  633. for i, key := range keys {
  634. args[3+i] = key
  635. }
  636. cmd := NewIntCmd(args...)
  637. c.process(cmd)
  638. return cmd
  639. }
  640. func (c *cmdable) BitOpAnd(destKey string, keys ...string) *IntCmd {
  641. return c.bitOp("and", destKey, keys...)
  642. }
  643. func (c *cmdable) BitOpOr(destKey string, keys ...string) *IntCmd {
  644. return c.bitOp("or", destKey, keys...)
  645. }
  646. func (c *cmdable) BitOpXor(destKey string, keys ...string) *IntCmd {
  647. return c.bitOp("xor", destKey, keys...)
  648. }
  649. func (c *cmdable) BitOpNot(destKey string, key string) *IntCmd {
  650. return c.bitOp("not", destKey, key)
  651. }
  652. func (c *cmdable) BitPos(key string, bit int64, pos ...int64) *IntCmd {
  653. args := make([]interface{}, 3+len(pos))
  654. args[0] = "bitpos"
  655. args[1] = key
  656. args[2] = bit
  657. switch len(pos) {
  658. case 0:
  659. case 1:
  660. args[3] = pos[0]
  661. case 2:
  662. args[3] = pos[0]
  663. args[4] = pos[1]
  664. default:
  665. panic("too many arguments")
  666. }
  667. cmd := NewIntCmd(args...)
  668. c.process(cmd)
  669. return cmd
  670. }
  671. func (c *cmdable) Decr(key string) *IntCmd {
  672. cmd := NewIntCmd("decr", key)
  673. c.process(cmd)
  674. return cmd
  675. }
  676. func (c *cmdable) DecrBy(key string, decrement int64) *IntCmd {
  677. cmd := NewIntCmd("decrby", key, decrement)
  678. c.process(cmd)
  679. return cmd
  680. }
  681. // Redis `GET key` command. It returns redis.Nil error when key does not exist.
  682. func (c *cmdable) Get(key string) *StringCmd {
  683. cmd := NewStringCmd("get", key)
  684. c.process(cmd)
  685. return cmd
  686. }
  687. func (c *cmdable) GetBit(key string, offset int64) *IntCmd {
  688. cmd := NewIntCmd("getbit", key, offset)
  689. c.process(cmd)
  690. return cmd
  691. }
  692. func (c *cmdable) GetRange(key string, start, end int64) *StringCmd {
  693. cmd := NewStringCmd("getrange", key, start, end)
  694. c.process(cmd)
  695. return cmd
  696. }
  697. func (c *cmdable) GetSet(key string, value interface{}) *StringCmd {
  698. cmd := NewStringCmd("getset", key, value)
  699. c.process(cmd)
  700. return cmd
  701. }
  702. func (c *cmdable) Incr(key string) *IntCmd {
  703. cmd := NewIntCmd("incr", key)
  704. c.process(cmd)
  705. return cmd
  706. }
  707. func (c *cmdable) IncrBy(key string, value int64) *IntCmd {
  708. cmd := NewIntCmd("incrby", key, value)
  709. c.process(cmd)
  710. return cmd
  711. }
  712. func (c *cmdable) IncrByFloat(key string, value float64) *FloatCmd {
  713. cmd := NewFloatCmd("incrbyfloat", key, value)
  714. c.process(cmd)
  715. return cmd
  716. }
  717. func (c *cmdable) MGet(keys ...string) *SliceCmd {
  718. args := make([]interface{}, 1+len(keys))
  719. args[0] = "mget"
  720. for i, key := range keys {
  721. args[1+i] = key
  722. }
  723. cmd := NewSliceCmd(args...)
  724. c.process(cmd)
  725. return cmd
  726. }
  727. func (c *cmdable) MSet(pairs ...interface{}) *StatusCmd {
  728. args := make([]interface{}, 1, 1+len(pairs))
  729. args[0] = "mset"
  730. args = appendArgs(args, pairs)
  731. cmd := NewStatusCmd(args...)
  732. c.process(cmd)
  733. return cmd
  734. }
  735. func (c *cmdable) MSetNX(pairs ...interface{}) *BoolCmd {
  736. args := make([]interface{}, 1, 1+len(pairs))
  737. args[0] = "msetnx"
  738. args = appendArgs(args, pairs)
  739. cmd := NewBoolCmd(args...)
  740. c.process(cmd)
  741. return cmd
  742. }
  743. // Redis `SET key value [expiration]` command.
  744. //
  745. // Use expiration for `SETEX`-like behavior.
  746. // Zero expiration means the key has no expiration time.
  747. func (c *cmdable) Set(key string, value interface{}, expiration time.Duration) *StatusCmd {
  748. args := make([]interface{}, 3, 4)
  749. args[0] = "set"
  750. args[1] = key
  751. args[2] = value
  752. if expiration > 0 {
  753. if usePrecise(expiration) {
  754. args = append(args, "px", formatMs(expiration))
  755. } else {
  756. args = append(args, "ex", formatSec(expiration))
  757. }
  758. }
  759. cmd := NewStatusCmd(args...)
  760. c.process(cmd)
  761. return cmd
  762. }
  763. func (c *cmdable) SetBit(key string, offset int64, value int) *IntCmd {
  764. cmd := NewIntCmd(
  765. "setbit",
  766. key,
  767. offset,
  768. value,
  769. )
  770. c.process(cmd)
  771. return cmd
  772. }
  773. // Redis `SET key value [expiration] NX` command.
  774. //
  775. // Zero expiration means the key has no expiration time.
  776. func (c *cmdable) SetNX(key string, value interface{}, expiration time.Duration) *BoolCmd {
  777. var cmd *BoolCmd
  778. if expiration == 0 {
  779. // Use old `SETNX` to support old Redis versions.
  780. cmd = NewBoolCmd("setnx", key, value)
  781. } else {
  782. if usePrecise(expiration) {
  783. cmd = NewBoolCmd("set", key, value, "px", formatMs(expiration), "nx")
  784. } else {
  785. cmd = NewBoolCmd("set", key, value, "ex", formatSec(expiration), "nx")
  786. }
  787. }
  788. c.process(cmd)
  789. return cmd
  790. }
  791. // Redis `SET key value [expiration] XX` command.
  792. //
  793. // Zero expiration means the key has no expiration time.
  794. func (c *cmdable) SetXX(key string, value interface{}, expiration time.Duration) *BoolCmd {
  795. var cmd *BoolCmd
  796. if expiration == 0 {
  797. cmd = NewBoolCmd("set", key, value, "xx")
  798. } else {
  799. if usePrecise(expiration) {
  800. cmd = NewBoolCmd("set", key, value, "px", formatMs(expiration), "xx")
  801. } else {
  802. cmd = NewBoolCmd("set", key, value, "ex", formatSec(expiration), "xx")
  803. }
  804. }
  805. c.process(cmd)
  806. return cmd
  807. }
  808. func (c *cmdable) SetRange(key string, offset int64, value string) *IntCmd {
  809. cmd := NewIntCmd("setrange", key, offset, value)
  810. c.process(cmd)
  811. return cmd
  812. }
  813. func (c *cmdable) StrLen(key string) *IntCmd {
  814. cmd := NewIntCmd("strlen", key)
  815. c.process(cmd)
  816. return cmd
  817. }
  818. //------------------------------------------------------------------------------
  819. func (c *cmdable) HDel(key string, fields ...string) *IntCmd {
  820. args := make([]interface{}, 2+len(fields))
  821. args[0] = "hdel"
  822. args[1] = key
  823. for i, field := range fields {
  824. args[2+i] = field
  825. }
  826. cmd := NewIntCmd(args...)
  827. c.process(cmd)
  828. return cmd
  829. }
  830. func (c *cmdable) HExists(key, field string) *BoolCmd {
  831. cmd := NewBoolCmd("hexists", key, field)
  832. c.process(cmd)
  833. return cmd
  834. }
  835. func (c *cmdable) HGet(key, field string) *StringCmd {
  836. cmd := NewStringCmd("hget", key, field)
  837. c.process(cmd)
  838. return cmd
  839. }
  840. func (c *cmdable) HGetAll(key string) *StringStringMapCmd {
  841. cmd := NewStringStringMapCmd("hgetall", key)
  842. c.process(cmd)
  843. return cmd
  844. }
  845. func (c *cmdable) HIncrBy(key, field string, incr int64) *IntCmd {
  846. cmd := NewIntCmd("hincrby", key, field, incr)
  847. c.process(cmd)
  848. return cmd
  849. }
  850. func (c *cmdable) HIncrByFloat(key, field string, incr float64) *FloatCmd {
  851. cmd := NewFloatCmd("hincrbyfloat", key, field, incr)
  852. c.process(cmd)
  853. return cmd
  854. }
  855. func (c *cmdable) HKeys(key string) *StringSliceCmd {
  856. cmd := NewStringSliceCmd("hkeys", key)
  857. c.process(cmd)
  858. return cmd
  859. }
  860. func (c *cmdable) HLen(key string) *IntCmd {
  861. cmd := NewIntCmd("hlen", key)
  862. c.process(cmd)
  863. return cmd
  864. }
  865. func (c *cmdable) HMGet(key string, fields ...string) *SliceCmd {
  866. args := make([]interface{}, 2+len(fields))
  867. args[0] = "hmget"
  868. args[1] = key
  869. for i, field := range fields {
  870. args[2+i] = field
  871. }
  872. cmd := NewSliceCmd(args...)
  873. c.process(cmd)
  874. return cmd
  875. }
  876. func (c *cmdable) HMSet(key string, fields map[string]interface{}) *StatusCmd {
  877. args := make([]interface{}, 2+len(fields)*2)
  878. args[0] = "hmset"
  879. args[1] = key
  880. i := 2
  881. for k, v := range fields {
  882. args[i] = k
  883. args[i+1] = v
  884. i += 2
  885. }
  886. cmd := NewStatusCmd(args...)
  887. c.process(cmd)
  888. return cmd
  889. }
  890. func (c *cmdable) HSet(key, field string, value interface{}) *BoolCmd {
  891. cmd := NewBoolCmd("hset", key, field, value)
  892. c.process(cmd)
  893. return cmd
  894. }
  895. func (c *cmdable) HSetNX(key, field string, value interface{}) *BoolCmd {
  896. cmd := NewBoolCmd("hsetnx", key, field, value)
  897. c.process(cmd)
  898. return cmd
  899. }
  900. func (c *cmdable) HVals(key string) *StringSliceCmd {
  901. cmd := NewStringSliceCmd("hvals", key)
  902. c.process(cmd)
  903. return cmd
  904. }
  905. //------------------------------------------------------------------------------
  906. func (c *cmdable) BLPop(timeout time.Duration, keys ...string) *StringSliceCmd {
  907. args := make([]interface{}, 1+len(keys)+1)
  908. args[0] = "blpop"
  909. for i, key := range keys {
  910. args[1+i] = key
  911. }
  912. args[len(args)-1] = formatSec(timeout)
  913. cmd := NewStringSliceCmd(args...)
  914. cmd.setReadTimeout(timeout)
  915. c.process(cmd)
  916. return cmd
  917. }
  918. func (c *cmdable) BRPop(timeout time.Duration, keys ...string) *StringSliceCmd {
  919. args := make([]interface{}, 1+len(keys)+1)
  920. args[0] = "brpop"
  921. for i, key := range keys {
  922. args[1+i] = key
  923. }
  924. args[len(keys)+1] = formatSec(timeout)
  925. cmd := NewStringSliceCmd(args...)
  926. cmd.setReadTimeout(timeout)
  927. c.process(cmd)
  928. return cmd
  929. }
  930. func (c *cmdable) BRPopLPush(source, destination string, timeout time.Duration) *StringCmd {
  931. cmd := NewStringCmd(
  932. "brpoplpush",
  933. source,
  934. destination,
  935. formatSec(timeout),
  936. )
  937. cmd.setReadTimeout(timeout)
  938. c.process(cmd)
  939. return cmd
  940. }
  941. func (c *cmdable) LIndex(key string, index int64) *StringCmd {
  942. cmd := NewStringCmd("lindex", key, index)
  943. c.process(cmd)
  944. return cmd
  945. }
  946. func (c *cmdable) LInsert(key, op string, pivot, value interface{}) *IntCmd {
  947. cmd := NewIntCmd("linsert", key, op, pivot, value)
  948. c.process(cmd)
  949. return cmd
  950. }
  951. func (c *cmdable) LInsertBefore(key string, pivot, value interface{}) *IntCmd {
  952. cmd := NewIntCmd("linsert", key, "before", pivot, value)
  953. c.process(cmd)
  954. return cmd
  955. }
  956. func (c *cmdable) LInsertAfter(key string, pivot, value interface{}) *IntCmd {
  957. cmd := NewIntCmd("linsert", key, "after", pivot, value)
  958. c.process(cmd)
  959. return cmd
  960. }
  961. func (c *cmdable) LLen(key string) *IntCmd {
  962. cmd := NewIntCmd("llen", key)
  963. c.process(cmd)
  964. return cmd
  965. }
  966. func (c *cmdable) LPop(key string) *StringCmd {
  967. cmd := NewStringCmd("lpop", key)
  968. c.process(cmd)
  969. return cmd
  970. }
  971. func (c *cmdable) LPush(key string, values ...interface{}) *IntCmd {
  972. args := make([]interface{}, 2, 2+len(values))
  973. args[0] = "lpush"
  974. args[1] = key
  975. args = appendArgs(args, values)
  976. cmd := NewIntCmd(args...)
  977. c.process(cmd)
  978. return cmd
  979. }
  980. func (c *cmdable) LPushX(key string, value interface{}) *IntCmd {
  981. cmd := NewIntCmd("lpushx", key, value)
  982. c.process(cmd)
  983. return cmd
  984. }
  985. func (c *cmdable) LRange(key string, start, stop int64) *StringSliceCmd {
  986. cmd := NewStringSliceCmd(
  987. "lrange",
  988. key,
  989. start,
  990. stop,
  991. )
  992. c.process(cmd)
  993. return cmd
  994. }
  995. func (c *cmdable) LRem(key string, count int64, value interface{}) *IntCmd {
  996. cmd := NewIntCmd("lrem", key, count, value)
  997. c.process(cmd)
  998. return cmd
  999. }
  1000. func (c *cmdable) LSet(key string, index int64, value interface{}) *StatusCmd {
  1001. cmd := NewStatusCmd("lset", key, index, value)
  1002. c.process(cmd)
  1003. return cmd
  1004. }
  1005. func (c *cmdable) LTrim(key string, start, stop int64) *StatusCmd {
  1006. cmd := NewStatusCmd(
  1007. "ltrim",
  1008. key,
  1009. start,
  1010. stop,
  1011. )
  1012. c.process(cmd)
  1013. return cmd
  1014. }
  1015. func (c *cmdable) RPop(key string) *StringCmd {
  1016. cmd := NewStringCmd("rpop", key)
  1017. c.process(cmd)
  1018. return cmd
  1019. }
  1020. func (c *cmdable) RPopLPush(source, destination string) *StringCmd {
  1021. cmd := NewStringCmd("rpoplpush", source, destination)
  1022. c.process(cmd)
  1023. return cmd
  1024. }
  1025. func (c *cmdable) RPush(key string, values ...interface{}) *IntCmd {
  1026. args := make([]interface{}, 2, 2+len(values))
  1027. args[0] = "rpush"
  1028. args[1] = key
  1029. args = appendArgs(args, values)
  1030. cmd := NewIntCmd(args...)
  1031. c.process(cmd)
  1032. return cmd
  1033. }
  1034. func (c *cmdable) RPushX(key string, value interface{}) *IntCmd {
  1035. cmd := NewIntCmd("rpushx", key, value)
  1036. c.process(cmd)
  1037. return cmd
  1038. }
  1039. //------------------------------------------------------------------------------
  1040. func (c *cmdable) SAdd(key string, members ...interface{}) *IntCmd {
  1041. args := make([]interface{}, 2, 2+len(members))
  1042. args[0] = "sadd"
  1043. args[1] = key
  1044. args = appendArgs(args, members)
  1045. cmd := NewIntCmd(args...)
  1046. c.process(cmd)
  1047. return cmd
  1048. }
  1049. func (c *cmdable) SCard(key string) *IntCmd {
  1050. cmd := NewIntCmd("scard", key)
  1051. c.process(cmd)
  1052. return cmd
  1053. }
  1054. func (c *cmdable) SDiff(keys ...string) *StringSliceCmd {
  1055. args := make([]interface{}, 1+len(keys))
  1056. args[0] = "sdiff"
  1057. for i, key := range keys {
  1058. args[1+i] = key
  1059. }
  1060. cmd := NewStringSliceCmd(args...)
  1061. c.process(cmd)
  1062. return cmd
  1063. }
  1064. func (c *cmdable) SDiffStore(destination string, keys ...string) *IntCmd {
  1065. args := make([]interface{}, 2+len(keys))
  1066. args[0] = "sdiffstore"
  1067. args[1] = destination
  1068. for i, key := range keys {
  1069. args[2+i] = key
  1070. }
  1071. cmd := NewIntCmd(args...)
  1072. c.process(cmd)
  1073. return cmd
  1074. }
  1075. func (c *cmdable) SInter(keys ...string) *StringSliceCmd {
  1076. args := make([]interface{}, 1+len(keys))
  1077. args[0] = "sinter"
  1078. for i, key := range keys {
  1079. args[1+i] = key
  1080. }
  1081. cmd := NewStringSliceCmd(args...)
  1082. c.process(cmd)
  1083. return cmd
  1084. }
  1085. func (c *cmdable) SInterStore(destination string, keys ...string) *IntCmd {
  1086. args := make([]interface{}, 2+len(keys))
  1087. args[0] = "sinterstore"
  1088. args[1] = destination
  1089. for i, key := range keys {
  1090. args[2+i] = key
  1091. }
  1092. cmd := NewIntCmd(args...)
  1093. c.process(cmd)
  1094. return cmd
  1095. }
  1096. func (c *cmdable) SIsMember(key string, member interface{}) *BoolCmd {
  1097. cmd := NewBoolCmd("sismember", key, member)
  1098. c.process(cmd)
  1099. return cmd
  1100. }
  1101. // Redis `SMEMBERS key` command output as a slice
  1102. func (c *cmdable) SMembers(key string) *StringSliceCmd {
  1103. cmd := NewStringSliceCmd("smembers", key)
  1104. c.process(cmd)
  1105. return cmd
  1106. }
  1107. // Redis `SMEMBERS key` command output as a map
  1108. func (c *cmdable) SMembersMap(key string) *StringStructMapCmd {
  1109. cmd := NewStringStructMapCmd("smembers", key)
  1110. c.process(cmd)
  1111. return cmd
  1112. }
  1113. func (c *cmdable) SMove(source, destination string, member interface{}) *BoolCmd {
  1114. cmd := NewBoolCmd("smove", source, destination, member)
  1115. c.process(cmd)
  1116. return cmd
  1117. }
  1118. // Redis `SPOP key` command.
  1119. func (c *cmdable) SPop(key string) *StringCmd {
  1120. cmd := NewStringCmd("spop", key)
  1121. c.process(cmd)
  1122. return cmd
  1123. }
  1124. // Redis `SPOP key count` command.
  1125. func (c *cmdable) SPopN(key string, count int64) *StringSliceCmd {
  1126. cmd := NewStringSliceCmd("spop", key, count)
  1127. c.process(cmd)
  1128. return cmd
  1129. }
  1130. // Redis `SRANDMEMBER key` command.
  1131. func (c *cmdable) SRandMember(key string) *StringCmd {
  1132. cmd := NewStringCmd("srandmember", key)
  1133. c.process(cmd)
  1134. return cmd
  1135. }
  1136. // Redis `SRANDMEMBER key count` command.
  1137. func (c *cmdable) SRandMemberN(key string, count int64) *StringSliceCmd {
  1138. cmd := NewStringSliceCmd("srandmember", key, count)
  1139. c.process(cmd)
  1140. return cmd
  1141. }
  1142. func (c *cmdable) SRem(key string, members ...interface{}) *IntCmd {
  1143. args := make([]interface{}, 2, 2+len(members))
  1144. args[0] = "srem"
  1145. args[1] = key
  1146. args = appendArgs(args, members)
  1147. cmd := NewIntCmd(args...)
  1148. c.process(cmd)
  1149. return cmd
  1150. }
  1151. func (c *cmdable) SUnion(keys ...string) *StringSliceCmd {
  1152. args := make([]interface{}, 1+len(keys))
  1153. args[0] = "sunion"
  1154. for i, key := range keys {
  1155. args[1+i] = key
  1156. }
  1157. cmd := NewStringSliceCmd(args...)
  1158. c.process(cmd)
  1159. return cmd
  1160. }
  1161. func (c *cmdable) SUnionStore(destination string, keys ...string) *IntCmd {
  1162. args := make([]interface{}, 2+len(keys))
  1163. args[0] = "sunionstore"
  1164. args[1] = destination
  1165. for i, key := range keys {
  1166. args[2+i] = key
  1167. }
  1168. cmd := NewIntCmd(args...)
  1169. c.process(cmd)
  1170. return cmd
  1171. }
  1172. //------------------------------------------------------------------------------
  1173. type XAddArgs struct {
  1174. Stream string
  1175. MaxLen int64 // MAXLEN N
  1176. MaxLenApprox int64 // MAXLEN ~ N
  1177. ID string
  1178. Values map[string]interface{}
  1179. }
  1180. func (c *cmdable) XAdd(a *XAddArgs) *StringCmd {
  1181. args := make([]interface{}, 0, 6+len(a.Values)*2)
  1182. args = append(args, "xadd")
  1183. args = append(args, a.Stream)
  1184. if a.MaxLen > 0 {
  1185. args = append(args, "maxlen", a.MaxLen)
  1186. } else if a.MaxLenApprox > 0 {
  1187. args = append(args, "maxlen", "~", a.MaxLenApprox)
  1188. }
  1189. if a.ID != "" {
  1190. args = append(args, a.ID)
  1191. } else {
  1192. args = append(args, "*")
  1193. }
  1194. for k, v := range a.Values {
  1195. args = append(args, k)
  1196. args = append(args, v)
  1197. }
  1198. cmd := NewStringCmd(args...)
  1199. c.process(cmd)
  1200. return cmd
  1201. }
  1202. func (c *cmdable) XLen(stream string) *IntCmd {
  1203. cmd := NewIntCmd("xlen", stream)
  1204. c.process(cmd)
  1205. return cmd
  1206. }
  1207. func (c *cmdable) XRange(stream, start, stop string) *XMessageSliceCmd {
  1208. cmd := NewXMessageSliceCmd("xrange", stream, start, stop)
  1209. c.process(cmd)
  1210. return cmd
  1211. }
  1212. func (c *cmdable) XRangeN(stream, start, stop string, count int64) *XMessageSliceCmd {
  1213. cmd := NewXMessageSliceCmd("xrange", stream, start, stop, "count", count)
  1214. c.process(cmd)
  1215. return cmd
  1216. }
  1217. func (c *cmdable) XRevRange(stream, start, stop string) *XMessageSliceCmd {
  1218. cmd := NewXMessageSliceCmd("xrevrange", stream, start, stop)
  1219. c.process(cmd)
  1220. return cmd
  1221. }
  1222. func (c *cmdable) XRevRangeN(stream, start, stop string, count int64) *XMessageSliceCmd {
  1223. cmd := NewXMessageSliceCmd("xrevrange", stream, start, stop, "count", count)
  1224. c.process(cmd)
  1225. return cmd
  1226. }
  1227. type XReadArgs struct {
  1228. Streams []string
  1229. Count int64
  1230. Block time.Duration
  1231. }
  1232. func (c *cmdable) XRead(a *XReadArgs) *XStreamSliceCmd {
  1233. args := make([]interface{}, 0, 5+len(a.Streams))
  1234. args = append(args, "xread")
  1235. if a.Count > 0 {
  1236. args = append(args, "count")
  1237. args = append(args, a.Count)
  1238. }
  1239. if a.Block >= 0 {
  1240. args = append(args, "block")
  1241. args = append(args, int64(a.Block/time.Millisecond))
  1242. }
  1243. args = append(args, "streams")
  1244. for _, s := range a.Streams {
  1245. args = append(args, s)
  1246. }
  1247. cmd := NewXStreamSliceCmd(args...)
  1248. c.process(cmd)
  1249. return cmd
  1250. }
  1251. func (c *cmdable) XReadStreams(streams ...string) *XStreamSliceCmd {
  1252. return c.XRead(&XReadArgs{
  1253. Streams: streams,
  1254. Block: -1,
  1255. })
  1256. }
  1257. func (c *cmdable) XGroupCreate(stream, group, start string) *StatusCmd {
  1258. cmd := NewStatusCmd("xgroup", "create", stream, group, start)
  1259. c.process(cmd)
  1260. return cmd
  1261. }
  1262. func (c *cmdable) XGroupSetID(stream, group, start string) *StatusCmd {
  1263. cmd := NewStatusCmd("xgroup", "setid", stream, group, start)
  1264. c.process(cmd)
  1265. return cmd
  1266. }
  1267. func (c *cmdable) XGroupDestroy(stream, group string) *IntCmd {
  1268. cmd := NewIntCmd("xgroup", "destroy", stream, group)
  1269. c.process(cmd)
  1270. return cmd
  1271. }
  1272. func (c *cmdable) XGroupDelConsumer(stream, group, consumer string) *IntCmd {
  1273. cmd := NewIntCmd("xgroup", "delconsumer", stream, group, consumer)
  1274. c.process(cmd)
  1275. return cmd
  1276. }
  1277. type XReadGroupArgs struct {
  1278. Group string
  1279. Consumer string
  1280. Streams []string
  1281. Count int64
  1282. Block time.Duration
  1283. }
  1284. func (c *cmdable) XReadGroup(a *XReadGroupArgs) *XStreamSliceCmd {
  1285. args := make([]interface{}, 0, 8+len(a.Streams))
  1286. args = append(args, "xreadgroup", "group", a.Group, a.Consumer)
  1287. if a.Count > 0 {
  1288. args = append(args, "count", a.Count)
  1289. }
  1290. if a.Block >= 0 {
  1291. args = append(args, "block", int64(a.Block/time.Millisecond))
  1292. }
  1293. args = append(args, "streams")
  1294. for _, s := range a.Streams {
  1295. args = append(args, s)
  1296. }
  1297. cmd := NewXStreamSliceCmd(args...)
  1298. c.process(cmd)
  1299. return cmd
  1300. }
  1301. func (c *cmdable) XAck(stream, group string, ids ...string) *IntCmd {
  1302. args := []interface{}{"xack", stream, group}
  1303. for _, id := range ids {
  1304. args = append(args, id)
  1305. }
  1306. cmd := NewIntCmd(args...)
  1307. c.process(cmd)
  1308. return cmd
  1309. }
  1310. func (c *cmdable) XPending(stream, group string) *XPendingCmd {
  1311. cmd := NewXPendingCmd("xpending", stream, group)
  1312. c.process(cmd)
  1313. return cmd
  1314. }
  1315. type XPendingExtArgs struct {
  1316. Stream string
  1317. Group string
  1318. Start string
  1319. End string
  1320. Count int64
  1321. Consumer string
  1322. }
  1323. func (c *cmdable) XPendingExt(a *XPendingExtArgs) *XPendingExtCmd {
  1324. args := make([]interface{}, 0, 7)
  1325. args = append(args, "xpending", a.Stream, a.Group, a.Start, a.End, a.Count)
  1326. if a.Consumer != "" {
  1327. args = append(args, a.Consumer)
  1328. }
  1329. cmd := NewXPendingExtCmd(args...)
  1330. c.process(cmd)
  1331. return cmd
  1332. }
  1333. type XClaimArgs struct {
  1334. Stream string
  1335. Group string
  1336. Consumer string
  1337. MinIdle time.Duration
  1338. Messages []string
  1339. }
  1340. func (c *cmdable) XClaim(a *XClaimArgs) *XMessageSliceCmd {
  1341. args := xClaimArgs(a)
  1342. cmd := NewXMessageSliceCmd(args...)
  1343. c.process(cmd)
  1344. return cmd
  1345. }
  1346. func (c *cmdable) XClaimJustID(a *XClaimArgs) *StringSliceCmd {
  1347. args := xClaimArgs(a)
  1348. args = append(args, "justid")
  1349. cmd := NewStringSliceCmd(args...)
  1350. c.process(cmd)
  1351. return cmd
  1352. }
  1353. func xClaimArgs(a *XClaimArgs) []interface{} {
  1354. args := make([]interface{}, 0, 4+len(a.Messages))
  1355. args = append(args,
  1356. "xclaim",
  1357. a.Stream,
  1358. a.Group, a.Consumer,
  1359. int64(a.MinIdle/time.Millisecond))
  1360. for _, id := range a.Messages {
  1361. args = append(args, id)
  1362. }
  1363. return args
  1364. }
  1365. func (c *cmdable) XTrim(key string, maxLen int64) *IntCmd {
  1366. cmd := NewIntCmd("xtrim", key, "maxlen", maxLen)
  1367. c.process(cmd)
  1368. return cmd
  1369. }
  1370. func (c *cmdable) XTrimApprox(key string, maxLen int64) *IntCmd {
  1371. cmd := NewIntCmd("xtrim", key, "maxlen", "~", maxLen)
  1372. c.process(cmd)
  1373. return cmd
  1374. }
  1375. //------------------------------------------------------------------------------
  1376. // Z represents sorted set member.
  1377. type Z struct {
  1378. Score float64
  1379. Member interface{}
  1380. }
  1381. // ZStore is used as an arg to ZInterStore and ZUnionStore.
  1382. type ZStore struct {
  1383. Weights []float64
  1384. // Can be SUM, MIN or MAX.
  1385. Aggregate string
  1386. }
  1387. func (c *cmdable) zAdd(a []interface{}, n int, members ...Z) *IntCmd {
  1388. for i, m := range members {
  1389. a[n+2*i] = m.Score
  1390. a[n+2*i+1] = m.Member
  1391. }
  1392. cmd := NewIntCmd(a...)
  1393. c.process(cmd)
  1394. return cmd
  1395. }
  1396. // Redis `ZADD key score member [score member ...]` command.
  1397. func (c *cmdable) ZAdd(key string, members ...Z) *IntCmd {
  1398. const n = 2
  1399. a := make([]interface{}, n+2*len(members))
  1400. a[0], a[1] = "zadd", key
  1401. return c.zAdd(a, n, members...)
  1402. }
  1403. // Redis `ZADD key NX score member [score member ...]` command.
  1404. func (c *cmdable) ZAddNX(key string, members ...Z) *IntCmd {
  1405. const n = 3
  1406. a := make([]interface{}, n+2*len(members))
  1407. a[0], a[1], a[2] = "zadd", key, "nx"
  1408. return c.zAdd(a, n, members...)
  1409. }
  1410. // Redis `ZADD key XX score member [score member ...]` command.
  1411. func (c *cmdable) ZAddXX(key string, members ...Z) *IntCmd {
  1412. const n = 3
  1413. a := make([]interface{}, n+2*len(members))
  1414. a[0], a[1], a[2] = "zadd", key, "xx"
  1415. return c.zAdd(a, n, members...)
  1416. }
  1417. // Redis `ZADD key CH score member [score member ...]` command.
  1418. func (c *cmdable) ZAddCh(key string, members ...Z) *IntCmd {
  1419. const n = 3
  1420. a := make([]interface{}, n+2*len(members))
  1421. a[0], a[1], a[2] = "zadd", key, "ch"
  1422. return c.zAdd(a, n, members...)
  1423. }
  1424. // Redis `ZADD key NX CH score member [score member ...]` command.
  1425. func (c *cmdable) ZAddNXCh(key string, members ...Z) *IntCmd {
  1426. const n = 4
  1427. a := make([]interface{}, n+2*len(members))
  1428. a[0], a[1], a[2], a[3] = "zadd", key, "nx", "ch"
  1429. return c.zAdd(a, n, members...)
  1430. }
  1431. // Redis `ZADD key XX CH score member [score member ...]` command.
  1432. func (c *cmdable) ZAddXXCh(key string, members ...Z) *IntCmd {
  1433. const n = 4
  1434. a := make([]interface{}, n+2*len(members))
  1435. a[0], a[1], a[2], a[3] = "zadd", key, "xx", "ch"
  1436. return c.zAdd(a, n, members...)
  1437. }
  1438. func (c *cmdable) zIncr(a []interface{}, n int, members ...Z) *FloatCmd {
  1439. for i, m := range members {
  1440. a[n+2*i] = m.Score
  1441. a[n+2*i+1] = m.Member
  1442. }
  1443. cmd := NewFloatCmd(a...)
  1444. c.process(cmd)
  1445. return cmd
  1446. }
  1447. // Redis `ZADD key INCR score member` command.
  1448. func (c *cmdable) ZIncr(key string, member Z) *FloatCmd {
  1449. const n = 3
  1450. a := make([]interface{}, n+2)
  1451. a[0], a[1], a[2] = "zadd", key, "incr"
  1452. return c.zIncr(a, n, member)
  1453. }
  1454. // Redis `ZADD key NX INCR score member` command.
  1455. func (c *cmdable) ZIncrNX(key string, member Z) *FloatCmd {
  1456. const n = 4
  1457. a := make([]interface{}, n+2)
  1458. a[0], a[1], a[2], a[3] = "zadd", key, "incr", "nx"
  1459. return c.zIncr(a, n, member)
  1460. }
  1461. // Redis `ZADD key XX INCR score member` command.
  1462. func (c *cmdable) ZIncrXX(key string, member Z) *FloatCmd {
  1463. const n = 4
  1464. a := make([]interface{}, n+2)
  1465. a[0], a[1], a[2], a[3] = "zadd", key, "incr", "xx"
  1466. return c.zIncr(a, n, member)
  1467. }
  1468. func (c *cmdable) ZCard(key string) *IntCmd {
  1469. cmd := NewIntCmd("zcard", key)
  1470. c.process(cmd)
  1471. return cmd
  1472. }
  1473. func (c *cmdable) ZCount(key, min, max string) *IntCmd {
  1474. cmd := NewIntCmd("zcount", key, min, max)
  1475. c.process(cmd)
  1476. return cmd
  1477. }
  1478. func (c *cmdable) ZLexCount(key, min, max string) *IntCmd {
  1479. cmd := NewIntCmd("zlexcount", key, min, max)
  1480. c.process(cmd)
  1481. return cmd
  1482. }
  1483. func (c *cmdable) ZIncrBy(key string, increment float64, member string) *FloatCmd {
  1484. cmd := NewFloatCmd("zincrby", key, increment, member)
  1485. c.process(cmd)
  1486. return cmd
  1487. }
  1488. func (c *cmdable) ZInterStore(destination string, store ZStore, keys ...string) *IntCmd {
  1489. args := make([]interface{}, 3+len(keys))
  1490. args[0] = "zinterstore"
  1491. args[1] = destination
  1492. args[2] = len(keys)
  1493. for i, key := range keys {
  1494. args[3+i] = key
  1495. }
  1496. if len(store.Weights) > 0 {
  1497. args = append(args, "weights")
  1498. for _, weight := range store.Weights {
  1499. args = append(args, weight)
  1500. }
  1501. }
  1502. if store.Aggregate != "" {
  1503. args = append(args, "aggregate", store.Aggregate)
  1504. }
  1505. cmd := NewIntCmd(args...)
  1506. c.process(cmd)
  1507. return cmd
  1508. }
  1509. func (c *cmdable) ZPopMax(key string, count ...int64) *ZSliceCmd {
  1510. args := []interface{}{
  1511. "zpopmax",
  1512. key,
  1513. }
  1514. switch len(count) {
  1515. case 0:
  1516. break
  1517. case 1:
  1518. args = append(args, count[0])
  1519. default:
  1520. panic("too many arguments")
  1521. }
  1522. cmd := NewZSliceCmd(args...)
  1523. c.process(cmd)
  1524. return cmd
  1525. }
  1526. func (c *cmdable) ZPopMin(key string, count ...int64) *ZSliceCmd {
  1527. args := []interface{}{
  1528. "zpopmin",
  1529. key,
  1530. }
  1531. switch len(count) {
  1532. case 0:
  1533. break
  1534. case 1:
  1535. args = append(args, count[0])
  1536. default:
  1537. panic("too many arguments")
  1538. }
  1539. cmd := NewZSliceCmd(args...)
  1540. c.process(cmd)
  1541. return cmd
  1542. }
  1543. func (c *cmdable) zRange(key string, start, stop int64, withScores bool) *StringSliceCmd {
  1544. args := []interface{}{
  1545. "zrange",
  1546. key,
  1547. start,
  1548. stop,
  1549. }
  1550. if withScores {
  1551. args = append(args, "withscores")
  1552. }
  1553. cmd := NewStringSliceCmd(args...)
  1554. c.process(cmd)
  1555. return cmd
  1556. }
  1557. func (c *cmdable) ZRange(key string, start, stop int64) *StringSliceCmd {
  1558. return c.zRange(key, start, stop, false)
  1559. }
  1560. func (c *cmdable) ZRangeWithScores(key string, start, stop int64) *ZSliceCmd {
  1561. cmd := NewZSliceCmd("zrange", key, start, stop, "withscores")
  1562. c.process(cmd)
  1563. return cmd
  1564. }
  1565. type ZRangeBy struct {
  1566. Min, Max string
  1567. Offset, Count int64
  1568. }
  1569. func (c *cmdable) zRangeBy(zcmd, key string, opt ZRangeBy, withScores bool) *StringSliceCmd {
  1570. args := []interface{}{zcmd, key, opt.Min, opt.Max}
  1571. if withScores {
  1572. args = append(args, "withscores")
  1573. }
  1574. if opt.Offset != 0 || opt.Count != 0 {
  1575. args = append(
  1576. args,
  1577. "limit",
  1578. opt.Offset,
  1579. opt.Count,
  1580. )
  1581. }
  1582. cmd := NewStringSliceCmd(args...)
  1583. c.process(cmd)
  1584. return cmd
  1585. }
  1586. func (c *cmdable) ZRangeByScore(key string, opt ZRangeBy) *StringSliceCmd {
  1587. return c.zRangeBy("zrangebyscore", key, opt, false)
  1588. }
  1589. func (c *cmdable) ZRangeByLex(key string, opt ZRangeBy) *StringSliceCmd {
  1590. return c.zRangeBy("zrangebylex", key, opt, false)
  1591. }
  1592. func (c *cmdable) ZRangeByScoreWithScores(key string, opt ZRangeBy) *ZSliceCmd {
  1593. args := []interface{}{"zrangebyscore", key, opt.Min, opt.Max, "withscores"}
  1594. if opt.Offset != 0 || opt.Count != 0 {
  1595. args = append(
  1596. args,
  1597. "limit",
  1598. opt.Offset,
  1599. opt.Count,
  1600. )
  1601. }
  1602. cmd := NewZSliceCmd(args...)
  1603. c.process(cmd)
  1604. return cmd
  1605. }
  1606. func (c *cmdable) ZRank(key, member string) *IntCmd {
  1607. cmd := NewIntCmd("zrank", key, member)
  1608. c.process(cmd)
  1609. return cmd
  1610. }
  1611. func (c *cmdable) ZRem(key string, members ...interface{}) *IntCmd {
  1612. args := make([]interface{}, 2, 2+len(members))
  1613. args[0] = "zrem"
  1614. args[1] = key
  1615. args = appendArgs(args, members)
  1616. cmd := NewIntCmd(args...)
  1617. c.process(cmd)
  1618. return cmd
  1619. }
  1620. func (c *cmdable) ZRemRangeByRank(key string, start, stop int64) *IntCmd {
  1621. cmd := NewIntCmd(
  1622. "zremrangebyrank",
  1623. key,
  1624. start,
  1625. stop,
  1626. )
  1627. c.process(cmd)
  1628. return cmd
  1629. }
  1630. func (c *cmdable) ZRemRangeByScore(key, min, max string) *IntCmd {
  1631. cmd := NewIntCmd("zremrangebyscore", key, min, max)
  1632. c.process(cmd)
  1633. return cmd
  1634. }
  1635. func (c *cmdable) ZRemRangeByLex(key, min, max string) *IntCmd {
  1636. cmd := NewIntCmd("zremrangebylex", key, min, max)
  1637. c.process(cmd)
  1638. return cmd
  1639. }
  1640. func (c *cmdable) ZRevRange(key string, start, stop int64) *StringSliceCmd {
  1641. cmd := NewStringSliceCmd("zrevrange", key, start, stop)
  1642. c.process(cmd)
  1643. return cmd
  1644. }
  1645. func (c *cmdable) ZRevRangeWithScores(key string, start, stop int64) *ZSliceCmd {
  1646. cmd := NewZSliceCmd("zrevrange", key, start, stop, "withscores")
  1647. c.process(cmd)
  1648. return cmd
  1649. }
  1650. func (c *cmdable) zRevRangeBy(zcmd, key string, opt ZRangeBy) *StringSliceCmd {
  1651. args := []interface{}{zcmd, key, opt.Max, opt.Min}
  1652. if opt.Offset != 0 || opt.Count != 0 {
  1653. args = append(
  1654. args,
  1655. "limit",
  1656. opt.Offset,
  1657. opt.Count,
  1658. )
  1659. }
  1660. cmd := NewStringSliceCmd(args...)
  1661. c.process(cmd)
  1662. return cmd
  1663. }
  1664. func (c *cmdable) ZRevRangeByScore(key string, opt ZRangeBy) *StringSliceCmd {
  1665. return c.zRevRangeBy("zrevrangebyscore", key, opt)
  1666. }
  1667. func (c *cmdable) ZRevRangeByLex(key string, opt ZRangeBy) *StringSliceCmd {
  1668. return c.zRevRangeBy("zrevrangebylex", key, opt)
  1669. }
  1670. func (c *cmdable) ZRevRangeByScoreWithScores(key string, opt ZRangeBy) *ZSliceCmd {
  1671. args := []interface{}{"zrevrangebyscore", key, opt.Max, opt.Min, "withscores"}
  1672. if opt.Offset != 0 || opt.Count != 0 {
  1673. args = append(
  1674. args,
  1675. "limit",
  1676. opt.Offset,
  1677. opt.Count,
  1678. )
  1679. }
  1680. cmd := NewZSliceCmd(args...)
  1681. c.process(cmd)
  1682. return cmd
  1683. }
  1684. func (c *cmdable) ZRevRank(key, member string) *IntCmd {
  1685. cmd := NewIntCmd("zrevrank", key, member)
  1686. c.process(cmd)
  1687. return cmd
  1688. }
  1689. func (c *cmdable) ZScore(key, member string) *FloatCmd {
  1690. cmd := NewFloatCmd("zscore", key, member)
  1691. c.process(cmd)
  1692. return cmd
  1693. }
  1694. func (c *cmdable) ZUnionStore(dest string, store ZStore, keys ...string) *IntCmd {
  1695. args := make([]interface{}, 3+len(keys))
  1696. args[0] = "zunionstore"
  1697. args[1] = dest
  1698. args[2] = len(keys)
  1699. for i, key := range keys {
  1700. args[3+i] = key
  1701. }
  1702. if len(store.Weights) > 0 {
  1703. args = append(args, "weights")
  1704. for _, weight := range store.Weights {
  1705. args = append(args, weight)
  1706. }
  1707. }
  1708. if store.Aggregate != "" {
  1709. args = append(args, "aggregate", store.Aggregate)
  1710. }
  1711. cmd := NewIntCmd(args...)
  1712. c.process(cmd)
  1713. return cmd
  1714. }
  1715. //------------------------------------------------------------------------------
  1716. func (c *cmdable) PFAdd(key string, els ...interface{}) *IntCmd {
  1717. args := make([]interface{}, 2, 2+len(els))
  1718. args[0] = "pfadd"
  1719. args[1] = key
  1720. args = appendArgs(args, els)
  1721. cmd := NewIntCmd(args...)
  1722. c.process(cmd)
  1723. return cmd
  1724. }
  1725. func (c *cmdable) PFCount(keys ...string) *IntCmd {
  1726. args := make([]interface{}, 1+len(keys))
  1727. args[0] = "pfcount"
  1728. for i, key := range keys {
  1729. args[1+i] = key
  1730. }
  1731. cmd := NewIntCmd(args...)
  1732. c.process(cmd)
  1733. return cmd
  1734. }
  1735. func (c *cmdable) PFMerge(dest string, keys ...string) *StatusCmd {
  1736. args := make([]interface{}, 2+len(keys))
  1737. args[0] = "pfmerge"
  1738. args[1] = dest
  1739. for i, key := range keys {
  1740. args[2+i] = key
  1741. }
  1742. cmd := NewStatusCmd(args...)
  1743. c.process(cmd)
  1744. return cmd
  1745. }
  1746. //------------------------------------------------------------------------------
  1747. func (c *cmdable) BgRewriteAOF() *StatusCmd {
  1748. cmd := NewStatusCmd("bgrewriteaof")
  1749. c.process(cmd)
  1750. return cmd
  1751. }
  1752. func (c *cmdable) BgSave() *StatusCmd {
  1753. cmd := NewStatusCmd("bgsave")
  1754. c.process(cmd)
  1755. return cmd
  1756. }
  1757. func (c *cmdable) ClientKill(ipPort string) *StatusCmd {
  1758. cmd := NewStatusCmd("client", "kill", ipPort)
  1759. c.process(cmd)
  1760. return cmd
  1761. }
  1762. // ClientKillByFilter is new style synx, while the ClientKill is old
  1763. // CLIENT KILL <option> [value] ... <option> [value]
  1764. func (c *cmdable) ClientKillByFilter(keys ...string) *IntCmd {
  1765. args := make([]interface{}, 2+len(keys))
  1766. args[0] = "client"
  1767. args[1] = "kill"
  1768. for i, key := range keys {
  1769. args[2+i] = key
  1770. }
  1771. cmd := NewIntCmd(args...)
  1772. c.process(cmd)
  1773. return cmd
  1774. }
  1775. func (c *cmdable) ClientList() *StringCmd {
  1776. cmd := NewStringCmd("client", "list")
  1777. c.process(cmd)
  1778. return cmd
  1779. }
  1780. func (c *cmdable) ClientPause(dur time.Duration) *BoolCmd {
  1781. cmd := NewBoolCmd("client", "pause", formatMs(dur))
  1782. c.process(cmd)
  1783. return cmd
  1784. }
  1785. // ClientSetName assigns a name to the connection.
  1786. func (c *statefulCmdable) ClientSetName(name string) *BoolCmd {
  1787. cmd := NewBoolCmd("client", "setname", name)
  1788. c.process(cmd)
  1789. return cmd
  1790. }
  1791. // ClientGetName returns the name of the connection.
  1792. func (c *cmdable) ClientGetName() *StringCmd {
  1793. cmd := NewStringCmd("client", "getname")
  1794. c.process(cmd)
  1795. return cmd
  1796. }
  1797. func (c *cmdable) ConfigGet(parameter string) *SliceCmd {
  1798. cmd := NewSliceCmd("config", "get", parameter)
  1799. c.process(cmd)
  1800. return cmd
  1801. }
  1802. func (c *cmdable) ConfigResetStat() *StatusCmd {
  1803. cmd := NewStatusCmd("config", "resetstat")
  1804. c.process(cmd)
  1805. return cmd
  1806. }
  1807. func (c *cmdable) ConfigSet(parameter, value string) *StatusCmd {
  1808. cmd := NewStatusCmd("config", "set", parameter, value)
  1809. c.process(cmd)
  1810. return cmd
  1811. }
  1812. func (c *cmdable) ConfigRewrite() *StatusCmd {
  1813. cmd := NewStatusCmd("config", "rewrite")
  1814. c.process(cmd)
  1815. return cmd
  1816. }
  1817. // Deperecated. Use DBSize instead.
  1818. func (c *cmdable) DbSize() *IntCmd {
  1819. return c.DBSize()
  1820. }
  1821. func (c *cmdable) DBSize() *IntCmd {
  1822. cmd := NewIntCmd("dbsize")
  1823. c.process(cmd)
  1824. return cmd
  1825. }
  1826. func (c *cmdable) FlushAll() *StatusCmd {
  1827. cmd := NewStatusCmd("flushall")
  1828. c.process(cmd)
  1829. return cmd
  1830. }
  1831. func (c *cmdable) FlushAllAsync() *StatusCmd {
  1832. cmd := NewStatusCmd("flushall", "async")
  1833. c.process(cmd)
  1834. return cmd
  1835. }
  1836. // Deprecated. Use FlushDB instead.
  1837. func (c *cmdable) FlushDb() *StatusCmd {
  1838. return c.FlushDB()
  1839. }
  1840. func (c *cmdable) FlushDB() *StatusCmd {
  1841. cmd := NewStatusCmd("flushdb")
  1842. c.process(cmd)
  1843. return cmd
  1844. }
  1845. func (c *cmdable) FlushDBAsync() *StatusCmd {
  1846. cmd := NewStatusCmd("flushdb", "async")
  1847. c.process(cmd)
  1848. return cmd
  1849. }
  1850. func (c *cmdable) Info(section ...string) *StringCmd {
  1851. args := []interface{}{"info"}
  1852. if len(section) > 0 {
  1853. args = append(args, section[0])
  1854. }
  1855. cmd := NewStringCmd(args...)
  1856. c.process(cmd)
  1857. return cmd
  1858. }
  1859. func (c *cmdable) LastSave() *IntCmd {
  1860. cmd := NewIntCmd("lastsave")
  1861. c.process(cmd)
  1862. return cmd
  1863. }
  1864. func (c *cmdable) Save() *StatusCmd {
  1865. cmd := NewStatusCmd("save")
  1866. c.process(cmd)
  1867. return cmd
  1868. }
  1869. func (c *cmdable) shutdown(modifier string) *StatusCmd {
  1870. var args []interface{}
  1871. if modifier == "" {
  1872. args = []interface{}{"shutdown"}
  1873. } else {
  1874. args = []interface{}{"shutdown", modifier}
  1875. }
  1876. cmd := NewStatusCmd(args...)
  1877. c.process(cmd)
  1878. if err := cmd.Err(); err != nil {
  1879. if err == io.EOF {
  1880. // Server quit as expected.
  1881. cmd.err = nil
  1882. }
  1883. } else {
  1884. // Server did not quit. String reply contains the reason.
  1885. cmd.err = errors.New(cmd.val)
  1886. cmd.val = ""
  1887. }
  1888. return cmd
  1889. }
  1890. func (c *cmdable) Shutdown() *StatusCmd {
  1891. return c.shutdown("")
  1892. }
  1893. func (c *cmdable) ShutdownSave() *StatusCmd {
  1894. return c.shutdown("save")
  1895. }
  1896. func (c *cmdable) ShutdownNoSave() *StatusCmd {
  1897. return c.shutdown("nosave")
  1898. }
  1899. func (c *cmdable) SlaveOf(host, port string) *StatusCmd {
  1900. cmd := NewStatusCmd("slaveof", host, port)
  1901. c.process(cmd)
  1902. return cmd
  1903. }
  1904. func (c *cmdable) SlowLog() {
  1905. panic("not implemented")
  1906. }
  1907. func (c *cmdable) Sync() {
  1908. panic("not implemented")
  1909. }
  1910. func (c *cmdable) Time() *TimeCmd {
  1911. cmd := NewTimeCmd("time")
  1912. c.process(cmd)
  1913. return cmd
  1914. }
  1915. //------------------------------------------------------------------------------
  1916. func (c *cmdable) Eval(script string, keys []string, args ...interface{}) *Cmd {
  1917. cmdArgs := make([]interface{}, 3+len(keys), 3+len(keys)+len(args))
  1918. cmdArgs[0] = "eval"
  1919. cmdArgs[1] = script
  1920. cmdArgs[2] = len(keys)
  1921. for i, key := range keys {
  1922. cmdArgs[3+i] = key
  1923. }
  1924. cmdArgs = appendArgs(cmdArgs, args)
  1925. cmd := NewCmd(cmdArgs...)
  1926. c.process(cmd)
  1927. return cmd
  1928. }
  1929. func (c *cmdable) EvalSha(sha1 string, keys []string, args ...interface{}) *Cmd {
  1930. cmdArgs := make([]interface{}, 3+len(keys), 3+len(keys)+len(args))
  1931. cmdArgs[0] = "evalsha"
  1932. cmdArgs[1] = sha1
  1933. cmdArgs[2] = len(keys)
  1934. for i, key := range keys {
  1935. cmdArgs[3+i] = key
  1936. }
  1937. cmdArgs = appendArgs(cmdArgs, args)
  1938. cmd := NewCmd(cmdArgs...)
  1939. c.process(cmd)
  1940. return cmd
  1941. }
  1942. func (c *cmdable) ScriptExists(hashes ...string) *BoolSliceCmd {
  1943. args := make([]interface{}, 2+len(hashes))
  1944. args[0] = "script"
  1945. args[1] = "exists"
  1946. for i, hash := range hashes {
  1947. args[2+i] = hash
  1948. }
  1949. cmd := NewBoolSliceCmd(args...)
  1950. c.process(cmd)
  1951. return cmd
  1952. }
  1953. func (c *cmdable) ScriptFlush() *StatusCmd {
  1954. cmd := NewStatusCmd("script", "flush")
  1955. c.process(cmd)
  1956. return cmd
  1957. }
  1958. func (c *cmdable) ScriptKill() *StatusCmd {
  1959. cmd := NewStatusCmd("script", "kill")
  1960. c.process(cmd)
  1961. return cmd
  1962. }
  1963. func (c *cmdable) ScriptLoad(script string) *StringCmd {
  1964. cmd := NewStringCmd("script", "load", script)
  1965. c.process(cmd)
  1966. return cmd
  1967. }
  1968. //------------------------------------------------------------------------------
  1969. func (c *cmdable) DebugObject(key string) *StringCmd {
  1970. cmd := NewStringCmd("debug", "object", key)
  1971. c.process(cmd)
  1972. return cmd
  1973. }
  1974. //------------------------------------------------------------------------------
  1975. // Publish posts the message to the channel.
  1976. func (c *cmdable) Publish(channel string, message interface{}) *IntCmd {
  1977. cmd := NewIntCmd("publish", channel, message)
  1978. c.process(cmd)
  1979. return cmd
  1980. }
  1981. func (c *cmdable) PubSubChannels(pattern string) *StringSliceCmd {
  1982. args := []interface{}{"pubsub", "channels"}
  1983. if pattern != "*" {
  1984. args = append(args, pattern)
  1985. }
  1986. cmd := NewStringSliceCmd(args...)
  1987. c.process(cmd)
  1988. return cmd
  1989. }
  1990. func (c *cmdable) PubSubNumSub(channels ...string) *StringIntMapCmd {
  1991. args := make([]interface{}, 2+len(channels))
  1992. args[0] = "pubsub"
  1993. args[1] = "numsub"
  1994. for i, channel := range channels {
  1995. args[2+i] = channel
  1996. }
  1997. cmd := NewStringIntMapCmd(args...)
  1998. c.process(cmd)
  1999. return cmd
  2000. }
  2001. func (c *cmdable) PubSubNumPat() *IntCmd {
  2002. cmd := NewIntCmd("pubsub", "numpat")
  2003. c.process(cmd)
  2004. return cmd
  2005. }
  2006. //------------------------------------------------------------------------------
  2007. func (c *cmdable) ClusterSlots() *ClusterSlotsCmd {
  2008. cmd := NewClusterSlotsCmd("cluster", "slots")
  2009. c.process(cmd)
  2010. return cmd
  2011. }
  2012. func (c *cmdable) ClusterNodes() *StringCmd {
  2013. cmd := NewStringCmd("cluster", "nodes")
  2014. c.process(cmd)
  2015. return cmd
  2016. }
  2017. func (c *cmdable) ClusterMeet(host, port string) *StatusCmd {
  2018. cmd := NewStatusCmd("cluster", "meet", host, port)
  2019. c.process(cmd)
  2020. return cmd
  2021. }
  2022. func (c *cmdable) ClusterForget(nodeID string) *StatusCmd {
  2023. cmd := NewStatusCmd("cluster", "forget", nodeID)
  2024. c.process(cmd)
  2025. return cmd
  2026. }
  2027. func (c *cmdable) ClusterReplicate(nodeID string) *StatusCmd {
  2028. cmd := NewStatusCmd("cluster", "replicate", nodeID)
  2029. c.process(cmd)
  2030. return cmd
  2031. }
  2032. func (c *cmdable) ClusterResetSoft() *StatusCmd {
  2033. cmd := NewStatusCmd("cluster", "reset", "soft")
  2034. c.process(cmd)
  2035. return cmd
  2036. }
  2037. func (c *cmdable) ClusterResetHard() *StatusCmd {
  2038. cmd := NewStatusCmd("cluster", "reset", "hard")
  2039. c.process(cmd)
  2040. return cmd
  2041. }
  2042. func (c *cmdable) ClusterInfo() *StringCmd {
  2043. cmd := NewStringCmd("cluster", "info")
  2044. c.process(cmd)
  2045. return cmd
  2046. }
  2047. func (c *cmdable) ClusterKeySlot(key string) *IntCmd {
  2048. cmd := NewIntCmd("cluster", "keyslot", key)
  2049. c.process(cmd)
  2050. return cmd
  2051. }
  2052. func (c *cmdable) ClusterCountFailureReports(nodeID string) *IntCmd {
  2053. cmd := NewIntCmd("cluster", "count-failure-reports", nodeID)
  2054. c.process(cmd)
  2055. return cmd
  2056. }
  2057. func (c *cmdable) ClusterCountKeysInSlot(slot int) *IntCmd {
  2058. cmd := NewIntCmd("cluster", "countkeysinslot", slot)
  2059. c.process(cmd)
  2060. return cmd
  2061. }
  2062. func (c *cmdable) ClusterDelSlots(slots ...int) *StatusCmd {
  2063. args := make([]interface{}, 2+len(slots))
  2064. args[0] = "cluster"
  2065. args[1] = "delslots"
  2066. for i, slot := range slots {
  2067. args[2+i] = slot
  2068. }
  2069. cmd := NewStatusCmd(args...)
  2070. c.process(cmd)
  2071. return cmd
  2072. }
  2073. func (c *cmdable) ClusterDelSlotsRange(min, max int) *StatusCmd {
  2074. size := max - min + 1
  2075. slots := make([]int, size)
  2076. for i := 0; i < size; i++ {
  2077. slots[i] = min + i
  2078. }
  2079. return c.ClusterDelSlots(slots...)
  2080. }
  2081. func (c *cmdable) ClusterSaveConfig() *StatusCmd {
  2082. cmd := NewStatusCmd("cluster", "saveconfig")
  2083. c.process(cmd)
  2084. return cmd
  2085. }
  2086. func (c *cmdable) ClusterSlaves(nodeID string) *StringSliceCmd {
  2087. cmd := NewStringSliceCmd("cluster", "slaves", nodeID)
  2088. c.process(cmd)
  2089. return cmd
  2090. }
  2091. func (c *cmdable) ReadOnly() *StatusCmd {
  2092. cmd := NewStatusCmd("readonly")
  2093. c.process(cmd)
  2094. return cmd
  2095. }
  2096. func (c *cmdable) ReadWrite() *StatusCmd {
  2097. cmd := NewStatusCmd("readwrite")
  2098. c.process(cmd)
  2099. return cmd
  2100. }
  2101. func (c *cmdable) ClusterFailover() *StatusCmd {
  2102. cmd := NewStatusCmd("cluster", "failover")
  2103. c.process(cmd)
  2104. return cmd
  2105. }
  2106. func (c *cmdable) ClusterAddSlots(slots ...int) *StatusCmd {
  2107. args := make([]interface{}, 2+len(slots))
  2108. args[0] = "cluster"
  2109. args[1] = "addslots"
  2110. for i, num := range slots {
  2111. args[2+i] = num
  2112. }
  2113. cmd := NewStatusCmd(args...)
  2114. c.process(cmd)
  2115. return cmd
  2116. }
  2117. func (c *cmdable) ClusterAddSlotsRange(min, max int) *StatusCmd {
  2118. size := max - min + 1
  2119. slots := make([]int, size)
  2120. for i := 0; i < size; i++ {
  2121. slots[i] = min + i
  2122. }
  2123. return c.ClusterAddSlots(slots...)
  2124. }
  2125. //------------------------------------------------------------------------------
  2126. func (c *cmdable) GeoAdd(key string, geoLocation ...*GeoLocation) *IntCmd {
  2127. args := make([]interface{}, 2+3*len(geoLocation))
  2128. args[0] = "geoadd"
  2129. args[1] = key
  2130. for i, eachLoc := range geoLocation {
  2131. args[2+3*i] = eachLoc.Longitude
  2132. args[2+3*i+1] = eachLoc.Latitude
  2133. args[2+3*i+2] = eachLoc.Name
  2134. }
  2135. cmd := NewIntCmd(args...)
  2136. c.process(cmd)
  2137. return cmd
  2138. }
  2139. func (c *cmdable) GeoRadius(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd {
  2140. cmd := NewGeoLocationCmd(query, "georadius", key, longitude, latitude)
  2141. c.process(cmd)
  2142. return cmd
  2143. }
  2144. func (c *cmdable) GeoRadiusRO(key string, longitude, latitude float64, query *GeoRadiusQuery) *GeoLocationCmd {
  2145. cmd := NewGeoLocationCmd(query, "georadius_ro", key, longitude, latitude)
  2146. c.process(cmd)
  2147. return cmd
  2148. }
  2149. func (c *cmdable) GeoRadiusByMember(key, member string, query *GeoRadiusQuery) *GeoLocationCmd {
  2150. cmd := NewGeoLocationCmd(query, "georadiusbymember", key, member)
  2151. c.process(cmd)
  2152. return cmd
  2153. }
  2154. func (c *cmdable) GeoRadiusByMemberRO(key, member string, query *GeoRadiusQuery) *GeoLocationCmd {
  2155. cmd := NewGeoLocationCmd(query, "georadiusbymember_ro", key, member)
  2156. c.process(cmd)
  2157. return cmd
  2158. }
  2159. func (c *cmdable) GeoDist(key string, member1, member2, unit string) *FloatCmd {
  2160. if unit == "" {
  2161. unit = "km"
  2162. }
  2163. cmd := NewFloatCmd("geodist", key, member1, member2, unit)
  2164. c.process(cmd)
  2165. return cmd
  2166. }
  2167. func (c *cmdable) GeoHash(key string, members ...string) *StringSliceCmd {
  2168. args := make([]interface{}, 2+len(members))
  2169. args[0] = "geohash"
  2170. args[1] = key
  2171. for i, member := range members {
  2172. args[2+i] = member
  2173. }
  2174. cmd := NewStringSliceCmd(args...)
  2175. c.process(cmd)
  2176. return cmd
  2177. }
  2178. func (c *cmdable) GeoPos(key string, members ...string) *GeoPosCmd {
  2179. args := make([]interface{}, 2+len(members))
  2180. args[0] = "geopos"
  2181. args[1] = key
  2182. for i, member := range members {
  2183. args[2+i] = member
  2184. }
  2185. cmd := NewGeoPosCmd(args...)
  2186. c.process(cmd)
  2187. return cmd
  2188. }
  2189. //------------------------------------------------------------------------------
  2190. func (c *cmdable) MemoryUsage(key string, samples ...int) *IntCmd {
  2191. args := []interface{}{"memory", "usage", key}
  2192. if len(samples) > 0 {
  2193. if len(samples) != 1 {
  2194. panic("MemoryUsage expects single sample count")
  2195. }
  2196. args = append(args, "SAMPLES", samples[0])
  2197. }
  2198. cmd := NewIntCmd(args...)
  2199. c.process(cmd)
  2200. return cmd
  2201. }