github.com/flower-corp/rosedb@v1.1.2-0.20230117132829-21dc4f7b319a/cmd/command.go (about) 1 package main 2 3 import ( 4 "errors" 5 "fmt" 6 "github.com/flower-corp/rosedb" 7 "github.com/flower-corp/rosedb/util" 8 "github.com/tidwall/redcon" 9 "path/filepath" 10 "strconv" 11 "strings" 12 "time" 13 ) 14 15 const ( 16 resultOK = "OK" 17 resultPong = "PONG" 18 argsWithValues = "WITHVALUES" 19 ) 20 21 var ( 22 errSyntax = errors.New("ERR syntax error ") 23 errValueIsInvalid = errors.New("ERR value is not an integer or out of range") 24 errDBIndexOutOfRange = errors.New("ERR DB index is out of range") 25 ) 26 27 func newWrongNumOfArgsError(cmd string) error { 28 return fmt.Errorf("ERR wrong number of arguments for '%s' command", cmd) 29 } 30 31 // +-------+--------+----------+------------+-----------+-------+---------+ 32 // |---------------------- server management commands --------------------| 33 // +-------+--------+----------+------------+-----------+-------+---------+ 34 func info(cli *Client, args [][]byte) (interface{}, error) { 35 // todo 36 return "info", nil 37 } 38 39 // +-------+--------+----------+------------+-----------+-------+---------+ 40 // |-------------------- connection management commands ------------------| 41 // +-------+--------+----------+------------+-----------+-------+---------+ 42 func selectDB(cli *Client, args [][]byte) (interface{}, error) { 43 cli.svr.mu.Lock() 44 defer cli.svr.mu.Unlock() 45 46 if len(args) != 1 { 47 return nil, newWrongNumOfArgsError("select") 48 } 49 n, err := strconv.Atoi(string(args[0])) 50 if err != nil { 51 return nil, errValueIsInvalid 52 } 53 54 if n < 0 || uint(n) >= cli.svr.opts.databases { 55 return nil, errDBIndexOutOfRange 56 } 57 58 db := cli.svr.dbs[n] 59 if db == nil { 60 path := filepath.Join(cli.svr.opts.dbPath, fmt.Sprintf(dbName, n)) 61 opts := rosedb.DefaultOptions(path) 62 newdb, err := rosedb.Open(opts) 63 if err != nil { 64 return nil, err 65 } 66 db = newdb 67 cli.svr.dbs[n] = db 68 } 69 cli.db = db 70 return resultOK, nil 71 } 72 73 func ping(cli *Client, args [][]byte) (interface{}, error) { 74 if len(args) > 1 { 75 return nil, newWrongNumOfArgsError("ping") 76 } 77 var res = resultPong 78 if len(args) == 1 { 79 res = string(args[0]) 80 } 81 return res, nil 82 } 83 84 // +-------+--------+----------+------------+-----------+-------+---------+ 85 // |-------------------------- generic commands --------------------------| 86 // +-------+--------+----------+------------+-----------+-------+---------+ 87 func del(cli *Client, args [][]byte) (interface{}, error) { 88 if len(args) < 1 { 89 return nil, newWrongNumOfArgsError("del") 90 } 91 for _, key := range args { 92 if err := cli.db.Delete(key); err != nil { 93 return 0, err 94 } 95 // delete other ds. todo 96 } 97 return redcon.SimpleInt(1), nil 98 } 99 100 func keyType(cli *Client, args [][]byte) (interface{}, error) { 101 // todo 102 return "string", nil 103 } 104 105 // +-------+--------+----------+------------+-----------+-------+---------+ 106 // |-------------------------- String commands --------------------------| 107 // +-------+--------+----------+------------+-----------+-------+---------+ 108 func set(cli *Client, args [][]byte) (interface{}, error) { 109 if len(args) < 2 { 110 return nil, newWrongNumOfArgsError("set") 111 } 112 key, value := args[0], args[1] 113 114 var setErr error 115 if len(args) > 2 { 116 ex := strings.ToLower(string(args[2])) 117 if ex != "ex" || len(args) != 4 { 118 return nil, errSyntax 119 } 120 second, err := strconv.Atoi(string(args[3])) 121 if err != nil { 122 return nil, errSyntax 123 } 124 setErr = cli.db.SetEX(key, value, time.Second*time.Duration(second)) 125 } else { 126 setErr = cli.db.Set(key, value) 127 } 128 if setErr != nil { 129 return nil, setErr 130 } 131 return redcon.SimpleString(resultOK), nil 132 } 133 134 func setEX(cli *Client, args [][]byte) (interface{}, error) { 135 if len(args) != 3 { 136 return nil, newWrongNumOfArgsError("get") 137 } 138 key, seconds, value := args[0], args[1], args[2] 139 sec, err := strconv.Atoi(string(seconds)) 140 if err != nil { 141 return nil, errValueIsInvalid 142 } 143 err = cli.db.SetEX(key, value, time.Second*time.Duration(sec)) 144 if err != nil { 145 return nil, err 146 } 147 return redcon.SimpleString(resultOK), nil 148 } 149 150 func setNX(cli *Client, args [][]byte) (interface{}, error) { 151 if len(args) != 2 { 152 return nil, newWrongNumOfArgsError("setnx") 153 } 154 key, value := args[0], args[1] 155 err := cli.db.SetNX(key, value) 156 if err != nil { 157 return nil, err 158 } 159 return redcon.SimpleString(resultOK), nil 160 } 161 162 func mSet(cli *Client, args [][]byte) (interface{}, error) { 163 if len(args) == 0 || len(args)%2 != 0 { 164 return nil, newWrongNumOfArgsError("mset") 165 } 166 err := cli.db.MSet(args...) 167 if err != nil { 168 return nil, err 169 } 170 return redcon.SimpleString(resultOK), nil 171 } 172 173 func mSetNX(cli *Client, args [][]byte) (interface{}, error) { 174 if len(args) == 0 || len(args)%2 != 0 { 175 return nil, newWrongNumOfArgsError("msetnx") 176 } 177 err := cli.db.MSetNX(args...) 178 if err != nil { 179 return nil, err 180 } 181 return redcon.SimpleString(resultOK), nil 182 } 183 184 func decr(cli *Client, args [][]byte) (interface{}, error) { 185 if len(args) != 1 { 186 return nil, newWrongNumOfArgsError("decr") 187 } 188 key := args[0] 189 return cli.db.Decr(key) 190 } 191 192 func decrBy(cli *Client, args [][]byte) (interface{}, error) { 193 if len(args) != 2 { 194 return nil, newWrongNumOfArgsError("decrby") 195 } 196 key, decrVal := args[0], args[1] 197 decrInt64Val, err := util.StrToInt64(string(decrVal)) 198 if err != nil { 199 return nil, errValueIsInvalid 200 } 201 return cli.db.DecrBy(key, decrInt64Val) 202 } 203 204 func incr(cli *Client, args [][]byte) (interface{}, error) { 205 if len(args) != 1 { 206 return nil, newWrongNumOfArgsError("incr") 207 } 208 key := args[0] 209 return cli.db.Incr(key) 210 } 211 212 func incrBy(cli *Client, args [][]byte) (interface{}, error) { 213 if len(args) != 2 { 214 return nil, newWrongNumOfArgsError("incrby") 215 } 216 key, incrVal := args[0], args[1] 217 incrInt64Val, err := util.StrToInt64(string(incrVal)) 218 if err != nil { 219 return nil, errValueIsInvalid 220 } 221 return cli.db.IncrBy(key, incrInt64Val) 222 } 223 224 func strLen(cli *Client, args [][]byte) (interface{}, error) { 225 if len(args) != 1 { 226 return nil, newWrongNumOfArgsError("strlen") 227 } 228 return cli.db.StrLen(args[0]), nil 229 } 230 231 func get(cli *Client, args [][]byte) (interface{}, error) { 232 if len(args) != 1 { 233 return nil, newWrongNumOfArgsError("get") 234 } 235 value, err := cli.db.Get(args[0]) 236 if err != nil { 237 return nil, err 238 } 239 return value, nil 240 } 241 242 func mGet(cli *Client, args [][]byte) (interface{}, error) { 243 if len(args) < 1 { 244 return nil, newWrongNumOfArgsError("mget") 245 } 246 var keys [][]byte 247 for _, key := range args { 248 keys = append(keys, key) 249 } 250 values, err := cli.db.MGet(keys) 251 return values, err 252 } 253 254 func getRange(cli *Client, args [][]byte) (interface{}, error) { 255 if len(args) != 3 { 256 return nil, newWrongNumOfArgsError("getrange") 257 } 258 start, err := strconv.Atoi(string(args[1])) 259 if err != nil { 260 return nil, errValueIsInvalid 261 } 262 263 end, err := strconv.Atoi(string(args[2])) 264 if err != nil { 265 return nil, errValueIsInvalid 266 } 267 268 return cli.db.GetRange(args[0], start, end) 269 } 270 271 func appendStr(cli *Client, args [][]byte) (interface{}, error) { 272 if len(args) != 2 { 273 return nil, newWrongNumOfArgsError("append") 274 } 275 key, value := args[0], args[1] 276 err := cli.db.Append(key, value) 277 if err != nil { 278 return nil, err 279 } 280 return redcon.SimpleInt(cli.db.StrLen(key)), nil 281 } 282 283 func getDel(cli *Client, args [][]byte) (interface{}, error) { 284 if len(args) != 1 { 285 return nil, newWrongNumOfArgsError("getdel") 286 } 287 val, err := cli.db.GetDel(args[0]) 288 return val, err 289 } 290 291 // +-------+--------+----------+------------+-----------+-------+---------+ 292 // |---------------------------- List commands ---------------------------| 293 // +-------+--------+----------+------------+-----------+-------+---------+ 294 func lPush(cli *Client, args [][]byte) (interface{}, error) { 295 if len(args) < 2 { 296 return nil, newWrongNumOfArgsError("lpush") 297 } 298 key, value := args[0], args[1:] 299 err := cli.db.LPush(key, value...) 300 if err != nil { 301 return nil, err 302 } 303 return redcon.SimpleInt(cli.db.LLen(key)), nil 304 } 305 306 func lPushX(cli *Client, args [][]byte) (interface{}, error) { 307 if len(args) < 2 { 308 return nil, newWrongNumOfArgsError("lpush") 309 } 310 key, value := args[0], args[1:] 311 err := cli.db.LPushX(key, value...) 312 if err != nil { 313 return nil, err 314 } 315 return redcon.SimpleInt(cli.db.LLen(key)), nil 316 } 317 318 func rPush(cli *Client, args [][]byte) (interface{}, error) { 319 if len(args) < 2 { 320 return nil, newWrongNumOfArgsError("rpush") 321 } 322 key, value := args[0], args[1:] 323 err := cli.db.RPush(key, value...) 324 if err != nil { 325 return nil, err 326 } 327 return redcon.SimpleInt(cli.db.LLen(key)), nil 328 } 329 330 func rPushX(cli *Client, args [][]byte) (interface{}, error) { 331 if len(args) < 2 { 332 return nil, newWrongNumOfArgsError("rpush") 333 } 334 key, value := args[0], args[1:] 335 err := cli.db.RPushX(key, value...) 336 if err != nil { 337 return nil, err 338 } 339 return redcon.SimpleInt(cli.db.LLen(key)), nil 340 } 341 342 func lPop(cli *Client, args [][]byte) (interface{}, error) { 343 return popInternal(cli.db, args, true) 344 } 345 346 func rPop(cli *Client, args [][]byte) (interface{}, error) { 347 return popInternal(cli.db, args, false) 348 } 349 350 func lMove(cli *Client, args [][]byte) (interface{}, error) { 351 if len(args) != 4 { 352 return nil, newWrongNumOfArgsError("lmove") 353 } 354 355 srcKey, dstKey := args[0], args[1] 356 from, to := strings.ToLower(string(args[2])), strings.ToLower(string(args[3])) 357 var srcIsLeft, dstIsLeft bool 358 359 if from == "left" { 360 srcIsLeft = true 361 } else if from == "right" { 362 srcIsLeft = false 363 } else { 364 return nil, errSyntax 365 } 366 367 if to == "left" { 368 dstIsLeft = true 369 } else if to == "right" { 370 dstIsLeft = false 371 } else { 372 return nil, errSyntax 373 } 374 375 return cli.db.LMove(srcKey, dstKey, srcIsLeft, dstIsLeft) 376 } 377 378 func popInternal(db *rosedb.RoseDB, args [][]byte, isLeft bool) (interface{}, error) { 379 if len(args) < 1 { 380 return nil, newWrongNumOfArgsError("lpop") 381 } 382 key := args[0] 383 var count = 1 384 if len(args) == 2 { 385 c, err := strconv.Atoi(string(args[1])) 386 if err != nil { 387 return nil, errValueIsInvalid 388 } 389 count = c 390 } 391 total := db.LLen(key) 392 var values [][]byte 393 for i := 0; i < count && i < total; i++ { 394 var ( 395 val []byte 396 err error 397 ) 398 if isLeft { 399 val, err = db.LPop(key) 400 } else { 401 val, err = db.RPop(key) 402 } 403 if err != nil { 404 return nil, err 405 } 406 values = append(values, val) 407 } 408 return values, nil 409 } 410 411 func lLen(cli *Client, args [][]byte) (interface{}, error) { 412 if len(args) != 1 { 413 return nil, newWrongNumOfArgsError("llen") 414 } 415 key := args[0] 416 return redcon.SimpleInt(cli.db.LLen(key)), nil 417 } 418 419 func lIndex(cli *Client, args [][]byte) (interface{}, error) { 420 if len(args) != 2 { 421 return nil, newWrongNumOfArgsError("lindex") 422 } 423 key, index := args[0], args[1] 424 intIndex, err := strconv.Atoi(string(index)) 425 if err != nil { 426 return nil, errValueIsInvalid 427 } 428 return cli.db.LIndex(key, intIndex) 429 } 430 431 func lSet(cli *Client, args [][]byte) (interface{}, error) { 432 if len(args) != 3 { 433 return nil, newWrongNumOfArgsError("lset") 434 } 435 436 key, index, value := args[0], args[1], args[2] 437 i, err := strconv.Atoi(string(index)) 438 if err != nil { 439 return nil, errValueIsInvalid 440 } 441 err = cli.db.LSet(key, i, value) 442 if err != nil { 443 return nil, err 444 } 445 return redcon.SimpleString(resultOK), nil 446 } 447 448 func lRange(cli *Client, args [][]byte) (interface{}, error) { 449 if len(args) != 3 { 450 return nil, newWrongNumOfArgsError("lrange") 451 } 452 453 key, start, end := args[0], args[1], args[2] 454 s, err := strconv.Atoi(string(start)) 455 if err != nil { 456 return nil, errValueIsInvalid 457 } 458 459 e, err := strconv.Atoi(string(end)) 460 if err != nil { 461 return nil, errValueIsInvalid 462 } 463 464 return cli.db.LRange(key, s, e) 465 } 466 467 func lRem(cli *Client, args [][]byte) (interface{}, error) { 468 if len(args) != 3 { 469 return nil, newWrongNumOfArgsError("lrem") 470 } 471 key, element := args[0], args[2] 472 count, err := strconv.Atoi(string(args[1])) 473 if err != nil { 474 return nil, errValueIsInvalid 475 } 476 rem, err := cli.db.LRem(key, count, element) 477 return redcon.SimpleInt(rem), err 478 } 479 480 // +-------+--------+----------+------------+-----------+-------+---------+ 481 // |--------------------------- Hash commands ----------------------------| 482 // +-------+--------+----------+------------+-----------+-------+---------+ 483 func hSet(cli *Client, args [][]byte) (interface{}, error) { 484 if len(args) < 2 || len(args)%2 == 0 { 485 return nil, newWrongNumOfArgsError("hset") 486 } 487 key := args[0] 488 var count int 489 for i := 1; i < len(args); i += 2 { 490 err := cli.db.HSet(key, args[i], args[i+1]) 491 if err != nil { 492 return nil, err 493 } 494 count++ 495 } 496 return redcon.SimpleInt(count), nil 497 } 498 499 func hSetNX(cli *Client, args [][]byte) (interface{}, error) { 500 if len(args) != 3 { 501 return nil, newWrongNumOfArgsError("hsetnx") 502 } 503 504 key, field, value := args[0], args[1], args[2] 505 ok, err := cli.db.HSetNX(key, field, value) 506 if err != nil { 507 return nil, err 508 } 509 if ok { 510 return redcon.SimpleInt(1), nil 511 } 512 return redcon.SimpleInt(0), nil 513 } 514 515 func hGet(cli *Client, args [][]byte) (interface{}, error) { 516 if len(args) != 2 { 517 return nil, newWrongNumOfArgsError("hget") 518 } 519 val, err := cli.db.HGet(args[0], args[1]) 520 return val, err 521 } 522 523 func hmGet(cli *Client, args [][]byte) (interface{}, error) { 524 if len(args) < 2 { 525 return nil, newWrongNumOfArgsError("hmget") 526 } 527 return cli.db.HMGet(args[0], args[1:]...) 528 } 529 530 func hDel(cli *Client, args [][]byte) (interface{}, error) { 531 if len(args) < 2 { 532 return nil, newWrongNumOfArgsError("hdel") 533 } 534 count, err := cli.db.HDel(args[0], args[1:]...) 535 return redcon.SimpleInt(count), err 536 } 537 538 func hExists(cli *Client, args [][]byte) (interface{}, error) { 539 if len(args) != 2 { 540 return nil, newWrongNumOfArgsError("hexists") 541 } 542 ok, err := cli.db.HExists(args[0], args[1]) 543 if err != nil { 544 return nil, err 545 } 546 if ok { 547 return redcon.SimpleInt(1), nil 548 } 549 return redcon.SimpleInt(0), nil 550 } 551 552 func hLen(cli *Client, args [][]byte) (interface{}, error) { 553 if len(args) != 1 { 554 return nil, newWrongNumOfArgsError("hlen") 555 } 556 return redcon.SimpleInt(cli.db.HLen(args[0])), nil 557 } 558 559 func hKeys(cli *Client, args [][]byte) (interface{}, error) { 560 if len(args) != 1 { 561 return nil, newWrongNumOfArgsError("hkeys") 562 } 563 return cli.db.HKeys(args[0]) 564 } 565 566 func hVals(cli *Client, args [][]byte) (interface{}, error) { 567 if len(args) != 1 { 568 return nil, newWrongNumOfArgsError("hvals") 569 } 570 return cli.db.HVals(args[0]) 571 } 572 573 func hGetAll(cli *Client, args [][]byte) (interface{}, error) { 574 if len(args) != 1 { 575 return nil, newWrongNumOfArgsError("hgetall") 576 } 577 return cli.db.HGetAll(args[0]) 578 } 579 580 func hStrLen(cli *Client, args [][]byte) (interface{}, error) { 581 if len(args) != 2 { 582 return nil, newWrongNumOfArgsError("hstrlen") 583 } 584 return redcon.SimpleInt(cli.db.HStrLen(args[0], args[1])), nil 585 } 586 587 func hScan(cli *Client, args [][]byte) (interface{}, error) { 588 if len(args) != 4 { 589 return nil, newWrongNumOfArgsError("hscan") 590 } 591 pattern := string(args[2]) 592 count, err := strconv.Atoi(string(args[3])) 593 if err != nil { 594 return nil, err 595 } 596 return cli.db.HScan(args[0], args[1], pattern, count) 597 } 598 599 func hIncrBy(cli *Client, args [][]byte) (interface{}, error) { 600 if len(args) != 3 { 601 return nil, newWrongNumOfArgsError("hincrby") 602 } 603 key, field, incrVal := args[0], args[1], args[2] 604 incrInt64Val, err := util.StrToInt64(string(incrVal)) 605 if err != nil { 606 return nil, errValueIsInvalid 607 } 608 return cli.db.HIncrBy(key, field, incrInt64Val) 609 } 610 611 func hRandField(cli *Client, args [][]byte) (interface{}, error) { 612 if len(args) != 1 && len(args) != 2 && len(args) != 3 { 613 return nil, newWrongNumOfArgsError("hrandfield") 614 } 615 if len(args) == 1 { 616 keys, err := cli.db.HRandField(args[0], 1, false) 617 if err != nil { 618 return nil, err 619 } 620 if len(keys) == 1 { 621 return keys[0], nil 622 } 623 return keys, nil 624 } 625 count, err := strconv.Atoi(string(args[1])) 626 if err != nil { 627 return nil, errValueIsInvalid 628 } 629 withValues := false 630 if len(args) == 3 { 631 if !strings.EqualFold(string(args[2]), argsWithValues) { 632 return nil, errSyntax 633 } 634 withValues = true 635 } 636 return cli.db.HRandField(args[0], count, withValues) 637 } 638 639 // +-------+--------+----------+------------+-----------+-------+---------+ 640 // |---------------------------- Set commands ----------------------------| 641 // +-------+--------+----------+------------+-----------+-------+---------+ 642 func sAdd(cli *Client, args [][]byte) (interface{}, error) { 643 if len(args) < 2 { 644 return nil, newWrongNumOfArgsError("sadd") 645 } 646 key := args[0] 647 var count int 648 for _, val := range args[1:] { 649 isMember := cli.db.SIsMember(key, val) 650 if !isMember { 651 err := cli.db.SAdd(key, val) 652 if err != nil { 653 return nil, err 654 } 655 count++ 656 } 657 } 658 return redcon.SimpleInt(count), nil 659 } 660 661 func sRem(cli *Client, args [][]byte) (interface{}, error) { 662 if len(args) < 2 { 663 return nil, newWrongNumOfArgsError("srem") 664 } 665 key := args[0] 666 var count int 667 for _, val := range args[1:] { 668 isMember := cli.db.SIsMember(key, val) 669 if isMember { 670 err := cli.db.SRem(key, val) 671 if err != nil { 672 return nil, err 673 } 674 count++ 675 } 676 } 677 return redcon.SimpleInt(count), nil 678 } 679 680 func sPop(cli *Client, args [][]byte) (interface{}, error) { 681 if len(args) != 2 { 682 return nil, newWrongNumOfArgsError("spop") 683 } 684 count, err := util.StrToUint(string(args[1])) 685 if err != nil { 686 return nil, errValueIsInvalid 687 } 688 return cli.db.SPop(args[0], uint(count)) 689 } 690 691 func sIsMember(cli *Client, args [][]byte) (interface{}, error) { 692 if len(args) != 2 { 693 return nil, newWrongNumOfArgsError("sismember") 694 } 695 key, mem := args[0], args[1] 696 if ok := cli.db.SIsMember(key, mem); ok { 697 return redcon.SimpleInt(1), nil 698 } else { 699 return redcon.SimpleInt(0), nil 700 } 701 } 702 703 func sMisMember(cli *Client, args [][]byte) (interface{}, error) { 704 if len(args) < 2 { 705 return nil, newWrongNumOfArgsError("smismember") 706 } 707 res := make([]redcon.SimpleInt, 0) 708 key := args[0] 709 for _, mem := range args[1:] { 710 if ok := cli.db.SIsMember(key, mem); ok { 711 res = append(res, redcon.SimpleInt(1)) 712 } else { 713 res = append(res, redcon.SimpleInt(0)) 714 } 715 } 716 return res, nil 717 } 718 719 func sMembers(cli *Client, args [][]byte) (interface{}, error) { 720 if len(args) != 1 { 721 return nil, newWrongNumOfArgsError("smembers") 722 } 723 return cli.db.SMembers(args[0]) 724 } 725 726 func sCard(cli *Client, args [][]byte) (interface{}, error) { 727 if len(args) != 1 { 728 return nil, newWrongNumOfArgsError("scard") 729 } 730 return redcon.SimpleInt(cli.db.SCard(args[0])), nil 731 } 732 733 func sDiff(cli *Client, args [][]byte) (interface{}, error) { 734 if len(args) == 0 { 735 return nil, newWrongNumOfArgsError("sdiff") 736 } 737 return cli.db.SDiff(args...) 738 } 739 740 func sDiffStore(cli *Client, args [][]byte) (interface{}, error) { 741 if len(args) < 2 { 742 return nil, newWrongNumOfArgsError("sdiffstore") 743 } 744 return cli.db.SDiffStore(args...) 745 } 746 747 func sUnion(cli *Client, args [][]byte) (interface{}, error) { 748 if len(args) == 0 { 749 return nil, newWrongNumOfArgsError("sunion") 750 } 751 return cli.db.SUnion(args...) 752 } 753 func sUnionStore(cli *Client, args [][]byte) (interface{}, error) { 754 if len(args) < 2 { 755 return nil, newWrongNumOfArgsError("sunionstore") 756 } 757 return cli.db.SUnionStore(args...) 758 } 759 func sInter(cli *Client, args [][]byte) (interface{}, error) { 760 if len(args) == 0 { 761 return nil, newWrongNumOfArgsError("sinter") 762 } 763 return cli.db.SInter(args...) 764 } 765 func sInterStore(cli *Client, args [][]byte) (interface{}, error) { 766 if len(args) < 2 { 767 return nil, newWrongNumOfArgsError("sinterstore") 768 } 769 return cli.db.SInterStore(args...) 770 } 771 772 // +-------+--------+----------+------------+-----------+-------+---------+ 773 // |------------------------- Sorted Set commands ------------------------| 774 // +-------+--------+----------+------------+-----------+-------+---------+ 775 776 func zAdd(cli *Client, args [][]byte) (interface{}, error) { 777 if (len(args)-1)%2 != 0 { 778 return nil, newWrongNumOfArgsError("zadd") 779 } 780 key := args[0] 781 for i := 1; i < len(args); i += 2 { 782 score, err := util.StrToFloat64(string(args[i])) 783 if err != nil { 784 return nil, errValueIsInvalid 785 } 786 err = cli.db.ZAdd(key, score, args[i+1]) 787 if err != nil { 788 return nil, err 789 } 790 } 791 return redcon.SimpleInt(len(args[1:]) / 2), nil 792 } 793 794 func zScore(cli *Client, args [][]byte) (interface{}, error) { 795 if len(args) != 2 { 796 return nil, newWrongNumOfArgsError("zscore") 797 } 798 _, score := cli.db.ZScore(args[0], args[1]) 799 return score, nil 800 } 801 802 func zRem(cli *Client, args [][]byte) (interface{}, error) { 803 if len(args) < 2 { 804 return nil, newWrongNumOfArgsError("zrem") 805 } 806 key := args[0] 807 for _, member := range args[1:] { 808 err := cli.db.ZRem(key, member) 809 if err != nil { 810 return nil, err 811 } 812 } 813 return redcon.SimpleInt(len(args[1:]) / 2), nil 814 } 815 816 func zCard(cli *Client, args [][]byte) (interface{}, error) { 817 if len(args) != 1 { 818 return nil, newWrongNumOfArgsError("zcard") 819 } 820 return redcon.SimpleInt(cli.db.ZCard(args[0])), nil 821 } 822 823 func zRange(cli *Client, args [][]byte) (interface{}, error) { 824 if len(args) != 3 { 825 return nil, newWrongNumOfArgsError("zrange") 826 } 827 start, err := strconv.Atoi(string(args[1])) 828 if err != nil { 829 return nil, err 830 } 831 stop, err := strconv.Atoi(string(args[2])) 832 if err != nil { 833 return nil, err 834 } 835 return cli.db.ZRange(args[0], start, stop) 836 } 837 838 func zRevRange(cli *Client, args [][]byte) (interface{}, error) { 839 if len(args) != 3 { 840 return nil, newWrongNumOfArgsError("zrevrange") 841 } 842 start, err := strconv.Atoi(string(args[1])) 843 if err != nil { 844 return nil, err 845 } 846 stop, err := strconv.Atoi(string(args[2])) 847 if err != nil { 848 return nil, err 849 } 850 return cli.db.ZRevRange(args[0], start, stop) 851 } 852 853 func zRank(cli *Client, args [][]byte) (interface{}, error) { 854 if len(args) != 2 { 855 return nil, newWrongNumOfArgsError("zrank") 856 } 857 ok, rank := cli.db.ZRank(args[0], args[1]) 858 if !ok { 859 return nil, nil 860 } 861 return rank, nil 862 } 863 864 func zRevRank(cli *Client, args [][]byte) (interface{}, error) { 865 if len(args) != 2 { 866 return nil, newWrongNumOfArgsError("zrevrank") 867 } 868 ok, rank := cli.db.ZRevRank(args[0], args[1]) 869 if !ok { 870 return nil, nil 871 } 872 return rank, nil 873 }