fix(aof): do not override context database when conn is nil (AOF replay fix)
This commit is contained in:
commit
7c11581e11
80
CODE_OF_CONDUCT.md
Normal file
80
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,80 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to make participation in our project
|
||||
and our community a harassment-free experience for everyone, regardless
|
||||
of age, body size, disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic
|
||||
status, nationality, personal appearance, race, religion, or sexual
|
||||
identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
- Using welcoming and inclusive language
|
||||
- Being respectful of differing viewpoints and experiences
|
||||
- Gracefully accepting constructive criticism
|
||||
- Focusing on what is best for the community
|
||||
- Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
- The use of sexualized language or imagery and unwelcome sexual
|
||||
attention or advances
|
||||
- Trolling, insulting/derogatory comments, and personal or political
|
||||
attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or
|
||||
electronic address, without explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in
|
||||
a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of
|
||||
acceptable behavior and are expected to take appropriate and fair
|
||||
corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit,
|
||||
or reject comments, commits, code, wiki edits, issues, and other
|
||||
contributions that are not aligned to this Code of Conduct, or to ban
|
||||
temporarily or permanently any contributor for other behaviors that they
|
||||
deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also
|
||||
applies when an individual is representing the project or its community
|
||||
in public spaces. Examples of representing a project or community
|
||||
include using an official project e-mail address, posting via an
|
||||
official social media account, or acting as an appointed representative
|
||||
at an online or offline event. Representation of a project may be
|
||||
further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may
|
||||
be reported by contacting the project team at <kelvin@echovault.io>.
|
||||
All complaints will be reviewed and investigated and will result in a
|
||||
response that is deemed necessary and appropriate to the circumstances.
|
||||
The project team is obligated to maintain confidentiality with regard to
|
||||
the reporter of an incident. Further details of specific enforcement
|
||||
policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in
|
||||
good faith may face temporary or permanent repercussions as determined
|
||||
by other members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor
|
||||
Covenant](https://www.contributor-covenant.org), version 1.4, available
|
||||
at
|
||||
<https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
<https://www.contributor-covenant.org/faq>
|
||||
65
CONTRIBUTING.md
Normal file
65
CONTRIBUTING.md
Normal file
@ -0,0 +1,65 @@
|
||||
# Contributing
|
||||
|
||||
## Issues
|
||||
|
||||
Issues are very valuable to this project.
|
||||
|
||||
- Ideas are a valuable source of contributions others can make
|
||||
- Problems show where this project is lacking
|
||||
- With a question you show where contributors can improve the user
|
||||
experience
|
||||
|
||||
Thank you for creating them.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Pull requests are a great way to get your ideas into this repository.
|
||||
|
||||
Before opening a pull request, reach out to one of the organization
|
||||
members or state your intent in the [discord server](https://discord.com/invite/JrG4kPrF8v). This prevents you
|
||||
from potentially doing redundant or low-priority work.
|
||||
|
||||
When deciding if I merge in a pull request I look at the following
|
||||
things:
|
||||
|
||||
### Does it state intent
|
||||
|
||||
You should be clear which problem you're trying to solve with your
|
||||
contribution.
|
||||
|
||||
For example:
|
||||
|
||||
> Add link to code of conduct in README.md
|
||||
|
||||
Doesn't tell me anything about why you're doing that
|
||||
|
||||
> Add link to code of conduct in README.md because users don't always
|
||||
> look in the CONTRIBUTING.md
|
||||
|
||||
Tells me the problem that you have found, and the pull request shows me
|
||||
the action you have taken to solve it.
|
||||
|
||||
### Is it of good quality
|
||||
|
||||
- There are no spelling mistakes
|
||||
- It reads well
|
||||
- For english language contributions: Has a good score on
|
||||
[Grammarly](https://www.grammarly.com) or [Hemingway
|
||||
App](https://www.hemingwayapp.com/)
|
||||
|
||||
### Does it move this repository closer to my vision for the repository
|
||||
|
||||
The aim of this repository is:
|
||||
|
||||
- To provide a distributed (primarily) in-memory data cache that is
|
||||
embeddable in Go and compatible with RESP.
|
||||
- Foster a culture of respect and gratitude in the open source
|
||||
community.
|
||||
|
||||
### Does it follow the contributor covenant
|
||||
|
||||
This repository has a [code of conduct](CODE_OF_CONDUCT.md), I will
|
||||
remove things that do not respect it.
|
||||
|
||||
If all the above conditions are met, feel free to fork the project
|
||||
and open a pull request.
|
||||
62
Dockerfile.dev
Normal file
62
Dockerfile.dev
Normal file
@ -0,0 +1,62 @@
|
||||
FROM --platform=linux/amd64 golang:alpine AS build
|
||||
|
||||
RUN apk add --no-cache gcc musl-dev
|
||||
|
||||
WORKDIR /build
|
||||
COPY . ./
|
||||
|
||||
ENV CGO_ENABLED=1 CC=gcc GOOS=linux GOARCH=amd64
|
||||
|
||||
ENV DEST=volumes/modules
|
||||
RUN CGO_ENABLED=$CGO_ENABLED CC=$CC GOOS=$GOOS GOARCH=$GOARCH go build -buildmode=plugin -o $DEST/module_set/module_set.so ./internal/volumes/modules/go/module_set/module_set.go
|
||||
RUN CGO_ENABLED=$CGO_ENABLED CC=$CC GOOS=$GOOS GOARCH=$GOARCH go build -buildmode=plugin -o $DEST/module_get/module_get.so ./internal/volumes/modules/go/module_get/module_get.go
|
||||
|
||||
ENV DEST=bin
|
||||
RUN CGO_ENABLED=$CGO_ENABLED CC=$CC GOOS=$GOOS GOARCH=$GOARCH go build -o $DEST/server ./cmd/...
|
||||
|
||||
|
||||
|
||||
FROM --platform=linux/amd64 alpine:latest AS server
|
||||
|
||||
RUN mkdir -p /usr/sugardb/bin/modules
|
||||
RUN mkdir -p /etc/ssl/certs/sugardb/server
|
||||
RUN mkdir -p /etc/ssl/certs/sugardb/client
|
||||
|
||||
COPY --from=build /build/volumes/modules /usr/sugardb/bin/modules
|
||||
COPY --from=build /build/bin/server /usr/sugardb/bin
|
||||
COPY ./openssl/server /etc/ssl/certs/sugardb/server
|
||||
COPY ./openssl/client /etc/ssl/certs/sugardb/client
|
||||
|
||||
WORKDIR /usr/sugardb/bin
|
||||
|
||||
CMD "./server" \
|
||||
"--bind-addr" "${BIND_ADDR}" \
|
||||
"--port" "${PORT}" \
|
||||
"--discovery-port" "${DISCOVERY_PORT}" \
|
||||
"--server-id" "${SERVER_ID}" \
|
||||
"--join-addr" "${JOIN_ADDR}" \
|
||||
"--data-dir" "${DATA_DIR}" \
|
||||
"--snapshot-threshold" "${SNAPSHOT_THRESHOLD}" \
|
||||
"--snapshot-interval" "${SNAPSHOT_INTERVAL}" \
|
||||
"--max-memory" "${MAX_MEMORY}" \
|
||||
"--eviction-policy" "${EVICTION_POLICY}" \
|
||||
"--eviction-sample" "${EVICTION_SAMPLE}" \
|
||||
"--eviction-interval" "${EVICTION_INTERVAL}" \
|
||||
"--tls=${TLS}" \
|
||||
"--mtls=${MTLS}" \
|
||||
"--bootstrap-cluster=${BOOTSTRAP_CLUSTER}" \
|
||||
"--acl-config=${ACL_CONFIG}" \
|
||||
"--require-pass=${REQUIRE_PASS}" \
|
||||
"--password=${PASSWORD}" \
|
||||
"--forward-commands=${FORWARD_COMMAND}" \
|
||||
"--restore-snapshot=${RESTORE_SNAPSHOT}" \
|
||||
"--restore-aof=${RESTORE_AOF}" \
|
||||
"--aof-sync-strategy=${AOF_SYNC_STRATEGY}" \
|
||||
# List of sugardb cert/key pairs
|
||||
"--cert-key-pair=${CERT_KEY_PAIR_1}" \
|
||||
"--cert-key-pair=${CERT_KEY_PAIR_2}" \
|
||||
# List of client certs
|
||||
"--client-ca=${CLIENT_CA_1}" \
|
||||
# List of plugins to load on startup
|
||||
"--loadmodule=${MODULE_1}" \
|
||||
"--loadmodule=${MODULE_2}" \
|
||||
11
Dockerfile.prod
Normal file
11
Dockerfile.prod
Normal file
@ -0,0 +1,11 @@
|
||||
FROM --platform=linux/amd64 golang:alpine AS build
|
||||
RUN apk add --no-cache gcc musl-dev
|
||||
WORKDIR /build
|
||||
COPY . ./
|
||||
RUN CGO_ENABLED=1 CC=gcc GOOS=linux GOARCH=amd64 go build -o bin/server ./cmd/...
|
||||
|
||||
FROM --platform=linux/amd64 alpine:latest AS server
|
||||
RUN mkdir -p /usr/sugardb/bin
|
||||
COPY --from=build /build/bin/server /usr/sugardb/bin
|
||||
WORKDIR /usr/sugardb/bin
|
||||
ENTRYPOINT ["./server"]
|
||||
51
LICENSE.md
Normal file
51
LICENSE.md
Normal file
@ -0,0 +1,51 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
41
Makefile
Normal file
41
Makefile
Normal file
@ -0,0 +1,41 @@
|
||||
run:
|
||||
docker-compose up --build
|
||||
|
||||
build-local:
|
||||
CGO_ENABLED=1 go build -buildmode=plugin -o ./bin/modules/module_set/module_set.so ./internal/volumes/modules/go/module_set/module_set.go && \
|
||||
CGO_ENABLED=1 go build -buildmode=plugin -o ./bin/modules/module_get/module_get.so ./internal/volumes/modules/go/module_get/module_get.go && \
|
||||
CGO_ENABLED=1 go build -o ./bin ./...
|
||||
|
||||
|
||||
build-modules-test:
|
||||
CGO_ENABLED=1 go build --race=$(RACE) -buildmode=plugin -o $(OUT)/modules/module_set/module_set.so ./internal/volumes/modules/go/module_set/module_set.go && \
|
||||
CGO_ENABLED=1 go build --race=$(RACE) -buildmode=plugin -o $(OUT)/modules/module_get/module_get.so ./internal/volumes/modules/go/module_get/module_get.go
|
||||
|
||||
test:
|
||||
env RACE=false OUT=internal/modules/admin/testdata make build-modules-test && \
|
||||
env RACE=false OUT=sugardb/testdata make build-modules-test && \
|
||||
CGO_ENABLED=1 go test ./... -coverprofile coverage/coverage.out
|
||||
|
||||
test-race:
|
||||
env RACE=true OUT=internal/modules/admin/testdata make build-modules-test && \
|
||||
env RACE=true OUT=sugardb/testdata make build-modules-test && \
|
||||
CGO_ENABLED=1 go test ./... --race
|
||||
|
||||
testenv-run:
|
||||
docker-compose -f test_env/run/docker-compose.yaml build
|
||||
docker-compose -f test_env/run/docker-compose.yaml run projenv
|
||||
|
||||
testenv-test:
|
||||
docker-compose -f test_env/test/docker-compose.yaml up --build
|
||||
|
||||
testenv-test-race:
|
||||
docker-compose -f test_env/test_race/docker-compose.yaml up --build
|
||||
|
||||
testenv-all:
|
||||
docker-compose -f test_env/all/docker-compose.yaml up --build
|
||||
|
||||
cover:
|
||||
go tool cover -html=./coverage/coverage.out
|
||||
|
||||
benchmark:
|
||||
go run redis_benchmark.go $(if $(commands),-commands="$(commands)") $(if $(use_local_server),-use_local_server)
|
||||
341
README.md
Normal file
341
README.md
Normal file
@ -0,0 +1,341 @@
|
||||
[]()
|
||||
[](https://goreportcard.com/report/github.com/echovault/echovault)
|
||||
[](https://codecov.io/gh/EchoVault/SugarDB)
|
||||
<br/>
|
||||
[](https://pkg.go.dev/github.com/echovault/sugardb)
|
||||
[]()
|
||||
[](https://www.apache.org/licenses/LICENSE-2.0)
|
||||
<br/>
|
||||
[](https://github.com/avelino/awesome-go)
|
||||
[](https://discord.com/invite/JrG4kPrF8v)
|
||||
<br/>
|
||||
|
||||
<hr/>
|
||||
|
||||
# Table of Contents
|
||||
1. [What is SugarDB](#what-is-sugardb)
|
||||
2. [Features](#features)
|
||||
3. [Usage (Embedded)](#usage-embedded)
|
||||
4. [Usage (Client-Server)](#usage-client-server)
|
||||
1. [Homebrew](#usage-homebrew)
|
||||
2. [Docker](#usage-docker)
|
||||
3. [GitHub Container Registry](#usage-container-registry)
|
||||
4. [Binaries](#usage-binaries)
|
||||
5. [Clients](#clients)
|
||||
6. [Benchmarks](#benchmarks)
|
||||
7. [Commands](#commands)
|
||||
1. [ACL](#commands-acl)
|
||||
2. [ADMIN](#commands-admin)
|
||||
3. [CONNECTION](#commands-connection)
|
||||
4. [GENERIC](#commands-generic)
|
||||
5. [HASH](#commands-hash)
|
||||
6. [LIST](#commands-list)
|
||||
7. [PUBSUB](#commands-pubsub)
|
||||
8. [SET](#commands-set)
|
||||
9. [SORTED SET](#commands-sortedset)
|
||||
10. [STRING](#commands-string)
|
||||
|
||||
<a name="what-is-sugardb"></a>
|
||||
# What is SugarDB?
|
||||
|
||||
SugarDB is a highly configurable, distributed, in-memory data store and cache implemented in Go.
|
||||
It can be imported as a Go library or run as an independent service.
|
||||
|
||||
SugarDB aims to provide a rich set of data structures and functions for
|
||||
manipulating data in memory. These data structures include, but are not limited to:
|
||||
Lists, Sets, Sorted Sets, Hashes, and much more to come soon.
|
||||
|
||||
SugarDB provides a persistence layer for increased reliability. Both Append-Only files
|
||||
and snapshots can be used to persist data in the disk for recovery in case of unexpected shutdowns.
|
||||
|
||||
Replication is a core feature of SugarDB and is implemented using the RAFT algorithm,
|
||||
allowing you to create a fault-tolerant cluster of SugarDB nodes to improve reliability.
|
||||
If you do not need a replication cluster, you can always run SugarDB
|
||||
in standalone mode and have a fully capable single node.
|
||||
|
||||
SugarDB aims to not only be a server but to be importable to existing
|
||||
projects to enhance them with SugarDB features, this
|
||||
capability is always being worked on and improved.
|
||||
|
||||
<a name="features"></a>
|
||||
# Features
|
||||
|
||||
Features offered by SugarDB include:
|
||||
|
||||
1) TLS and mTLS support for multiple server and client RootCAs.
|
||||
2) Replication cluster support using the RAFT algorithm.
|
||||
3) ACL Layer for user Authentication and Authorization.
|
||||
4) Distributed Pub/Sub functionality.
|
||||
5) Sets, Sorted Sets, Hashes, Lists and more.
|
||||
6) Persistence layer with Snapshots and Append-Only files.
|
||||
7) Key Eviction Policies.
|
||||
8) Command extension via shared object files.
|
||||
9) Command extension via embedded API.
|
||||
10) Command extension via Lua Modules.
|
||||
11) Command extension via JavaScript Modules.
|
||||
12) Multi-database support for key namespacing.
|
||||
|
||||
We are working hard to add more features to SugarDB to make it
|
||||
much more powerful. Features in the roadmap include:
|
||||
|
||||
1) Sharding
|
||||
2) Streams
|
||||
3) Transactions
|
||||
4) Bitmap
|
||||
5) HyperLogLog
|
||||
6) JSON
|
||||
7) Improved Observability
|
||||
|
||||
|
||||
<a name="usage-embedded"></a>
|
||||
# Usage (Embedded)
|
||||
|
||||
Install SugarDB with: `go get github.com/echovault/sugardb`.
|
||||
|
||||
Here's an example of using SugarDB as an embedded library.
|
||||
You can access all of SugarDB's commands using an ergonomic API.
|
||||
|
||||
```go
|
||||
func main() {
|
||||
server, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
_, _, _ = server.Set("key", "Hello, SugarDB!", sugardb.SETOptions{})
|
||||
|
||||
v, _ := server.Get("key")
|
||||
fmt.Println(v) // Hello, SugarDB!
|
||||
|
||||
// (Optional): Listen for TCP connections on this SugarDB instance.
|
||||
server.Start()
|
||||
}
|
||||
```
|
||||
|
||||
An embedded SugarDB instance can still be part of a cluster, and the changes triggered
|
||||
from the API will be consistent across the cluster.
|
||||
|
||||
<a name="usage-client-server"></a>
|
||||
# Usage (Client-Server)
|
||||
|
||||
<a name="usage-homebrew"></a>
|
||||
### Homebrew
|
||||
|
||||
To install via homebrew, run:
|
||||
1) `brew tap echovault/sugardb`
|
||||
2) `brew install echovault/echovault/sugardb`
|
||||
|
||||
Once installed, you can run the server with the following command:
|
||||
`sugardb --bind-addr=localhost --data-dir="path/to/persistence/directory"`
|
||||
|
||||
<a name="usage-docker"></a>
|
||||
### Docker
|
||||
|
||||
`docker pull echovault/sugardb`
|
||||
|
||||
The full list of tags can be found [here](https://hub.docker.com/r/echovault/sugardb/tags).
|
||||
|
||||
<a name="usage-container-registry"></a>
|
||||
### Container Registry
|
||||
|
||||
`docker pull ghcr.io/echovault/sugardb`
|
||||
|
||||
The full list of tags can be found [here](https://github.com/EchoVault/SugarDB/pkgs/container/sugardb).
|
||||
|
||||
<a name="usage-binaries"></a>
|
||||
### Binaries
|
||||
|
||||
You can download the binaries by clicking on a release tag and downloading
|
||||
the binary for your system.
|
||||
|
||||
<a name="clients"></a>
|
||||
# Clients
|
||||
|
||||
SugarDB uses RESP, which makes it compatible with existing
|
||||
Redis clients.
|
||||
|
||||
<a name="benchmarks"></a>
|
||||
# Benchmarks
|
||||
To compare command performance with Redis, benchmarks can be run with:
|
||||
|
||||
`make benchmark`
|
||||
|
||||
Prerequisites:
|
||||
- `brew install redis` to run the Redis server and benchmark script
|
||||
- `brew tap echovault/sugardb` & `brew install echovault/echovault/sugardb` to run the SugarDB Client-Server
|
||||
|
||||
Benchmark script options:
|
||||
- `make benchmark use_local_server=true` runs on your local SugarDB Client-Server
|
||||
- `make benchmark commands=ping,set,get...` runs the benchmark script on the specified commands
|
||||
|
||||
<a name="commands"></a>
|
||||
# Supported Commands
|
||||
|
||||
<a name="commands-acl"></a>
|
||||
## ACL
|
||||
* [ACL CAT](https://sugardb.io/docs/commands/acl/acl_cat)
|
||||
* [ACL DELUSER](https://sugardb.io/docs/commands/acl/acl_deluser)
|
||||
* [ACL GETUSER](https://sugardb.io/docs/commands/acl/acl_getuser)
|
||||
* [ACL LIST](https://sugardb.io/docs/commands/acl/acl_list)
|
||||
* [ACL LOAD](https://sugardb.io/docs/commands/acl/acl_load)
|
||||
* [ACL SAVE](https://sugardb.io/docs/commands/acl/acl_save)
|
||||
* [ACL SETUSER](https://sugardb.io/docs/commands/acl/acl_setuser)
|
||||
* [ACL USERS](https://sugardb.io/docs/commands/acl/acl_users)
|
||||
* [ACL WHOAMI](https://sugardb.io/docs/commands/acl/acl_whoami)
|
||||
|
||||
<a name="commands-admin"></a>
|
||||
## ADMIN
|
||||
* [COMMAND COUNT](https://sugardb.io/docs/commands/admin/command_count)
|
||||
* [COMMAND LIST](https://sugardb.io/docs/commands/admin/command_list)
|
||||
* [COMMANDS](https://sugardb.io/docs/commands/admin/commands)
|
||||
* [LASTSAVE](https://sugardb.io/docs/commands/admin/lastsave)
|
||||
* [MODULE LIST](https://sugardb.io/docs/commands/admin/module_list)
|
||||
* [MODULE LOAD](https://sugardb.io/docs/commands/admin/module_load)
|
||||
* [MODULE UNLOAD](https://sugardb.io/docs/commands/admin/module_unload)
|
||||
* [REWRITEAOF](https://sugardb.io/docs/commands/admin/rewriteaof)
|
||||
* [SAVE](https://sugardb.io/docs/commands/admin/save)
|
||||
|
||||
<a name="commands-connection"></a>
|
||||
## CONNECTION
|
||||
* [AUTH](https://sugardb.io/docs/commands/connection/auth)
|
||||
* [ECHO](https://sugardb.io/docs/commands/connection/echo)
|
||||
* [HELLO](https://sugardb.io/docs/commands/connection/hello)
|
||||
* [PING](https://sugardb.io/docs/commands/connection/ping)
|
||||
* [SELECT](https://sugardb.io/docs/commands/connection/select)
|
||||
* [SWAPDB](https://sugardb.io/docs/commands/connection/swapdb)
|
||||
|
||||
<a name="commands-generic"></a>
|
||||
## GENERIC
|
||||
* [COPY](https://sugardb.io/docs/commands/generic/copy)
|
||||
* [DBSIZE](https://sugardb.io/docs/commands/generic/dbsize)
|
||||
* [DECR](https://sugardb.io/docs/commands/generic/decr)
|
||||
* [DECRBY](https://sugardb.io/docs/commands/generic/decrby)
|
||||
* [DEL](https://sugardb.io/docs/commands/generic/del)
|
||||
* [EXISTS](https://sugardb.io/docs/commands/generic/exists)
|
||||
* [EXPIRE](https://sugardb.io/docs/commands/generic/expire)
|
||||
* [EXPIRETIME](https://sugardb.io/docs/commands/generic/expiretime)
|
||||
* [FLUSHALL](https://sugardb.io/docs/commands/generic/flushall)
|
||||
* [FLUSHDB](https://sugardb.io/docs/commands/generic/flushdb)
|
||||
* [GET](https://sugardb.io/docs/commands/generic/get)
|
||||
* [GETDEL](https://sugardb.io/docs/commands/generic/getdel)
|
||||
* [GETEX](https://sugardb.io/docs/commands/generic/get)
|
||||
* [INCR](https://sugardb.io/docs/commands/generic/incr)
|
||||
* [INCRBY](https://sugardb.io/docs/commands/generic/incrby)
|
||||
* [INCRBYFLOAT](https://sugardb.io/docs/commands/generic/incrbyfloat)
|
||||
* [MGET](https://sugardb.io/docs/commands/generic/mget)
|
||||
* [MOVE](https://sugardb.io/docs/commands/generic/move)
|
||||
* [MSET](https://sugardb.io/docs/commands/generic/mset)
|
||||
* [OBJECTFREQ](https://sugardb.io/docs/commands/generic/objectfreq)
|
||||
* [OBJECTIDLETIME](https://sugardb.io/docs/commands/generic/objectidletime)
|
||||
* [PERSIST](https://sugardb.io/docs/commands/generic/persist)
|
||||
* [PEXPIRE](https://sugardb.io/docs/commands/generic/pexpire)
|
||||
* [PEXPIREAT](https://sugardb.io/docs/commands/generic/pexpireat)
|
||||
* [PEXPIRETIME](https://sugardb.io/docs/commands/generic/pexpiretime)
|
||||
* [PTTL](https://sugardb.io/docs/commands/generic/pttl)
|
||||
* [RANDOMKEY](https://sugardb.io/docs/commands/generic/randomkey)
|
||||
* [RENAME](https://sugardb.io/docs/commands/generic/rename)
|
||||
* [SET](https://sugardb.io/docs/commands/generic/set)
|
||||
* [TTL](https://sugardb.io/docs/commands/generic/ttl)
|
||||
* [TYPE](https://sugardb.io/docs/commands/generic/type)
|
||||
|
||||
|
||||
<a name="commands-hash"></a>
|
||||
## HASH
|
||||
* [HDEL](https://sugardb.io/docs/commands/hash/hdel)
|
||||
* [HEXISTS](https://sugardb.io/docs/commands/hash/hexists)
|
||||
* [HEXPIRE](https://sugardb.io/docs/commands/hash/hexpire)
|
||||
* [HGET](https://sugardb.io/docs/commands/hash/hget)
|
||||
* [HGETALL](https://sugardb.io/docs/commands/hash/hgetall)
|
||||
* [HINCRBY](https://sugardb.io/docs/commands/hash/hincrby)
|
||||
* [HINCRBYFLOAT](https://sugardb.io/docs/commands/hash/hincrbyfloat)
|
||||
* [HKEYS](https://sugardb.io/docs/commands/hash/hkeys)
|
||||
* [HLEN](https://sugardb.io/docs/commands/hash/hlen)
|
||||
* [HMGET](https://sugardb.io/docs/commands/hash/hmget)
|
||||
* [HRANDFIELD](https://sugardb.io/docs/commands/hash/hrandfield)
|
||||
* [HSET](https://sugardb.io/docs/commands/hash/hset)
|
||||
* [HSETNX](https://sugardb.io/docs/commands/hash/hsetnx)
|
||||
* [HSTRLEN](https://sugardb.io/docs/commands/hash/hstrlen)
|
||||
* [HTTL](https://sugardb.io/docs/commands/hash/httl)
|
||||
* [HVALS](https://sugardb.io/docs/commands/hash/hvals)
|
||||
|
||||
<a name="commands-list"></a>
|
||||
## LIST
|
||||
* [LINDEX](https://sugardb.io/docs/commands/list/lindex)
|
||||
* [LLEN](https://sugardb.io/docs/commands/list/llen)
|
||||
* [LMOVE](https://sugardb.io/docs/commands/list/lmove)
|
||||
* [LPOP](https://sugardb.io/docs/commands/list/lpop)
|
||||
* [LPUSH](https://sugardb.io/docs/commands/list/lpush)
|
||||
* [LPUSHX](https://sugardb.io/docs/commands/list/lpushx)
|
||||
* [LRANGE](https://sugardb.io/docs/commands/list/lrange)
|
||||
* [LREM](https://sugardb.io/docs/commands/list/lrem)
|
||||
* [LSET](https://sugardb.io/docs/commands/list/lset)
|
||||
* [LTRIM](https://sugardb.io/docs/commands/list/ltrim)
|
||||
* [RPOP](https://sugardb.io/docs/commands/list/rpop)
|
||||
* [RPUSH](https://sugardb.io/docs/commands/list/rpush)
|
||||
* [RPUSHX](https://sugardb.io/docs/commands/list/rpushx)
|
||||
|
||||
<a name="commands-pubsub"></a>
|
||||
## PUBSUB
|
||||
* [PSUBSCRIBE](https://sugardb.io/docs/commands/pubsub/psubscribe)
|
||||
* [PUBLISH](https://sugardb.io/docs/commands/pubsub/publish)
|
||||
* [PUBSUB CHANNELS](https://sugardb.io/docs/commands/pubsub/pubsub_channels)
|
||||
* [PUBSUB NUMPAT](https://sugardb.io/docs/commands/pubsub/pubsub_numpat)
|
||||
* [PUBSUB NUMSUB](https://sugardb.io/docs/commands/pubsub/pubsub_numsub)
|
||||
* [PUNSUBSCRIBE](https://sugardb.io/docs/commands/pubsub/punsubscribe)
|
||||
* [SUBSCRIBE](https://sugardb.io/docs/commands/pubsub/subscribe)
|
||||
* [UNSUBSCRIBE](https://sugardb.io/docs/commands/pubsub/unsubscribe)
|
||||
|
||||
<a name="commands-set"></a>
|
||||
## SET
|
||||
* [SADD](https://sugardb.io/docs/commands/set/sadd)
|
||||
* [SCARD](https://sugardb.io/docs/commands/set/scard)
|
||||
* [SDIFF](https://sugardb.io/docs/commands/set/sdiff)
|
||||
* [SDIFFSTORE](https://sugardb.io/docs/commands/set/sdiffstore)
|
||||
* [SINTER](https://sugardb.io/docs/commands/set/sinter)
|
||||
* [SINTERCARD](https://sugardb.io/docs/commands/set/sintercard)
|
||||
* [SINTERSTORE](https://sugardb.io/docs/commands/set/sinterstore)
|
||||
* [SISMEMBER](https://sugardb.io/docs/commands/set/sismember)
|
||||
* [SMEMBERS](https://sugardb.io/docs/commands/set/smembers)
|
||||
* [SMISMEMBER](https://sugardb.io/docs/commands/set/smismember)
|
||||
* [SMOVE](https://sugardb.io/docs/commands/set/smove)
|
||||
* [SPOP](https://sugardb.io/docs/commands/set/spop)
|
||||
* [SRANDMEMBER](https://sugardb.io/docs/commands/set/srandmember)
|
||||
* [SREM](https://sugardb.io/docs/commands/set/srem)
|
||||
* [SUNION](https://sugardb.io/docs/commands/set/sunion)
|
||||
* [SUNIONSTORE](https://sugardb.io/docs/commands/set/sunionstore)
|
||||
|
||||
<a name="commands-sortedset"></a>
|
||||
## SORTED SET
|
||||
* [ZADD](https://sugardb.io/docs/commands/sorted_set/zadd)
|
||||
* [ZCARD](https://sugardb.io/docs/commands/sorted_set/zcard)
|
||||
* [ZCOUNT](https://sugardb.io/docs/commands/sorted_set/zcount)
|
||||
* [ZDIFF](https://sugardb.io/docs/commands/sorted_set/zdiff)
|
||||
* [ZDIFFSTORE](https://sugardb.io/docs/commands/sorted_set/zdiffstore)
|
||||
* [ZINCRBY](https://sugardb.io/docs/commands/sorted_set/zincrby)
|
||||
* [ZINTER](https://sugardb.io/docs/commands/sorted_set/zinter)
|
||||
* [ZINTERSTORE](https://sugardb.io/docs/commands/sorted_set/zinterstore)
|
||||
* [ZLEXCOUNT](https://sugardb.io/docs/commands/sorted_set/zlexcount)
|
||||
* [ZMPOP](https://sugardb.io/docs/commands/sorted_set/zmpop)
|
||||
* [ZMSCORE](https://sugardb.io/docs/commands/sorted_set/zmscore)
|
||||
* [ZPOPMAX](https://sugardb.io/docs/commands/sorted_set/zpopmax)
|
||||
* [ZPOPMIN](https://sugardb.io/docs/commands/sorted_set/zpopmin)
|
||||
* [ZRANDMEMBER](https://sugardb.io/docs/commands/sorted_set/zrandmember)
|
||||
* [ZRANGE](https://sugardb.io/docs/commands/sorted_set/zrange)
|
||||
* [ZRANGESTORE](https://sugardb.io/docs/commands/sorted_set/zrangestore)
|
||||
* [ZRANK](https://sugardb.io/docs/commands/sorted_set/zrank)
|
||||
* [ZREM](https://sugardb.io/docs/commands/sorted_set/zrem)
|
||||
* [ZREMRANGEBYLEX](https://sugardb.io/docs/commands/sorted_set/zremrangebylex)
|
||||
* [ZREMRANGEBYRANK](https://sugardb.io/docs/commands/sorted_set/zremrangebyrank)
|
||||
* [ZREMRANGEBYSCORE](https://sugardb.io/docs/commands/sorted_set/zremrangebyscore)
|
||||
* [ZREVRANK](https://sugardb.io/docs/commands/sorted_set/zrevrank)
|
||||
* [ZSCORE](https://sugardb.io/docs/commands/sorted_set/zscore)
|
||||
* [ZUNION](https://sugardb.io/docs/commands/sorted_set/zunion)
|
||||
* [ZUNIONSTORE](https://sugardb.io/docs/commands/sorted_set/zunionstore)
|
||||
|
||||
<a name="commands-string"></a>
|
||||
## STRING
|
||||
* [APPEND](https://sugardb.io/docs/commands/string/append)
|
||||
* [GETRANGE](https://sugardb.io/docs/commands/string/getrange)
|
||||
* [SETRANGE](https://sugardb.io/docs/commands/string/setrange)
|
||||
* [STRLEN](https://sugardb.io/docs/commands/string/strlen)
|
||||
* [SUBSTR](https://sugardb.io/docs/commands/string/substr)
|
||||
53
cmd/main.go
Normal file
53
cmd/main.go
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright 2024 Kelvin Clement Mwinuka
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"apigo.cc/go/sugardb/internal"
|
||||
"apigo.cc/go/sugardb/internal/config"
|
||||
"apigo.cc/go/sugardb/sugardb"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func main() {
|
||||
conf, err := config.GetConfig()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
ctx := context.WithValue(context.Background(), internal.ContextServerID("ServerID"), conf.ServerID)
|
||||
|
||||
cancelCh := make(chan os.Signal, 1)
|
||||
signal.Notify(cancelCh, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)
|
||||
|
||||
server, err := sugardb.NewSugarDB(
|
||||
sugardb.WithContext(ctx),
|
||||
sugardb.WithConfig(conf),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
go server.Start()
|
||||
|
||||
<-cancelCh
|
||||
|
||||
server.ShutDown()
|
||||
}
|
||||
10378
coverage/coverage.out
Normal file
10378
coverage/coverage.out
Normal file
File diff suppressed because it is too large
Load Diff
281
docker-compose.yaml
Normal file
281
docker-compose.yaml
Normal file
@ -0,0 +1,281 @@
|
||||
networks:
|
||||
testnet:
|
||||
driver: bridge
|
||||
|
||||
services:
|
||||
standalone_node:
|
||||
container_name: standalone_node
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
environment:
|
||||
- BIND_ADDR=0.0.0.0
|
||||
- PORT=7480
|
||||
- DISCOVERY_PORT=7946
|
||||
- SERVER_ID=1
|
||||
- PLUGIN_DIR=/usr/local/lib/sugardb
|
||||
- DATA_DIR=/var/lib/sugardb
|
||||
- TLS=false
|
||||
- MTLS=false
|
||||
- BOOTSTRAP_CLUSTER=false
|
||||
- ACL_CONFIG=/etc/sugardb/config/acl.yml
|
||||
- REQUIRE_PASS=false
|
||||
- PASSWORD=password1
|
||||
- FORWARD_COMMAND=false
|
||||
- SNAPSHOT_THRESHOLD=1000
|
||||
- SNAPSHOT_INTERVAL=5m30s
|
||||
- RESTORE_SNAPSHOT=true
|
||||
- RESTORE_AOF=false
|
||||
- AOF_SYNC_STRATEGY=everysec
|
||||
- MAX_MEMORY=2000kb
|
||||
- EVICTION_POLICY=noeviction
|
||||
- EVICTION_SAMPLE=20
|
||||
- EVICTION_INTERVAL=100ms
|
||||
# List of sugardb cert/key pairs
|
||||
- CERT_KEY_PAIR_1=/etc/ssl/certs/sugardb/server/server1.crt,/etc/ssl/certs/sugardb/server/server1.key
|
||||
- CERT_KEY_PAIR_2=/etc/ssl/certs/sugardb/server/server2.crt,/etc/ssl/certs/sugardb/server/server2.key
|
||||
# List of client certificate authorities
|
||||
- CLIENT_CA_1=/etc/ssl/certs/sugardb/client/rootCA.crt
|
||||
# List of shared object plugins to load on startup
|
||||
- MODULE_1=./modules/module_set/module_set.so
|
||||
- MODULE_2=./modules/module_get/module_get.so
|
||||
ports:
|
||||
- "7480:7480"
|
||||
- "7946:7946"
|
||||
volumes:
|
||||
- ./internal/volumes/config:/etc/sugardb/config
|
||||
- ./internal/volumes/nodes/standalone_node:/var/lib/sugardb
|
||||
- ./internal/volumes/modules/lua:/var/lib/sugardb/scripts/lua
|
||||
- ./internal/volumes/modules/js:/var/lib/sugardb/scripts/js
|
||||
networks:
|
||||
- testnet
|
||||
|
||||
cluster_node_1:
|
||||
container_name: cluster_node_1
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
environment:
|
||||
- BIND_ADDR=0.0.0.0
|
||||
- PORT=7480
|
||||
- DISCOVERY_PORT=7946
|
||||
- SERVER_ID=1
|
||||
- JOIN_ADDR=2/cluster_node_2:7946
|
||||
- DATA_DIR=/var/lib/sugardb
|
||||
- TLS=false
|
||||
- MTLS=false
|
||||
- BOOTSTRAP_CLUSTER=true
|
||||
- ACL_CONFIG=/etc/sugardb/config/acl.yml
|
||||
- REQUIRE_PASS=false
|
||||
- FORWARD_COMMAND=true
|
||||
- SNAPSHOT_THRESHOLD=1000
|
||||
- SNAPSHOT_INTERVAL=5m30s
|
||||
- RESTORE_SNAPSHOT=false
|
||||
- RESTORE_AOF=false
|
||||
- AOF_SYNC_STRATEGY=everysec
|
||||
- MAX_MEMORY=100mb
|
||||
- EVICTION_POLICY=noeviction
|
||||
- EVICTION_SAMPLE=20
|
||||
- EVICTION_INTERVAL=100ms
|
||||
# List of sugardb cert/key pairs
|
||||
- CERT_KEY_PAIR_1=/etc/ssl/certs/sugardb/server/server1.crt,/etc/ssl/certs/sugardb/server/server1.key
|
||||
- CERT_KEY_PAIR_2=/etc/ssl/certs/sugardb/server/server2.crt,/etc/ssl/certs/sugardb/server/server2.key
|
||||
# List of client certificate authorities
|
||||
- CLIENT_CA_1=/etc/ssl/certs/sugardb/client/rootCA.crt
|
||||
# List of shared object plugins to load on startup
|
||||
- MODULE_1=./modules/module_set/module_set.so
|
||||
- MODULE_2=./modules/module_get/module_get.so
|
||||
ports:
|
||||
- "7481:7480"
|
||||
- "7945:7946"
|
||||
volumes:
|
||||
- ./internal/volumes/config:/etc/sugardb/config
|
||||
- ./internal/volumes/nodes/cluster_node_1:/var/lib/sugardb
|
||||
- ./internal/volumes/modules/lua:/var/lib/sugardb/scripts/lua
|
||||
- ./internal/volumes/modules/js:/var/lib/sugardb/scripts/js
|
||||
networks:
|
||||
- testnet
|
||||
|
||||
cluster_node_2:
|
||||
container_name: cluster_node_2
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
environment:
|
||||
- BIND_ADDR=0.0.0.0
|
||||
- PORT=7480
|
||||
- DISCOVERY_PORT=7946
|
||||
- SERVER_ID=2
|
||||
- JOIN_ADDR=3/cluster_node_3:7946
|
||||
- DATA_DIR=/var/lib/sugardb
|
||||
- TLS=false
|
||||
- MTLS=false
|
||||
- BOOTSTRAP_CLUSTER=false
|
||||
- ACL_CONFIG=/etc/sugardb/config/acl.yml
|
||||
- REQUIRE_PASS=false
|
||||
- FORWARD_COMMAND=true
|
||||
- SNAPSHOT_THRESHOLD=1000
|
||||
- SNAPSHOT_INTERVAL=5m30s
|
||||
- RESTORE_SNAPSHOT=false
|
||||
- RESTORE_AOF=false
|
||||
- AOF_SYNC_STRATEGY=everysec
|
||||
- MAX_MEMORY=100mb
|
||||
- EVICTION_POLICY=noeviction
|
||||
- EVICTION_SAMPLE=20
|
||||
- EVICTION_INTERVAL=100ms
|
||||
# List of sugardb cert/key pairs
|
||||
- CERT_KEY_PAIR_1=/etc/ssl/certs/sugardb/server/server1.crt,/etc/ssl/certs/sugardb/server/server1.key
|
||||
- CERT_KEY_PAIR_2=/etc/ssl/certs/sugardb/server/server2.crt,/etc/ssl/certs/sugardb/server/server2.key
|
||||
# List of client certificate authorities
|
||||
- CLIENT_CA_1=/etc/ssl/certs/sugardb/client/rootCA.crt
|
||||
# List of shared object plugins to load on startup
|
||||
- MODULE_1=./modules/module_set/module_set.so
|
||||
- MODULE_2=./modules/module_get/module_get.so
|
||||
ports:
|
||||
- "7482:7480"
|
||||
- "7947:7946"
|
||||
volumes:
|
||||
- ./internal/volumes/config:/etc/sugardb/config
|
||||
- ./internal/volumes/nodes/cluster_node_2:/var/lib/sugardb
|
||||
- ./internal/volumes/modules/lua:/var/lib/sugardb/scripts/lua
|
||||
- ./internal/volumes/modules/js:/var/lib/sugardb/scripts/js
|
||||
networks:
|
||||
- testnet
|
||||
|
||||
cluster_node_3:
|
||||
container_name: cluster_node_3
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
environment:
|
||||
- BIND_ADDR=0.0.0.0
|
||||
- PORT=7480
|
||||
- DISCOVERY_PORT=7946
|
||||
- SERVER_ID=3
|
||||
- JOIN_ADDR=4/cluster_node_4:7946
|
||||
- DATA_DIR=/var/lib/sugardb
|
||||
- TLS=false
|
||||
- MTLS=false
|
||||
- BOOTSTRAP_CLUSTER=false
|
||||
- ACL_CONFIG=/etc/sugardb/config/acl.yml
|
||||
- REQUIRE_PASS=false
|
||||
- FORWARD_COMMAND=true
|
||||
- SNAPSHOT_THRESHOLD=1000
|
||||
- SNAPSHOT_INTERVAL=5m30s
|
||||
- RESTORE_SNAPSHOT=false
|
||||
- RESTORE_AOF=false
|
||||
- AOF_SYNC_STRATEGY=everysec
|
||||
- MAX_MEMORY=100mb
|
||||
- EVICTION_POLICY=noeviction
|
||||
- EVICTION_SAMPLE=20
|
||||
- EVICTION_INTERVAL=100ms
|
||||
# List of sugardb cert/key pairs
|
||||
- CERT_KEY_PAIR_1=/etc/ssl/certs/sugardb/server/server1.crt,/etc/ssl/certs/sugardb/server/server1.key
|
||||
- CERT_KEY_PAIR_2=/etc/ssl/certs/sugardb/server/server2.crt,/etc/ssl/certs/sugardb/server/server2.key
|
||||
# List of client certificate authorities
|
||||
- CLIENT_CA_1=/etc/ssl/certs/sugardb/client/rootCA.crt
|
||||
# List of shared object plugins to load on startup
|
||||
- MODULE_1=./modules/module_set/module_set.so
|
||||
- MODULE_2=./modules/module_get/module_get.so
|
||||
ports:
|
||||
- "7483:7480"
|
||||
- "7948:7946"
|
||||
volumes:
|
||||
- ./internal/volumes/config:/etc/sugardb/config
|
||||
- ./internal/volumes/nodes/cluster_node_3:/var/lib/sugardb
|
||||
- ./internal/volumes/modules/lua:/var/lib/sugardb/scripts/lua
|
||||
- ./internal/volumes/modules/js:/var/lib/sugardb/scripts/js
|
||||
networks:
|
||||
- testnet
|
||||
|
||||
cluster_node_4:
|
||||
container_name: cluster_node_4
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
environment:
|
||||
- BIND_ADDR=0.0.0.0
|
||||
- PORT=7480
|
||||
- DISCOVERY_PORT=7946
|
||||
- SERVER_ID=4
|
||||
- JOIN_ADDR=5/cluster_node_5:7946
|
||||
- DATA_DIR=/var/lib/sugardb
|
||||
- TLS=false
|
||||
- MTLS=false
|
||||
- BOOTSTRAP_CLUSTER=false
|
||||
- ACL_CONFIG=/etc/sugardb/config/acl.yml
|
||||
- REQUIRE_PASS=false
|
||||
- FORWARD_COMMAND=true
|
||||
- SNAPSHOT_THRESHOLD=1000
|
||||
- SNAPSHOT_INTERVAL=5m30s
|
||||
- RESTORE_SNAPSHOT=false
|
||||
- RESTORE_AOF=false
|
||||
- AOF_SYNC_STRATEGY=everysec
|
||||
- MAX_MEMORY=100mb
|
||||
- EVICTION_POLICY=noeviction
|
||||
- EVICTION_SAMPLE=20
|
||||
- EVICTION_INTERVAL=100ms
|
||||
# List of sugardb cert/key pairs
|
||||
- CERT_KEY_PAIR_1=/etc/ssl/certs/sugardb/server/server1.crt,/etc/ssl/certs/sugardb/server/server1.key
|
||||
- CERT_KEY_PAIR_2=/etc/ssl/certs/sugardb/server/server2.crt,/etc/ssl/certs/sugardb/server/server2.key
|
||||
# List of client certificate authorities
|
||||
- CLIENT_CA_1=/etc/ssl/certs/sugardb/client/rootCA.crt
|
||||
# List of shared object plugins to load on startup
|
||||
- MODULE_1=./modules/module_set/module_set.so
|
||||
- MODULE_2=./modules/module_get/module_get.so
|
||||
ports:
|
||||
- "7484:7480"
|
||||
- "7949:7946"
|
||||
volumes:
|
||||
- ./internal/volumes/config:/etc/sugardb/config
|
||||
- ./internal/volumes/nodes/cluster_node_4:/var/lib/sugardb
|
||||
- ./internal/volumes/modules/lua:/var/lib/sugardb/scripts/lua
|
||||
- ./internal/volumes/modules/js:/var/lib/sugardb/scripts/js
|
||||
networks:
|
||||
- testnet
|
||||
|
||||
cluster_node_5:
|
||||
container_name: cluster_node_5
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.dev
|
||||
environment:
|
||||
- BIND_ADDR=0.0.0.0
|
||||
- PORT=7480
|
||||
- DISCOVERY_PORT=7946
|
||||
- SERVER_ID=5
|
||||
- JOIN_ADDR=1/cluster_node_1:7946
|
||||
- DATA_DIR=/var/lib/sugardb
|
||||
- TLS=false
|
||||
- MTLS=false
|
||||
- BOOTSTRAP_CLUSTER=false
|
||||
- ACL_CONFIG=/etc/sugardb/config/acl.yml
|
||||
- REQUIRE_PASS=false
|
||||
- FORWARD_COMMAND=true
|
||||
- SNAPSHOT_THRESHOLD=1000
|
||||
- SNAPSHOT_INTERVAL=5m30s
|
||||
- RESTORE_SNAPSHOT=false
|
||||
- RESTORE_AOF=false
|
||||
- AOF_SYNC_STRATEGY=everysec
|
||||
- MAX_MEMORY=100mb
|
||||
- EVICTION_POLICY=noeviction
|
||||
- EVICTION_SAMPLE=20
|
||||
- EVICTION_INTERVAL=100ms
|
||||
# List of sugardb cert/key pairs
|
||||
- CERT_KEY_PAIR_1=/etc/ssl/certs/sugardb/server/server1.crt,/etc/ssl/certs/sugardb/server/server1.key
|
||||
- CERT_KEY_PAIR_2=/etc/ssl/certs/sugardb/server/server2.crt,/etc/ssl/certs/sugardb/server/server2.key
|
||||
# List of client certificate authorities
|
||||
- CLIENT_CA_1=/etc/ssl/certs/sugardb/client/rootCA.crt
|
||||
# List of shared object plugins to load on startup
|
||||
- MODULE_1=./modules/module_set/module_set.so
|
||||
- MODULE_2=./modules/module_get/module_get.so
|
||||
ports:
|
||||
- "7485:7480"
|
||||
- "7950:7946"
|
||||
volumes:
|
||||
- ./internal/volumes/config:/etc/sugardb/config
|
||||
- ./internal/volumes/nodes/cluster_node_5:/var/lib/sugardb
|
||||
- ./internal/volumes/modules/lua:/var/lib/sugardb/scripts/lua
|
||||
- ./internal/volumes/modules/js:/var/lib/sugardb/scripts/js
|
||||
networks:
|
||||
- testnet
|
||||
22
docs/.gitignore
vendored
Normal file
22
docs/.gitignore
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
# Dependencies
|
||||
/node_modules
|
||||
|
||||
# Production
|
||||
/build
|
||||
|
||||
# Generated files
|
||||
.docusaurus
|
||||
.cache-loader
|
||||
.next
|
||||
package-lock.json
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
1
docs/CNAME
Normal file
1
docs/CNAME
Normal file
@ -0,0 +1 @@
|
||||
.io
|
||||
3
docs/babel.config.js
Normal file
3
docs/babel.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
||||
};
|
||||
5
docs/blog/authors.yml
Normal file
5
docs/blog/authors.yml
Normal file
@ -0,0 +1,5 @@
|
||||
kelvinmwinuka:
|
||||
name: Kelvin Clement Mwinuka
|
||||
title: EchoVault Maintainer
|
||||
url: https://kelvinmwinuka.com
|
||||
image_url: https://github.com/kelvinmwinuka.png
|
||||
199
docs/docs/acl.md
Normal file
199
docs/docs/acl.md
Normal file
@ -0,0 +1,199 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
# Access Control List
|
||||
|
||||
Access Control Lists enable you to add a layer of security to the SugarDB server or cluster. You can create users with associated rules and require clients to authorize before executing commands on the server.
|
||||
|
||||
SugarDB creates a default user upon startup. You can see this user by executing the following command:
|
||||
|
||||
```
|
||||
> ACL LIST
|
||||
1) "default on +@all +all %RW~* +&*"
|
||||
```
|
||||
|
||||
The default user is enabled, and has access to all categories, commands, keys and pub/sub channels. Connections are associated with user by default.
|
||||
|
||||
You can configure the default user to require a passwords by using the following configuration options:
|
||||
|
||||
- `--require-pass` forces the SugarDB server to require a user to authenticate itself using a password and/or username.
|
||||
|
||||
- `--password` attaches the provided password to the default user.
|
||||
|
||||
## Authorization
|
||||
|
||||
The TCP client can authenticate itself using the `AUTH` command:
|
||||
|
||||
`AUTH <username> <password>` tries to authenticate the TCP connection with the provided username and password.
|
||||
|
||||
`AUTH <password>` tries to authenticate the TCP connection with the default user and the provided passsword.
|
||||
|
||||
Authorization is not supported in embedded mode. When an SugarDB instance is embedded, it autimatically has access to all the commands exposed by the API.
|
||||
|
||||
## Configuration files
|
||||
|
||||
You can configure ACL Rules by passing the path to the config file to the `--acl-config=<path/to/config/file>` flag. The configuration file can be either a YAML or JSON file.
|
||||
|
||||
### YAML Config example
|
||||
|
||||
```yaml
|
||||
- Username: "user1"
|
||||
Enabled: true
|
||||
NoPassword: false
|
||||
NoKeys: false
|
||||
Passwords:
|
||||
- PasswordType: "plaintext"
|
||||
PasswordValue: "password1"
|
||||
- PasswordType: "SHA256"
|
||||
PasswordValue: "6cf615d5bcaac778352a8f1f3360d23f02f34ec182e259897fd6ce485d7870d4"
|
||||
IncludedCategories: ["*"]
|
||||
ExcludedCategories: []
|
||||
IncludedReadKeys: ["*"]
|
||||
IncludedWriteKeys: ["*"]
|
||||
IncludedPubSubChannels: ["*"]
|
||||
ExcludedPubSubChannels: []
|
||||
|
||||
- Username: "user2"
|
||||
Enabled: true
|
||||
NoPassword: false
|
||||
NoKeys: false
|
||||
Passwords:
|
||||
- PasswordType: "plaintext"
|
||||
PasswordValue: "password4"
|
||||
- PasswordType: "SHA256"
|
||||
PasswordValue: "8b2c86ea9cf2ea4eb517fd1e06b74f399e7fec0fef92e3b482a6cf2e2b092023"
|
||||
IncludedCategories: ["hash", "set", "sortedset", "list", "generic"]
|
||||
ExcludedCategories: []
|
||||
IncludedReadKeys: ["*"]
|
||||
IncludedWriteKeys: ["*"]
|
||||
IncludedPubSubChannels: ["user:channel:*"]
|
||||
ExcludedPubSubChannels: ["admin:channel:*"]
|
||||
```
|
||||
|
||||
### JSON Config example
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"Username": "user1",
|
||||
"Enabled": true,
|
||||
"NoPassword": false,
|
||||
"NoKeys": false,
|
||||
"Passwords": [
|
||||
{
|
||||
"PasswordType": "plaintext",
|
||||
"PasswordValue": "password1"
|
||||
},
|
||||
{
|
||||
"PasswordType": "SHA256",
|
||||
"PasswordValue": "6cf615d5bcaac778352a8f1f3360d23f02f34ec182e259897fd6ce485d7870d4"
|
||||
}
|
||||
],
|
||||
"IncludedCategories": ["*"],
|
||||
"ExcludedCategories": [],
|
||||
"IncludedReadKeys": ["*"],
|
||||
"IncludedWriteKeys": ["*"],
|
||||
"IncludedPubSubChannels": ["*"],
|
||||
"ExcludedPubSubChannels": []
|
||||
},
|
||||
{
|
||||
"Username": "user2",
|
||||
"Enabled": true,
|
||||
"NoPassword": false,
|
||||
"NoKeys": false,
|
||||
"Passwords": [
|
||||
{
|
||||
"PasswordType": "plaintext",
|
||||
"PasswordValue": "password4"
|
||||
},
|
||||
{
|
||||
"PasswordType": "SHA256",
|
||||
"PasswordValue": "8b2c86ea9cf2ea4eb517fd1e06b74f399e7fec0fef92e3b482a6cf2e2b092023"
|
||||
}
|
||||
],
|
||||
"IncludedCategories": ["hash", "set", "sortedset", "list", "generic"],
|
||||
"ExcludedCategories": [],
|
||||
"IncludedReadKeys": ["*"],
|
||||
"IncludedWriteKeys": ["*"],
|
||||
"IncludedPubSubChannels": ["user:channel:*"],
|
||||
"ExcludedPubSubChannels": ["admin:channel:*"]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## ACL rules
|
||||
|
||||
ACL rules allow you to add new user profiles and set fine-grained rules that determine what clients can do on the server.
|
||||
|
||||
The default user's rules are very permissive so if you want to restrict access, you will have to explicitly configure ACL rules. The default user can be configured too.
|
||||
|
||||
### Enable and disable users
|
||||
|
||||
- `on` - Enable this user. A TCP connection can authenticate as this user.
|
||||
- `off` - Disable this user. It's impossible to authenticate as thsi user.
|
||||
|
||||
### Allow and disallow categories
|
||||
|
||||
- `+@all` - Allow this user to access all categories (aliased by `allCategories` and `+@*`). This overrides all other category access rules.
|
||||
- `-@all` - Block this user from accessing any categories (aliased by `-@*`, and `nocommands`). This overrides all other category access rules.
|
||||
- `+@<category>` - Allow this user to access the specified category. If updating an existing user, then this category will be added to the list of categories they are allowed to access.
|
||||
- `-@<category>` - Block the user from accessing this specific category. If updating an existing user, then this category is removed from the list of categories the user is allowed to access.
|
||||
|
||||
If both `+@all` and `-@all` are specified, whichever one is specified last will take effect.
|
||||
|
||||
The `nocommands` flag will apply the `-@all` rule.
|
||||
|
||||
### Allow and disallow commands
|
||||
|
||||
- `+all` - Allow this user to execute all commands (aliased by `allCommands`). This overrides all other command access rules.
|
||||
- `-all` - Block this user from executing any commands. This overrides all other command access rules.
|
||||
- `+<command>` - Allow the user to access the specified command. In order to allow the user to access only a specific subcommand, you can use `+<command>|<subcommand>`.
|
||||
- `-<command>` - Block this user from executing any commands. In order to allow the user to access only a specific subscommand, you can user `-<command>|<subcommand>`.
|
||||
|
||||
If both `+all` and `-all` are specified, whichever one is specified last will take effect.
|
||||
|
||||
The `nocommands` flag will apply the `-all` rule.
|
||||
|
||||
### Allow and disallow access to keys
|
||||
|
||||
By default, SugarDB allows each user to read and write to all keys. If you'd like to control what keys users have access to and what they can do with those keys, you can make use of the following options:
|
||||
|
||||
- `%RW~*` - Allow this user to read and write all keys on the SugarDB instance (aliased by `allKeys`).
|
||||
- `%RW~<key>` - Allow this user to read and write to the specified key. This option accepts a glob pattern for the key which allows you to restrict certain key patterns.
|
||||
- `%W~*` - Allow the user to write to all keys.
|
||||
- `%W~<key>` - Block the user from writing to any keys except the one specified. A glob pattern can be used in place of the key.
|
||||
- `%R~*` - Allow the user to read from all the keys.
|
||||
- `%R~<key>` - Block the user from reading any keys except the one specified. A glob pattern can be used in place of the key.
|
||||
|
||||
### Allow and disallow Pub/Sub channels
|
||||
|
||||
- `+&*` - Allow this user to access all pub/sub channels (aliased by `allChannels`).
|
||||
- `-&*` - Block this user from accessing any of the pub/sub channels.
|
||||
- `+&<channel>` - Allow this user to access the specied channel. This rule accepts a glob pattern (e.g. "channel\*").
|
||||
- `-&<channel>` - Block this user from accessing the specied channel. This rule accepts a glob pattern (e.g. "channel\*").
|
||||
|
||||
If both `+&*` and `-&*` are specified, the one specified last will take effect.
|
||||
|
||||
### Add and remove passwords
|
||||
|
||||
By default users have no password and require no password to authenticate against them except when the `--require-pass` configuration is `true`. You can add and remove passwords associated with a user using the following options:
|
||||
|
||||
- `><password>` - Adds the plaintext password to the list of passwords associated with the user.
|
||||
- `<<password>` - Removes the plaintext password from the list of passwords associated with the user.
|
||||
- `#<hash>` - Adds the hash to the list of passwords associated with the user. The hash must be a SHA256 hash. When the user is being authenticated, they provide a plaintext passwords and the passwords will be compared with the user's plaintext passwords. If no match is found, the password's SHA256 hash is compared with the list of password hashes associated with the user.
|
||||
- `!<hash>` - Removes the SHA256 hash from the list of passwords hashes associated with the user.
|
||||
|
||||
### Reset the user
|
||||
|
||||
You can pass certain flags to make sweeping updates to a user's ACL rules. These flags often reset the granular rules specified above.
|
||||
|
||||
- `nopass` - Deletes all the user's associated passwords. Future TCP connections will not need to provide a password to authenticate against this user.
|
||||
- `resetpass` - Deletes all the user's associated passwords, but does not set the `nopass` flag to true.
|
||||
- `nocommands` - Blocks the user from executing any commands.
|
||||
- `resetkeys` - Blocks the user from accesssing any keys for both reads and writes (aliased by `nokeys`).
|
||||
- `resetchannels` - Allows the user to access all pub/sub channels.
|
||||
|
||||
## Examples
|
||||
|
||||
For examples on how to create and update ACL users and their rules, checkout out the `ACL SETUSER` command documentation.
|
||||
11
docs/docs/architecture/index.md
Normal file
11
docs/docs/architecture/index.md
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# Architecture
|
||||
|
||||
SugarDB can be run in the following modes:
|
||||
|
||||
- Standalone mode - Where only one instance runs in isolation.
|
||||
- Replication cluster - Strongly consistent RAFT cluster.
|
||||
- Sharding - To be implemented.
|
||||
59
docs/docs/commands/acl/acl_cat.mdx
Normal file
59
docs/docs/commands/acl/acl_cat.mdx
Normal file
@ -0,0 +1,59 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# ACL CAT
|
||||
|
||||
### Syntax
|
||||
```
|
||||
ACL CAT [category]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">acl</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Lists all the categories. If the optional category is provided, lists all the commands in the category.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
List all categories:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
categories, err := db.ACLCat()
|
||||
```
|
||||
|
||||
List all commands/subcommands in pubsub module:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
commands, err := db.ACLCat("pubsub")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
List all categories:
|
||||
```
|
||||
> ACL CAT
|
||||
```
|
||||
|
||||
List all commands/subcommands in pubsub module:
|
||||
```
|
||||
> ACL CAT pubsub
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/acl/acl_deluser.mdx
Normal file
47
docs/docs/commands/acl/acl_deluser.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# ACL DELUSER
|
||||
|
||||
### Syntax
|
||||
```
|
||||
ACL DELUSER username [username ...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">acl</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Deletes users and terminates their connections. This command cannot delete the default user.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Delete users:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.ACLDelUser("username1", "username2")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Delete users:
|
||||
```
|
||||
> ACL DELUSER username1 username2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
77
docs/docs/commands/acl/acl_getuser.mdx
Normal file
77
docs/docs/commands/acl/acl_getuser.mdx
Normal file
@ -0,0 +1,77 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# ACL GETUSER
|
||||
|
||||
### Syntax
|
||||
```
|
||||
ACL GETUSER username
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">acl</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
List the ACL rules of a user.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Retrieve user:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
rules, err := db.ACLGetUser("username")
|
||||
```
|
||||
|
||||
Returns a map[string][]string map where each key is the rule category and each value is a string slice of relevant values.
|
||||
The map returned has the following structure:
|
||||
|
||||
- "username" - string slice containing the user's username.
|
||||
- "flags" - string slices containing the following values: "on" if the user is enabled, otherwise "off",
|
||||
- "nokeys" if the user is not allowed to access any keys (and NoKeys is true),
|
||||
- "nopass" if the user has no passwords (and NoPass is true).
|
||||
- "categories" - string slice af ACL command categories associated with the user.
|
||||
If the user is allowed to access all categories, it will contain "+@*".
|
||||
For each category the user is allowed to access, the slice will contain "+@\<category\>".
|
||||
If the user is not allowed to access any categories, it will contain "-@*".
|
||||
For each category the user is not allowed to access, the slice will contain "-@\<category\>".
|
||||
- "commands" - string slice af commands associated with the user.
|
||||
If the user is allowed to execute all commands, it will contain "+all".
|
||||
For each command the user is allowed to execute, the slice will contain "+\<command\>".
|
||||
If the user is not allowed to execute any commands, it will contain "-all".
|
||||
For each command the user is not allowed to execute, the slice will contain "-\<category\>".
|
||||
- "keys" - string slice af keys associated with the user.
|
||||
If the user is allowed read/write access all keys, the slice will contain "%RW~*".
|
||||
For each key glob pattern the user has read/write access to, the slice will contain "%RW~\<pattern\>".
|
||||
If the user is allowed read access to all keys, the slice will contain "%R~*".
|
||||
For each key glob pattern the user has read access to, the slice will contain "%R~\<pattern\>".
|
||||
If the user is allowed write access to all keys, the slice will contain "%W~*".
|
||||
For each key glob pattern the user has write access to, the slice will contain "%W~\<pattern\>".
|
||||
- "channels" - string slice af pubsub channels associated with the user.
|
||||
If the user is allowed to access all channels, the slice will contain "+&*".
|
||||
For each channel the user is allowed to access, the slice will contain "+&\<channel\>".
|
||||
If the user is not allowed to access any channels, the slice will contain "-&*".
|
||||
For each channel the user is not allowed to access, the slice will contain "-&\<channel\>".
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Retrieve user:
|
||||
```
|
||||
> ACL GETUSER username
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/acl/acl_list.mdx
Normal file
47
docs/docs/commands/acl/acl_list.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# ACL LIST
|
||||
|
||||
### Syntax
|
||||
```
|
||||
ACL LIST
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">acl</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Dumps effective acl rules in ACL DSL format.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
List ACL rules:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
rules, err := db.ACLList()
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
List ACL rules:
|
||||
```
|
||||
> ACL LIST
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
58
docs/docs/commands/acl/acl_load.mdx
Normal file
58
docs/docs/commands/acl/acl_load.mdx
Normal file
@ -0,0 +1,58 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# ACL LOAD
|
||||
|
||||
### Syntax
|
||||
```
|
||||
ACL LOAD <MERGE | REPLACE>
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">acl</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Reloads the rules from the configured ACL config file.
|
||||
When 'MERGE' is passed, users from config file who share a username with users in memory will be merged.
|
||||
When 'REPLACE' is passed, users from config file who share a username with users in memory will replace the user in memory.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Load ACL config:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// Load config and merge with currently loaded ACL config
|
||||
ok, err := db.ACLLoad(sugardb.ACLLoadOptions{Merge: true})
|
||||
|
||||
// Load config and replace currently loaded ACL config
|
||||
ok, err := db.ACLLoad(sugardb.ACLLoadOptions{Replace: true})`
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Load ACL config file and merge it with currently loaded config:
|
||||
```
|
||||
> ACL LOAD MERGE
|
||||
```
|
||||
|
||||
Load ACL config file and replace the currently loaded config:
|
||||
```
|
||||
> ACL LOAD REPLACE
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
49
docs/docs/commands/acl/acl_save.mdx
Normal file
49
docs/docs/commands/acl/acl_save.mdx
Normal file
@ -0,0 +1,49 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# ACL SAVE
|
||||
|
||||
### Syntax
|
||||
```
|
||||
ACL SAVE
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">acl</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Saves the effective ACL rules the configured ACL config file.
|
||||
The save command overwrites the current ACL config file entirely and using the current
|
||||
in-memory ACL configuration.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Save ACL rules:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := server.ACLSave()
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Save ACL rules:
|
||||
```
|
||||
> ACL SAVE
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
123
docs/docs/commands/acl/acl_setuser.mdx
Normal file
123
docs/docs/commands/acl/acl_setuser.mdx
Normal file
@ -0,0 +1,123 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# ACL SETUSER
|
||||
|
||||
### Syntax
|
||||
```
|
||||
ACL SAVE
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">acl</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Configure a new or existing user.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Save user:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
user := sugardb.User{}
|
||||
ok, err := server.ACLSetUser(user)
|
||||
```
|
||||
|
||||
The User struct takes the following shape:
|
||||
```go
|
||||
type User struct {
|
||||
// Username - string - the user's username.
|
||||
Username string
|
||||
|
||||
// Enabled - bool - whether the user should be enabled (i.e connections can authenticate with this user).
|
||||
Enabled bool
|
||||
|
||||
// NoPassword - bool - if true, this user can be authenticated against without a password.
|
||||
NoPassword bool
|
||||
|
||||
// NoKeys - bool - if true, this user will not be allowed to access any keys.
|
||||
NoKeys bool
|
||||
|
||||
// NoCommands - bool - if true, this user will not be allowed to execute any commands.
|
||||
NoCommands bool
|
||||
|
||||
// ResetPass - bool - if true, all the user's configured passwords are removed and NoPassword is set to false.
|
||||
ResetPass bool
|
||||
|
||||
// ResetKeys - bool - if true, the user's NoKeys flag is set to true and all their currently accessible keys are cleared.
|
||||
ResetKeys bool
|
||||
|
||||
// ResetChannels - bool - if true, the user will be allowed to access all PubSub channels.
|
||||
ResetChannels bool
|
||||
|
||||
// AddPlainPasswords - []string - the list of plaintext passwords to add to the user's passwords.
|
||||
AddPlainPasswords []string
|
||||
|
||||
// RemovePlainPasswords - []string - the list of plaintext passwords to remove from the user's passwords.
|
||||
RemovePlainPasswords []string
|
||||
|
||||
// AddHashPasswords - []string - the list of SHA256 password hashes to add to the user's passwords.
|
||||
AddHashPasswords []string
|
||||
|
||||
// RemoveHashPasswords - []string - the list of SHA256 password hashes to add to the user's passwords.
|
||||
RemoveHashPasswords []string
|
||||
|
||||
// IncludeCategories - []string - the list of ACL command categories to allow this user to access, default is all.
|
||||
IncludeCategories []string
|
||||
|
||||
// ExcludeCategories - []string - the list of ACL command categories to bar the user from accessing. The default is none.
|
||||
ExcludeCategories []string
|
||||
|
||||
// IncludeCommands - []string - the list of commands to allow the user to execute. The default is none. If you want to
|
||||
// specify a subcommand, use the format "command|subcommand".
|
||||
IncludeCommands []string
|
||||
|
||||
// ExcludeCommands - []string - the list of commands to bar the user from executing.
|
||||
// The default is none. If you want to specify a subcommand, use the format "command|subcommand".
|
||||
ExcludeCommands []string
|
||||
|
||||
// IncludeReadWriteKeys - []string - the list of keys the user is allowed read and write access to. The default is all.
|
||||
// This field accepts glob pattern strings.
|
||||
IncludeReadWriteKeys []string
|
||||
|
||||
// IncludeReadKeys - []string - the list of keys the user is allowed read access to. The default is all.
|
||||
// This field accepts glob pattern strings.
|
||||
IncludeReadKeys []string
|
||||
|
||||
// IncludeWriteKeys - []string - the list of keys the user is allowed write access to. The default is all.
|
||||
// This field accepts glob pattern strings.
|
||||
IncludeWriteKeys []string
|
||||
|
||||
// IncludeChannels - []string - the list of PubSub channels the user is allowed to access ("Subscribe" and "Publish").
|
||||
// This field accepts glob pattern strings.
|
||||
IncludeChannels []string
|
||||
|
||||
// ExcludeChannels - []string - the list of PubSub channels the user cannot access ("Subscribe" and "Publish").
|
||||
// This field accepts glob pattern strings.
|
||||
ExcludeChannels []string
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Checkout the <a href="/docs/acl">Access Control List documentation</a> for the list of rules.
|
||||
```
|
||||
> ACL SETUSER username
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/acl/acl_users.mdx
Normal file
47
docs/docs/commands/acl/acl_users.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# ACL USERS
|
||||
|
||||
### Syntax
|
||||
```
|
||||
ACL USERS
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">acl</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Lists all usernames of the configured ACL users.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
List ACL usernames:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
users, err := db.ACLUsers()
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
List ACL usersnames:
|
||||
```
|
||||
> ACL USERS
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
38
docs/docs/commands/acl/acl_whoami.mdx
Normal file
38
docs/docs/commands/acl/acl_whoami.mdx
Normal file
@ -0,0 +1,38 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# ACL WHOAMI
|
||||
|
||||
### Syntax
|
||||
```
|
||||
ACL WHOAMI
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">acl</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
Returns the authenticated user of the current connection.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Not available in embedded mode.
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get the username of the user associated with the current connection:
|
||||
```
|
||||
> ACL WHOAMI
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
1
docs/docs/commands/acl/index.md
Normal file
1
docs/docs/commands/acl/index.md
Normal file
@ -0,0 +1 @@
|
||||
# ACL
|
||||
46
docs/docs/commands/admin/command_count.mdx
Normal file
46
docs/docs/commands/admin/command_count.mdx
Normal file
@ -0,0 +1,46 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# COMMAND COUNT
|
||||
|
||||
### Syntax
|
||||
```
|
||||
COMMAND COUNT
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">admin</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Get the number of commands in the SugarDB instance.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get server command count:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
count, err := db.CommandCount()
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get server command count:
|
||||
```
|
||||
> COMMAND COUNT
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
94
docs/docs/commands/admin/command_list.mdx
Normal file
94
docs/docs/commands/admin/command_list.mdx
Normal file
@ -0,0 +1,94 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# COMMAND LIST
|
||||
|
||||
### Syntax
|
||||
```
|
||||
COMMAND LIST [FILTERBY <ACLCAT category | PATTERN pattern | MODULE module>]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">admin</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Get the list of command names. Allows for filtering by ACL category or glob pattern.
|
||||
|
||||
### Options
|
||||
|
||||
FILTERBY - An optional condition used to filter the response. ACLCAT filters by the provided acl
|
||||
category string. PATTERN filters the response by the provided glob pattern.
|
||||
MODULE filters the response by the provided SugarDB module.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get a list of all the loaded commands:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
commands, err := db.CommandList(sugardb.CommandListOptions{})
|
||||
```
|
||||
|
||||
Get a list of all commands with the \"fast\" ACL category:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
commands, err := db.CommandList(sugardb.CommandListOptions{ACLCAT: "fast"})
|
||||
```
|
||||
|
||||
Get a list of all commands which satisfy the \"z*\" glob pattern:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
commands, err := db.CommandList(sugardb.CommandListOptions{PATTERN: "z*"})
|
||||
```
|
||||
|
||||
Get a list of all the commands in the \"set\" module:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
commands, err := db.CommandList(sugardb.CommandListOptions{MODULE: "set"})
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get a list of all the loaded commands:
|
||||
```
|
||||
> COMMAND LIST
|
||||
```
|
||||
|
||||
Get a list of all commands with the "fast" ACL category:
|
||||
```
|
||||
> COMMAND LIST FILTERBY ACLCAT fast
|
||||
```
|
||||
|
||||
Get a list of all commands which satisfy the "z*" glob pattern:
|
||||
```
|
||||
> COMMAND LIST FILTERBY PATTERN z*
|
||||
```
|
||||
|
||||
Get a list of all the commands in the "set" module:
|
||||
```
|
||||
> COMMAND LIST FILTERBY MODULE set
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
40
docs/docs/commands/admin/commands.mdx
Normal file
40
docs/docs/commands/admin/commands.mdx
Normal file
@ -0,0 +1,40 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# COMMANDS
|
||||
|
||||
### Syntax
|
||||
```
|
||||
COMMANDS
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">admin</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Get a list of all the commands in available on the SugarDB instance with categories and descriptions.
|
||||
Sub-commands are formatted as "command|subcommand".
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Make use of the <a href="/docs/commands/admin/command_list">CommandList method</a>.
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get List of commands:
|
||||
```
|
||||
> COMMAND
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
1
docs/docs/commands/admin/index.md
Normal file
1
docs/docs/commands/admin/index.md
Normal file
@ -0,0 +1 @@
|
||||
# Admin
|
||||
47
docs/docs/commands/admin/lastsave.mdx
Normal file
47
docs/docs/commands/admin/lastsave.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# LASTSAVE
|
||||
|
||||
### Syntax
|
||||
```
|
||||
LASTSAVE
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">admin</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
Get unix timestamp for the latest snapshot in milliseconds.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get last snapshot timestamp:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
count, err := db.LastSave()
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get last snapshot timestamp:
|
||||
```
|
||||
> LASTSAVE
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/admin/module_list.mdx
Normal file
47
docs/docs/commands/admin/module_list.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# MODULE LIST
|
||||
|
||||
### Syntax
|
||||
```
|
||||
MODULE LIST
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">admin</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
List all the modules that are currently loaded in the server/instance.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
List all the modules that are currently loaded in the instance:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
modules := db.ListModules()
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
List all the modules that are currently loaded in the server:
|
||||
```
|
||||
> MODULE LIST
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
63
docs/docs/commands/admin/module_load.mdx
Normal file
63
docs/docs/commands/admin/module_load.mdx
Normal file
@ -0,0 +1,63 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# MODULE LOAD
|
||||
|
||||
### Syntax
|
||||
```
|
||||
MODULE LOAD path [arg [arg ...]]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">admin</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
Load a module from a dynamic library at runtime.
|
||||
The path should be the full path to the module, including the .so filename. Any args will be passed unmodified to the
|
||||
module's key extraction and handler functions.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Load a modules with no args:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err := server.LoadModule("/path/to/module.so")
|
||||
```
|
||||
|
||||
Load a module with a few args:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err := server.LoadModule("/path/to/module.so", "arg1", "arg2", "arg3")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Load a module with no args:
|
||||
```
|
||||
> MODULE LOAD path/to/module.so
|
||||
```
|
||||
|
||||
Load a module with a few args:
|
||||
```
|
||||
> MODULE LOAD path/to/module.so arg1 arg2 arg3
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/admin/module_unload.mdx
Normal file
47
docs/docs/commands/admin/module_unload.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# MODULE UNLOAD
|
||||
|
||||
### Syntax
|
||||
```
|
||||
MODULE UNLOAD name
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">admin</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
Unloads a module based on the its name as displayed by the MODULE LIST command.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Unload a module:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err := server.UnloadModule("module-name")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Unload a module:
|
||||
```
|
||||
> MODULE UNLOAD module-name
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/admin/rewriteaof.mdx
Normal file
47
docs/docs/commands/admin/rewriteaof.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# REWRITEAOF
|
||||
|
||||
### Syntax
|
||||
```
|
||||
REWRITEAOF
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">admin</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
Trigger re-writing of append process.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Trigger re-writing of append process:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
count, err := db.RewriteAOF()
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Trigger re-writing of append process:
|
||||
```
|
||||
> REWRITEAOF
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/admin/save.mdx
Normal file
47
docs/docs/commands/admin/save.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# SAVE
|
||||
|
||||
### Syntax
|
||||
```
|
||||
SAVE
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">admin</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">admin</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
Trigger a snapshot save.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Trigger a snapshot save:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
count, err := db.Save()
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Trigger a snapshot save:
|
||||
```
|
||||
> SAVE
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
46
docs/docs/commands/connection/auth.mdx
Normal file
46
docs/docs/commands/connection/auth.mdx
Normal file
@ -0,0 +1,46 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# AUTH
|
||||
|
||||
### Syntax
|
||||
```
|
||||
AUTH [username] password
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">connection</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">connection</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Authenticates the connection. If the username is not provided, the connection will be authenticated against the
|
||||
default ACL user. Otherwise, it is authenticated against the ACL user with the provided username.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
```go
|
||||
// Not available in embedded mode.
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Authenticate against the default user:
|
||||
```
|
||||
> AUTH password
|
||||
```
|
||||
Authenticate against a specific user:
|
||||
```
|
||||
> AUTH username password
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
42
docs/docs/commands/connection/echo.mdx
Normal file
42
docs/docs/commands/connection/echo.mdx
Normal file
@ -0,0 +1,42 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# ECHO
|
||||
|
||||
### Syntax
|
||||
```
|
||||
ECHO [message]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">connection</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">connection</span>
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
Sends a message to the SugarDB server and it returns the same message back.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
```go
|
||||
// Not available in embedded mode.
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Echo with message:
|
||||
|
||||
```
|
||||
> ECHO "Hello, World!"
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
86
docs/docs/commands/connection/hello.mdx
Normal file
86
docs/docs/commands/connection/hello.mdx
Normal file
@ -0,0 +1,86 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HELLO
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HELLO [protover [AUTH username password] [SETNAME clientname]]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">connection</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">connection</span>
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
Switch to a different protocol, optionally authenticating and setting the connection's name.
|
||||
This command returns a contextual client report.
|
||||
|
||||
### Options
|
||||
- `protover` - The protocol version to switch to. The default is 2.
|
||||
- `AUTH username password` - Authenticate with the server using the specified username and password.
|
||||
- `SETNAME clientname` - Set the connection's name to the specified clientname.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
When using the embedded API, there's no need to authenticate the API caller or set an alias for the caller.
|
||||
Therefore, only the set protocol functionality is available in embedded mode. You can set the protocol using
|
||||
the SetProtocol method:
|
||||
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err := db.SetProtocol(2)
|
||||
```
|
||||
|
||||
The method above changes the protocol to version 3. This is relevant when executing commands using the
|
||||
`ExecuteCommand` method. Since this methods returns a raw RESP response. It will not affect any other methods'
|
||||
return types as they return native go types.
|
||||
|
||||
`SetProtocol` return an error if the protocol version is not supported (i.e. not 2 or 3).
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Only fetch client report:
|
||||
```
|
||||
> HELLO
|
||||
```
|
||||
|
||||
Authenticate and set the connection's name:
|
||||
```
|
||||
> HELLO 2 AUTH myuser mypass SETNAME myclient
|
||||
```
|
||||
|
||||
Authenticate only:
|
||||
```
|
||||
> HELLO 2 AUTH myuser mypass
|
||||
```
|
||||
|
||||
Set the connection's name only:
|
||||
```
|
||||
> HELLO 2 SETNAME myclient
|
||||
```
|
||||
|
||||
Switch to protocol version 3:
|
||||
```
|
||||
> HELLO 3
|
||||
```
|
||||
|
||||
Authenticate and switch to protocol version 3:
|
||||
```
|
||||
> HELLO 3 AUTH myuser mypass
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
1
docs/docs/commands/connection/index.md
Normal file
1
docs/docs/commands/connection/index.md
Normal file
@ -0,0 +1 @@
|
||||
# Connection
|
||||
46
docs/docs/commands/connection/ping.mdx
Normal file
46
docs/docs/commands/connection/ping.mdx
Normal file
@ -0,0 +1,46 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# PING
|
||||
|
||||
### Syntax
|
||||
```
|
||||
PING [message]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">connection</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">connection</span>
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
Ping the SugarDB server. If a message is provided, the message will be echoed back to the client.
|
||||
Otherwise, the server will return "PONG".
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
```go
|
||||
// Not available in embedded mode.
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Ping without message (returns PONG):
|
||||
```
|
||||
> PING
|
||||
```
|
||||
Ping with message (returns "Hello, world!"):
|
||||
```
|
||||
> PING "Hello, world!"
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
50
docs/docs/commands/connection/select.mdx
Normal file
50
docs/docs/commands/connection/select.mdx
Normal file
@ -0,0 +1,50 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# SELECT
|
||||
|
||||
### Syntax
|
||||
```
|
||||
SELECT index
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">connection</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">connection</span>
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
Change the logical database that the current connection is operating from.
|
||||
If the database does not exist, it will be created.
|
||||
When this command is executed in a RAFT cluster, the database will be created in all the nodes of the cluster.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Select the database that the embedded instance is operating from:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err := db.SelectDB(2)
|
||||
```
|
||||
After successfully calling this method, all subsequent commands executed on that instance
|
||||
will be executed on the selected database. So you should to be careful when doing this in a multi-threaded environment.
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Select the database with index 1:
|
||||
```
|
||||
> SELECT 1
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
52
docs/docs/commands/connection/swapdb.mdx
Normal file
52
docs/docs/commands/connection/swapdb.mdx
Normal file
@ -0,0 +1,52 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# SWAPDB
|
||||
|
||||
### Syntax
|
||||
```
|
||||
SWAPDB index1 index2
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">connection</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">connection</span>
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
This command swaps two databases,
|
||||
so that immediately all the clients connected to a given database will see the data of the other database,
|
||||
and the other way around. If either one of the databases does not exist, it will be created.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Swap the databases with indexes 1 and 2:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err := db.SwapDBs(1, 2)
|
||||
```
|
||||
The method above only switches the databases for the currently active TCP connections.
|
||||
To switch the database for the embedded instance, use the `SelectDB` method.
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Swap the databases with indexes 1 and 2:
|
||||
```
|
||||
> SWAPDB 1 2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
85
docs/docs/commands/generic/copy.mdx
Normal file
85
docs/docs/commands/generic/copy.mdx
Normal file
@ -0,0 +1,85 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# COPY
|
||||
|
||||
### Syntax
|
||||
```
|
||||
COPY source destination [DB destination-db] [REPLACE]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">slow</span>
|
||||
<span className="acl-category">write</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
|
||||
### Description
|
||||
Copies the value stored at the source key to the destination key.
|
||||
Returns 1 if copied and 0 if not copied.
|
||||
Also returns 0 if the destination key already exists in the database and the REPLACE option is not set.
|
||||
|
||||
### Options
|
||||
- `DB destination-db`: the destination database to copy the key to
|
||||
- `REPLACE`: replace the destination key if it already exists
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
The API provides a struct called COPYOptions that wraps these options in a convenient object.
|
||||
```go
|
||||
type COPYOptions struct {
|
||||
Database string
|
||||
Replace bool
|
||||
}
|
||||
```
|
||||
|
||||
Copy the value stored at key 'hello' to the new key 'bye'
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
db.Set("hello", "world")
|
||||
key = db.Copy("hello", "bye")
|
||||
```
|
||||
|
||||
Copy the value stored at key 'hello' in database 0 and replace the value at key 'bye' in database 1
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err := db.SelectDB(1)
|
||||
ok, err := db.Set("bye", "goodbye")
|
||||
err := db.SelectDB(0)
|
||||
ok, err := db.Set("hello", "world")
|
||||
ret, err = db.Copy("hello", "bye", db.COPYOptions{Database: "1", Replace: true})
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Copy the value stored at key 'hello' to the key 'bye'
|
||||
```
|
||||
> SET "hello" "world"
|
||||
> COPY "hello" "bye"
|
||||
```
|
||||
|
||||
Copy the value stored at key 'hello' in database 0 and replace the value at key 'bye' in database 1
|
||||
```
|
||||
> SELECT 1
|
||||
> SET "bye" "goodbye"
|
||||
> SELECT 0
|
||||
> SET "hello" "world"
|
||||
> COPY "hello" "bye" DB 1 REPLACE
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/generic/dbsize.mdx
Normal file
47
docs/docs/commands/generic/dbsize.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# DBSIZE
|
||||
|
||||
### Syntax
|
||||
```
|
||||
DBSIZE
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">read</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
|
||||
### Description
|
||||
Return the number of keys in the currently-selected database.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get the number of keys in the database:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
key, err := db.DBSize()
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get the number of keys in the database:
|
||||
```
|
||||
> DBSIZE
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
50
docs/docs/commands/generic/decr.mdx
Normal file
50
docs/docs/commands/generic/decr.mdx
Normal file
@ -0,0 +1,50 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# DECR
|
||||
|
||||
### Syntax
|
||||
```
|
||||
DECR key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Decrements the number stored at key by one.
|
||||
If the key does not exist, it is set to 0 before performing the operation.
|
||||
An error is returned if the key contains a value of the wrong type or contains a string that cannot be represented as integer.
|
||||
This operation is limited to 64 bit signed integers.
|
||||
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Decrement the value of the key `mykey`:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
value, err := db.Decr("mykey")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Decrement the value of the key `mykey`:
|
||||
```
|
||||
> DECR mykey
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/generic/decrby.mdx
Normal file
48
docs/docs/commands/generic/decrby.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# DECRBY
|
||||
|
||||
### Syntax
|
||||
```
|
||||
DECRBY key decrement
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
The DECRBY command reduces the value stored at the specified key by the specified decrement.
|
||||
If the key does not exist, it is initialized with a value of 0 before performing the operation.
|
||||
If the key's value is not of the correct type or cannot be represented as an integer, an error is returned.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Decrement the value of the key `mykey` by 5:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
value, err := db.DecrBy("mykey 5")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Decrement the value of the key `mykey` by 5:
|
||||
```
|
||||
> DECRBY mykey 5
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
61
docs/docs/commands/generic/del.mdx
Normal file
61
docs/docs/commands/generic/del.mdx
Normal file
@ -0,0 +1,61 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# DEL
|
||||
|
||||
### Syntax
|
||||
```
|
||||
DEL key [key ...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Removes one or more keys from the store.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Delete a single key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
noOfDeletedKeys, err = db.Del("key1")
|
||||
```
|
||||
|
||||
Delete multiple keys:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
noOfDeletedKeys, err = db.Del("key1", "key2", "key3")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Delete a single key:
|
||||
```
|
||||
> DEL key
|
||||
```
|
||||
|
||||
Delete multiple keys:
|
||||
```
|
||||
> DEL key1 key2 key3
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/generic/exists.mdx
Normal file
47
docs/docs/commands/generic/exists.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# EXISTS
|
||||
|
||||
### Syntax
|
||||
```
|
||||
EXISTS
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">read</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
|
||||
### Description
|
||||
Returns the number of keys that exists from the provided list of keys. Note: If duplicate keys are provided, each one is counted separately.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Return the number of keys that exists:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
key, err := db.Exists("key1")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Return the number of keys that exists:
|
||||
```
|
||||
> EXISTS key1 key2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
106
docs/docs/commands/generic/expire.mdx
Normal file
106
docs/docs/commands/generic/expire.mdx
Normal file
@ -0,0 +1,106 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# EXPIRE
|
||||
|
||||
### Syntax
|
||||
```
|
||||
EXPIRE key seconds [NX | XX | GT | LT]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Expire the key in the specified number of seconds. This commands turns a key into a volatile one.
|
||||
|
||||
### Options
|
||||
|
||||
- `NX` - Only set the expiry time if the key has no associated expiry.
|
||||
- `XX` - Only set the expiry time if the key already has an expiry time.
|
||||
- `GT` - Only set the expiry time if the new expiry time is greater than the current one.
|
||||
- `LT` - Only set the expiry time if the new expiry time is less than the current one.
|
||||
<br></br>
|
||||
NX, GT, and LT are mutually exclusive. XX can additionally be passed in with either GT or LT.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
The embedded API utilizes the ExpireOptions interface, which acts as a wrapper for the various expiry options.
|
||||
<br></br>
|
||||
ExpireOptions include the following constants:
|
||||
- `NX` - Only set the expiry time if the key has no associated expiry.
|
||||
- `XX` - Only set the expiry time if the key already has an expiry time.
|
||||
- `GT` - Only set the expiry time if the new expiry time is greater than the current one.
|
||||
- `LT` - Only set the expiry time if the new expiry time is less than the current one.
|
||||
<br></br>
|
||||
Add an expiration to a key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 10, nil)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it does not have one already:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 10, sugardb.NX)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it has one already:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 10, sugardb.XX)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it already has one that is less than the current expiry:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 10, sugardb.XX, sugardb.LT)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Add an expiration to a key:
|
||||
```
|
||||
> EXPIRE key 10
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it does not have one already:
|
||||
```
|
||||
> EXPIRE key 10 NX
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it has one already:
|
||||
```
|
||||
> EXPIRE key 10 XX
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it already has one that is less than the current expiry:
|
||||
```
|
||||
> EXPIRE key 10 XX LT
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
106
docs/docs/commands/generic/expireat.mdx
Normal file
106
docs/docs/commands/generic/expireat.mdx
Normal file
@ -0,0 +1,106 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# EXPIREAT
|
||||
|
||||
### Syntax
|
||||
```
|
||||
EXPIREAT key unix-time-seconds [NX | XX | GT | LT]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Expire the key at the provided unix-time. This commands turns a key into a volatile one.
|
||||
|
||||
### Options
|
||||
|
||||
- `NX` - Only set the expiry time if the key has no associated expiry.
|
||||
- `XX` - Only set the expiry time if the key already has an expiry time.
|
||||
- `GT` - Only set the expiry time if the new expiry time is greater than the current one.
|
||||
- `LT` - Only set the expiry time if the new expiry time is less than the current one.
|
||||
<br></br>
|
||||
NX, GT, and LT are mutually exclusive. XX can additionally be passed in with either GT or LT.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
The embedded API utilizes the ExpireOptions interface, which acts as a wrapper for the various expiry options.
|
||||
<br></br>
|
||||
ExpireOptions include the following constants:
|
||||
- `NX` - Only set the expiry time if the key has no associated expiry.
|
||||
- `XX` - Only set the expiry time if the key already has an expiry time.
|
||||
- `GT` - Only set the expiry time if the new expiry time is greater than the current one.
|
||||
- `LT` - Only set the expiry time if the new expiry time is less than the current one.
|
||||
<br></br>
|
||||
Add an expiration to a key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 1767160800, nil)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it does not have one already:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 1767160800, sugardb.NX)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it has one already:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 1767160800, sugardb.XX)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it already has one that is less than the current expiry:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 1767160800, sugardb.XX, sugardb.LT)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Add an expiration to a key:
|
||||
```
|
||||
> EXPIRE key 1767160800
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it does not have one already:
|
||||
```
|
||||
> EXPIRE key 1767160800 NX
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it has one already:
|
||||
```
|
||||
> EXPIRE key 1767160800 XX
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it already has one that is less than the current expiry:
|
||||
```
|
||||
> EXPIRE key 1767160800 XX LT
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/generic/expiretime.mdx
Normal file
47
docs/docs/commands/generic/expiretime.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# EXPIRETIME
|
||||
|
||||
### Syntax
|
||||
```
|
||||
EXPIRETIME key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Returns the absolute unix time in seconds when the key will expire.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get the expiration time of a key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
expireTime, err := db.ExpireTime("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get the expiration time of a key:
|
||||
```
|
||||
> EXPIRETIME key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/generic/flushall.mdx
Normal file
48
docs/docs/commands/generic/flushall.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# FLUSHALL
|
||||
|
||||
### Syntax
|
||||
```
|
||||
FLUSHALL
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">slow</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Delete all the keys in all the existing databases. This command is always synchronous.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
In order to delete all the keys in all the databases, you need to pass -1 to the `Flush` method:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
db.Flush(-1)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Flush all the databases:
|
||||
```
|
||||
> FLUSHALL
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/generic/flushdb.mdx
Normal file
48
docs/docs/commands/generic/flushdb.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# FLUSHDB
|
||||
|
||||
### Syntax
|
||||
```
|
||||
FLUSHDB
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">dangerous</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">slow</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Delete all the keys in the currently selected database. This command is always synchronous.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
For the embedded instance, you need to pass the database index to the `Flush` method:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
db.Flush(0)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Flush the database that the current connection is operating from:
|
||||
```
|
||||
FLUSHDB
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/generic/get.mdx
Normal file
47
docs/docs/commands/generic/get.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# GET
|
||||
|
||||
### Syntax
|
||||
```
|
||||
GET key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Get the value at the specified key.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get the value at the specified key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
value, err := db.Get("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get the value at the specified key:
|
||||
```
|
||||
> GET key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
46
docs/docs/commands/generic/getdel.mdx
Normal file
46
docs/docs/commands/generic/getdel.mdx
Normal file
@ -0,0 +1,46 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# GETDEL
|
||||
|
||||
### Syntax
|
||||
```
|
||||
GETDEL key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Get the value of key and delete the key. This command is similar to [GET], but deletes key on success.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get the value at the specified key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
value, err := db.GetDel("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get the value at the specified key:
|
||||
```
|
||||
> GETDEL key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
65
docs/docs/commands/generic/getex.mdx
Normal file
65
docs/docs/commands/generic/getex.mdx
Normal file
@ -0,0 +1,65 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# GETEX
|
||||
|
||||
### Syntax
|
||||
```
|
||||
GETEX key [EX | PX | EXAT | PXAT | PERSIST]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Get the value of key and optionally set its expiration. GETEX is similar to [GET], but is a write command with additional options.
|
||||
|
||||
### Options
|
||||
- `EX` - Set the specified expire time, in seconds.
|
||||
- `PX` - Set the specified expire time, in milliseconds.
|
||||
- `EXAT` - Set the specified Unix time at which the key will expire, in seconds.
|
||||
- `PXAT` - Set the specified Unix time at which the key will expire, in milliseconds.
|
||||
- `PERSIST` - Remove the time to live associated with the key.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
The embedded API utilizes the GetExOption interface, which acts as a wrapper for the various expiry options of the GETEX command.
|
||||
<br></br>
|
||||
GetExOption includes the following constants:
|
||||
- `EX` - Set the specified expire time, in seconds.
|
||||
- `PX` - Set the specified expire time, in milliseconds.
|
||||
- `EXAT` - Set the specified Unix time at which the key will expire, in seconds.
|
||||
- `PXAT` - Set the specified Unix time at which the key will expire, in milliseconds.
|
||||
- `PERSIST` - Remove the time to live associated with the key.
|
||||
<br></br>
|
||||
Get the value at the specified key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
value, err := db.GetEx("key", nil, 0)
|
||||
|
||||
// optionally set expiry
|
||||
value, err = db.GetEx("key", sugardb.EX, 10)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get the value at the specified key and set the expiry:
|
||||
```
|
||||
> GETEX key EX 10
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/generic/incr.mdx
Normal file
48
docs/docs/commands/generic/incr.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# INCR
|
||||
|
||||
### Syntax
|
||||
```
|
||||
INCR key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Increments the number stored at key by one. If the key does not exist, it is set to 0 before performing the operation.
|
||||
An error is returned if the key contains a value of the wrong type or contains a string that cannot be represented as integer.
|
||||
This operation is limited to 64 bit signed integers.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Increment the value of the key `mykey`:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
value, err := db.Incr("mykey")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Increment the value of the key `mykey`:
|
||||
```
|
||||
> INCR mykey
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
50
docs/docs/commands/generic/incrby.mdx
Normal file
50
docs/docs/commands/generic/incrby.mdx
Normal file
@ -0,0 +1,50 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# INCRBY
|
||||
|
||||
### Syntax
|
||||
```
|
||||
INCRBY key increment
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Increments the number stored at key by increment. If the key does not exist, it is set to 0 before performing
|
||||
the operation. An error is returned if the key contains a value of the wrong type or contains a string
|
||||
that can not be represented as integer.
|
||||
|
||||
### Options
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Increment the value of the key `mykey` by 5:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
value, err := db.IncrBy("mykey", "5")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Increment the value of the key `mykey` by 5:
|
||||
```
|
||||
> INCRBY mykey 5
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
50
docs/docs/commands/generic/incrbyfloat.mdx
Normal file
50
docs/docs/commands/generic/incrbyfloat.mdx
Normal file
@ -0,0 +1,50 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# INCRBYFLOAT
|
||||
|
||||
### Syntax
|
||||
```
|
||||
INCRBYFLOAT key increment
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Increments the floating point number stored at key by increment. If the key does not exist, it is set to 0 before performing
|
||||
the operation. An error is returned if the key contains a value of the wrong type or contains a string
|
||||
that can not be represented as a floating point number.
|
||||
|
||||
### Options
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Increment the value of the key `mykey` by 10.33:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
value, err := db.IncrByFloat("mykey", "10.33")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Increment the value of the key `mykey` by 10.33:
|
||||
```
|
||||
> INCRBYFLOAT mykey 10.33
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
1
docs/docs/commands/generic/index.md
Normal file
1
docs/docs/commands/generic/index.md
Normal file
@ -0,0 +1 @@
|
||||
# Generic
|
||||
47
docs/docs/commands/generic/mget.mdx
Normal file
47
docs/docs/commands/generic/mget.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# MGET
|
||||
|
||||
### Syntax
|
||||
```
|
||||
MGET key [key ...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Get multiple values from the specified keys.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get the values at the specified keys:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
values, err := db.MGet("key1", "key2", "key3")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get the values at the specified keys:
|
||||
```
|
||||
> MGET key1 key2 key3
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/generic/move.mdx
Normal file
48
docs/docs/commands/generic/move.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# MOVE
|
||||
|
||||
### Syntax
|
||||
```
|
||||
MOVE key database
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Move key from currently selected database to specified destination database. Returns 1 if successful, if
|
||||
key already exists in the destination database, or key does not exist in the source database, it does nothing and returns 0.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Move the key to database 1:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
value, err := db.Move("key", 1)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Move the key to database 1:
|
||||
```
|
||||
> MOVE key 1
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
46
docs/docs/commands/generic/mset.mdx
Normal file
46
docs/docs/commands/generic/mset.mdx
Normal file
@ -0,0 +1,46 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# MSET
|
||||
|
||||
### Syntax
|
||||
```
|
||||
MSET key value [key value ...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">write</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Set or modify multiple key/value pairs at once.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Set multiple key/value pairs:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.MSet(map[string]string{"key1": "value1", "key2": "value2", "key3": "value3"})
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Set multiple key/value pairs:
|
||||
```
|
||||
> MSET key1 value1 key2 value2 key3 value3
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
49
docs/docs/commands/generic/objectfreq.mdx
Normal file
49
docs/docs/commands/generic/objectfreq.mdx
Normal file
@ -0,0 +1,49 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# OBJECTFREQ
|
||||
|
||||
### Syntax
|
||||
```
|
||||
OBJECTFREQ keys
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">read</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Get the time in seconds since the last access to the value stored at the key.
|
||||
The command is only available when the maxmemory-policy configuration directive is set to one of the LRU policies.
|
||||
This command returns an integer representing the access frequency. If the key doesn't exist -1 and an error is returned.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get a key's access frequency:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
freq, err := db.ObjectFreq("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get the access frequency of a key:
|
||||
```
|
||||
> OBJECTFREQ key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
50
docs/docs/commands/generic/objectidletime.mdx
Normal file
50
docs/docs/commands/generic/objectidletime.mdx
Normal file
@ -0,0 +1,50 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# OBJECTIDLETIME
|
||||
|
||||
### Syntax
|
||||
```
|
||||
OBJECTIDLETIME key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">read</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Get the time in seconds since the last access to the value stored at the key.
|
||||
The command is only available when the maxmemory-policy configuration directive is set to one of the LRU policies.
|
||||
This commands returns a float representing the seconds since the key was last accessed. If the key doesn't exist -1
|
||||
and an error is returned.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get a key's idle time:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
idletime, err := db.ObjectIdleTime("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get the idle time of a key:
|
||||
```
|
||||
> OBJECTIDLETIME key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/generic/persist.mdx
Normal file
47
docs/docs/commands/generic/persist.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# PERSIST
|
||||
|
||||
### Syntax
|
||||
```
|
||||
PERSIST key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Removes the TTl associated with a key, turning it from a volatile key to a persistent key.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Remove the TTL associated with a key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Persist("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Remove the TTL associated with a key:
|
||||
```
|
||||
> PERSIST key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
103
docs/docs/commands/generic/pexpire.mdx
Normal file
103
docs/docs/commands/generic/pexpire.mdx
Normal file
@ -0,0 +1,103 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# PEXPIRE
|
||||
|
||||
### Syntax
|
||||
```
|
||||
PEXPIRE key seconds [NX | XX | GT | LT]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Expire the key in the specified number of milliseconds. This commands turns a key into a volatile one.
|
||||
|
||||
## Options
|
||||
|
||||
- `NX` - Only set the expiry time if the key has no associated expiry.
|
||||
- `XX` - Only set the expiry time if the key already has an expiry time.
|
||||
- `GT` - Only set the expiry time if the new expiry time is greater than the current one.
|
||||
- `LT` - Only set the expiry time if the new expiry time is less than the current one.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
The embedded API utilizes the ExpireOptions interface, which acts as a wrapper for the various expiry options.
|
||||
<br></br>
|
||||
ExpireOptions include the following constants:
|
||||
- `NX` - Only set the expiry time if the key has no associated expiry.
|
||||
- `XX` - Only set the expiry time if the key already has an expiry time.
|
||||
- `GT` - Only set the expiry time if the new expiry time is greater than the current one.
|
||||
- `LT` - Only set the expiry time if the new expiry time is less than the current one.
|
||||
<br></br>
|
||||
Add an expiration to a key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
updated, err := db.PExpire("key", 10000, nil)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it does not have one already:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
updated, err := db.PExpire("key", 10000, db.NX)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it has one already:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
updated, err := db.PExpire("key", 10000, db.XX)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it already has one that is less than the current expiry:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
updated, err := db.PExpire("key", 10000, db.XX, db.LT)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Add an expiration to a key:
|
||||
```
|
||||
> PEXPIRE key 10000
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it does not have one already:
|
||||
```
|
||||
> PEXPIRE key 10000 NX
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it has one already:
|
||||
```
|
||||
> PEXPIRE key 10000 XX
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it already has one that is less than the current expiry:
|
||||
```
|
||||
> PEXPIRE key 10000 XX LT
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
106
docs/docs/commands/generic/pexpireat.mdx
Normal file
106
docs/docs/commands/generic/pexpireat.mdx
Normal file
@ -0,0 +1,106 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# PEXPIREAT
|
||||
|
||||
### Syntax
|
||||
```
|
||||
PEXPIREAT key unix-time-milliseconds [NX | XX | GT | LT]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Expire the key at the provided unix-time. This commands turns a key into a volatile one.
|
||||
|
||||
### Options
|
||||
|
||||
- `NX` - Only set the expiry time if the key has no associated expiry.
|
||||
- `XX` - Only set the expiry time if the key already has an expiry time.
|
||||
- `GT` - Only set the expiry time if the new expiry time is greater than the current one.
|
||||
- `LT` - Only set the expiry time if the new expiry time is less than the current one.
|
||||
<br></br>
|
||||
NX, GT, and LT are mutually exclusive. XX can additionally be passed in with either GT or LT.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
The embedded API utilizes the ExpireOptions interface, which acts as a wrapper for the various expiry options.
|
||||
<br></br>
|
||||
ExpireOptions include the following constants:
|
||||
- `NX` - Only set the expiry time if the key has no associated expiry.
|
||||
- `XX` - Only set the expiry time if the key already has an expiry time.
|
||||
- `GT` - Only set the expiry time if the new expiry time is greater than the current one.
|
||||
- `LT` - Only set the expiry time if the new expiry time is less than the current one.
|
||||
<br></br>
|
||||
Add an expiration to a key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 1767160800000, nil)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it does not have one already:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 1767160800000, db.NX)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it has one already:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 1767160800000, db.XX)
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it already has one that is less than the current expiry:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Expire("key", 1767160800000, db.XX, db.LT)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Add an expiration to a key:
|
||||
```
|
||||
> EXPIRE key 1767160800000
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it does not have one already:
|
||||
```
|
||||
> EXPIRE key 1767160800000 NX
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it has one already:
|
||||
```
|
||||
> EXPIRE key 1767160800000 XX
|
||||
```
|
||||
|
||||
Add an expiration to a key only if it already has one that is less than the current expiry:
|
||||
```
|
||||
> EXPIRE key 1767160800000 XX LT
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
50
docs/docs/commands/generic/pexpiretime.mdx
Normal file
50
docs/docs/commands/generic/pexpiretime.mdx
Normal file
@ -0,0 +1,50 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# PEXPIRETIME
|
||||
|
||||
### Syntax
|
||||
```
|
||||
PEXPIRETIME key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
|
||||
### Description
|
||||
Returns the absolute unix time in milliseconds when the key will expire.
|
||||
Returns -1 if the key exists but has no associated expiry time.
|
||||
Returns -2 if the key does not exist.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Retrieve the expiration time of a key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
pexpireTime, err := db.PExpireTime("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Retrieve the expiration time of a key:
|
||||
```
|
||||
> PEXPIRETIME key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
49
docs/docs/commands/generic/pttl.mdx
Normal file
49
docs/docs/commands/generic/pttl.mdx
Normal file
@ -0,0 +1,49 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# PTTL
|
||||
|
||||
### Syntax
|
||||
```
|
||||
PTTL key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Returns the remaining time to live for a key that has an expiry time in milliseconds.
|
||||
If the key exists but does not have an associated expiry time, -1 is returned.
|
||||
If the key does not exist, -2 is returned.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Retrieve the expiration time of a key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ttl, err := db.PTTL("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Retrieve the expiration time of a key:
|
||||
```
|
||||
> PTTL key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/generic/randomkey.mdx
Normal file
47
docs/docs/commands/generic/randomkey.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# RANDOMKEY
|
||||
|
||||
### Syntax
|
||||
```
|
||||
RANDOMKEY
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">slow</span>
|
||||
<span className="acl-category">read</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
|
||||
### Description
|
||||
Returns a random key from the currently selected database. If no keys are available, an empty string is returned.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get a random key from the database:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
key, err := db.RandomKey()
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get a random key from the database:
|
||||
```
|
||||
> RANDOMKEY
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
46
docs/docs/commands/generic/rename.mdx
Normal file
46
docs/docs/commands/generic/rename.mdx
Normal file
@ -0,0 +1,46 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# RENAME
|
||||
|
||||
### Syntax
|
||||
```
|
||||
RENAME key newkey
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Renames key to newkey. If newkey already exists, it is overwritten. If key does not exist, an error is returned.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Rename the key `mykey` to `newkey`:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = db.Rename("mykey", "newkey")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Rename the key `mykey` to `newkey`:
|
||||
```
|
||||
> RENAME mykey newkey
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/generic/renamenx.md
Normal file
47
docs/docs/commands/generic/renamenx.md
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# RENAMENX
|
||||
|
||||
### Syntax
|
||||
```
|
||||
RENAMENX key newkey
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Renames the specified key with the new name only if the new name does not already exist.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Rename the key `mykey` to `newkey`:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = db.RenameNX("mykey", "newkey")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Rename the key `mykey` to `newkey`:
|
||||
```
|
||||
> RENAMENX mykey newkey
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
121
docs/docs/commands/generic/set.mdx
Normal file
121
docs/docs/commands/generic/set.mdx
Normal file
@ -0,0 +1,121 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# SET
|
||||
|
||||
### Syntax
|
||||
```
|
||||
SET key value [NX | XX] [GET] [EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">slow</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Set the value of a key, considering the value's type. If the key already exists, it is overwritten.
|
||||
|
||||
### Options
|
||||
- `NX` - Only set if the key does not exist.
|
||||
- `XX` - Only set if the key exists.
|
||||
- `GET` - Return the old value stored at key, or nil if the value does not exist.
|
||||
- `EX` - Expire the key after the specified number of seconds (positive integer).
|
||||
- `PX` - Expire the key after the specified number of milliseconds (positive integer).
|
||||
- `EXAT` - Expire at the exact time in unix seconds (positive integer).
|
||||
- `PXAT` - Expire at the exat time in unix milliseconds (positive integer).
|
||||
|
||||
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
The embedded API organizes the SET command options into constants wrapped in interfaces.
|
||||
<br></br>
|
||||
SetWriteOption
|
||||
- `SETNX` - Only set if the key does not exist.
|
||||
- `SETXX` - Only set if the key exists.
|
||||
<br></br>
|
||||
SetExOption
|
||||
- `SETEX` - Expire the key after the specified number of seconds.
|
||||
- `SETPX` - Expire the key after the specified number of milliseconds.
|
||||
- `SETEXAT` - Expire at the exact time in unix seconds.
|
||||
- `SETPXAT` - Expire at the exact time in unix milliseconds.
|
||||
<br></br>
|
||||
The API provides a struct called SETOptions that wraps these options in a convenient object.
|
||||
```go
|
||||
type SETOptions struct {
|
||||
WriteOpt SetWriteOption
|
||||
ExpireOpt SetExOption
|
||||
ExpireTime int
|
||||
Get bool
|
||||
}
|
||||
```
|
||||
<br></br>
|
||||
Set a value at a key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Set("name", "SugarDB", db.SETOptions{})
|
||||
```
|
||||
|
||||
Set a value only if the key does not exist:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.Set("name", "SugarDB", db.SETOptions{WriteOpt: db.SETNX})
|
||||
```
|
||||
|
||||
Set a value if key already exists and get the previous value:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
previousValue, err := db.Set("name", "SugarDB", db.SetOptions{WriteOpt: db.SETXX, Get: true})
|
||||
```
|
||||
|
||||
Set a value if the key already exists, return the previous value, and expire after 10 seconds:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
previousValue, err := db.Set("name", "SugarDB", db.SetOptions{WriteOpt: db.SETXX, ExpireOpt: db.SETEX, ExpireTime 10, Get: true})
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Set a value at a key:
|
||||
```
|
||||
> SET name SugarDB
|
||||
```
|
||||
|
||||
Set a value only if the key does not exist:
|
||||
```
|
||||
> SET name SugarDB NX
|
||||
```
|
||||
|
||||
Set a value if key already exists and get the previous value:
|
||||
```
|
||||
> SET name SugarDB XX GET
|
||||
```
|
||||
|
||||
Set a value if the key already exists, return the previous value, and expire after 10 seconds:
|
||||
```
|
||||
> SET name SugarDB XX GET EX 10
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
62
docs/docs/commands/generic/touch.mdx
Normal file
62
docs/docs/commands/generic/touch.mdx
Normal file
@ -0,0 +1,62 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# TOUCH
|
||||
|
||||
### Syntax
|
||||
```
|
||||
TOUCH keys [key ...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">read</span>
|
||||
<span className="acl-category">fast</span>
|
||||
|
||||
### Description
|
||||
Alters the last access time or access count of the key(s) depending on whether LFU or LRU strategy was used.
|
||||
A key is ignored if it does not exist. This commands returns the number of keys that were touched.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Touch a key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
touched, err := db.Touch("key1")
|
||||
```
|
||||
|
||||
Touch multiple keys:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
touched, err := db.Touch("key1", "key2", "key3")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Touch a key:
|
||||
```
|
||||
> TOUCH key1
|
||||
```
|
||||
|
||||
Touch multiple keys:
|
||||
```
|
||||
> TOUCH key1 key2 key3
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
49
docs/docs/commands/generic/ttl.mdx
Normal file
49
docs/docs/commands/generic/ttl.mdx
Normal file
@ -0,0 +1,49 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# TTL
|
||||
|
||||
### Syntax
|
||||
```
|
||||
TTL key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Returns the remaining time to live for a key that has an expiry time in milliseconds.
|
||||
If the key exists but does not have an associated expiry time, -1 is returned.
|
||||
If the key does not exist, -2 is returned.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Retrieve the expiration time of a key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ttl, err := db.TTL("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Retrieve the expiration time of a key:
|
||||
```
|
||||
> TTL key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/generic/type.mdx
Normal file
48
docs/docs/commands/generic/type.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# TYPE
|
||||
|
||||
### Syntax
|
||||
```
|
||||
TYPE key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">generic</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">keyspace</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Returns the string representation of the value type stored at the key.
|
||||
The types that can be returned are string, integer, float, list, set, set, and hash.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Retrieve the type of the value stored at key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
type, err := db.Type("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Retrieve the type of the value stored at key:
|
||||
```
|
||||
> TYPE key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/hash/hdel.mdx
Normal file
48
docs/docs/commands/hash/hdel.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HDEL
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HDEL key field [field ...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
|
||||
### Description
|
||||
Deletes the specified fields from the hash.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Delete fields from a hash:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
deletedCount, err := db.HDel("key", "field1", "field2")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Delete fields from a hash:
|
||||
```
|
||||
> HDEL key field1 field2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/hash/hexists.mdx
Normal file
48
docs/docs/commands/hash/hexists.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HEXISTS
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HEXISTS key field
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
|
||||
### Description
|
||||
Returns if field is an existing field in the hash.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Returns if field exists in a hash:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
exists, err := db.HExists ("key", "field1")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Returns if field exists in a hash:
|
||||
```
|
||||
> HEXISTS key field1
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/hash/hexpire.mdx
Normal file
48
docs/docs/commands/hash/hexpire.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HEXPIRE
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HEXPIRE key seconds [NX | XX | GT | LT] FIELDS numfields field [field...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Set an expiration (TTL or time to live) in seconds on one or more fields of a given hash key.
|
||||
You must specify at least one field. Field(s) will automatically be deleted from the hash key when their TTLs expire.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Set the expiration in seconds for fields in the hash:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
respArray, err := db.HExpire("key", 500, nil, field1, field2)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Set the expiration in seconds for fields in the hash:
|
||||
```
|
||||
> HEXPIRE key 500 FIELDS 2 field1 field2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/hash/hget.mdx
Normal file
47
docs/docs/commands/hash/hget.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HGET
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HGET key field [field ...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Retrieve the value of each of the listed fields from the hash.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Retrieve values from a hash:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
values, err := db.HGet("key", "field1", "field2", "field3")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Retrieve values from a hash:
|
||||
```
|
||||
> HGET key field1 field2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/hash/hgetall.mdx
Normal file
47
docs/docs/commands/hash/hgetall.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HGETALL
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HGETALL key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">read</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Get all fields and values of a hash.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get all fields and values of a hash:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
result, err := db.HGetAll("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get all fields and values of a hash:
|
||||
```
|
||||
> HGETALL key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/hash/hincrby.mdx
Normal file
47
docs/docs/commands/hash/hincrby.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HINCRBY
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HINCRBY key field increment
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Increment the hash value by the integer increment.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Increment the hash value by the integer increment:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
newValue, err := db.HIncrBy("key", "field", 7)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Increment the hash value by the integer increment:
|
||||
```
|
||||
> HINCRBY key field 7
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/hash/hincrbyfloat.mdx
Normal file
47
docs/docs/commands/hash/hincrbyfloat.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HINCRBYFLOAT
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HINCRBYFLOAT key field increment
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Increment the hash value by the float increment.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Increment the hash value by the float increment:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
newValue, err := db.HIncrByFloat("key", "field", 7.75)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Increment the hash value by the float increment:
|
||||
```
|
||||
> HINCRBYFLOAT key field 7.75
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/hash/hkeys.mdx
Normal file
47
docs/docs/commands/hash/hkeys.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HKEYS
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HKEYS key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">read</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Returns all the fields in a hash.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Retrieve all fields from a hash:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
keys, err := db.HKeys("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Retrieve all fields from a hash:
|
||||
```
|
||||
> HKEYS key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/hash/hlen.mdx
Normal file
47
docs/docs/commands/hash/hlen.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HLEN
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HLEN key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Returns the number of fields in the hash.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Retrieve the number of fields in the hash:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
length, err := db.HLen("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Retrieve the number of fields in the hash:
|
||||
```
|
||||
> HLEN key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/hash/hmget.mdx
Normal file
47
docs/docs/commands/hash/hmget.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HMGET
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HMGET key field [field ...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Retrieves the value of each of the listed fields from the hash.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Retrieve values from a hash:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
values, err := db.HMGet("key", "field1", "field2", "field3")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Retrieve values from a hash:
|
||||
```
|
||||
> HMGET key field1 field2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
51
docs/docs/commands/hash/hrandfield.mdx
Normal file
51
docs/docs/commands/hash/hrandfield.mdx
Normal file
@ -0,0 +1,51 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HRANDFIELD
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HRANDFIELD key [count [WITHVALUES]]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">read</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Returns one or more random fields from the hash.
|
||||
|
||||
## Options
|
||||
- `WITHVALUES` - When provided, the return value will contain the field and its value.
|
||||
Otherwise, only the field is returned.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Returns one or more random fields from the hash:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fields, err := db.HRandField("key", db.HRandFieldOptions{})
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Returns one or more random fields from the hash:
|
||||
```
|
||||
> HRANDFIELD key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/hash/hset.mdx
Normal file
48
docs/docs/commands/hash/hset.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HSET
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HSET key field value [field value ...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Update each field of the hash with the corresponding value.
|
||||
If the field does not exist, it is created.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Update each field of the hash with the corresponding value:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
noOfUpdatedFields, err := db.HSet("key", map[string]string{"field1": "value1", "field2": "value2"})
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Update each field of the hash with the corresponding value:
|
||||
```
|
||||
> HSET key field1 value1 field2 value2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/hash/hsetnx.mdx
Normal file
47
docs/docs/commands/hash/hsetnx.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HSETNX
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HSETNX key field value [field value ...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Set hash field value only if the field does not exist.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Set hash field value:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
noOfUpdatedFields, err := db.HSetNX("key", map[string]string{"field1": "value1", "field2": "value2"})
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Set hash field value:
|
||||
```
|
||||
> HSETNX key field1 value1 field2 value2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/hash/hstrlen.mdx
Normal file
48
docs/docs/commands/hash/hstrlen.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HSTRLEN
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HSTRLEN key field [field ...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Return the string length of the values stored at the specified fields.
|
||||
Returns 0 if the value does not exist.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Return the string length of the values stored at the specified fields:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
lengths, err := db.HStrLen("key", "field1", "field2", "field3")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Return the string length of the values stored at the specified fields:
|
||||
```
|
||||
> HSTRLEN key field1 field2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/hash/httl.mdx
Normal file
48
docs/docs/commands/hash/httl.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HTTL
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HTTL key FIELDS numfields field [field...]
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Returns the remaining TTL (time to live) of a hash key's field(s) that have a set expiration.
|
||||
This introspection capability allows you to check how many seconds a given hash field will continue to be part of the hash key.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Get the expiration time in seconds for fields in the hash:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
TTLArray, err := db.HTTL("key", field1, field2)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Get the expiration time in seconds for fields in the hash:
|
||||
```
|
||||
> HTTL key FIELDS 2 field1 field2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/hash/hvals.mdx
Normal file
47
docs/docs/commands/hash/hvals.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# HVALS
|
||||
|
||||
### Syntax
|
||||
```
|
||||
HVALS key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">hash</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">hash</span>
|
||||
<span className="acl-category">read</span>
|
||||
<span className="acl-category">slow</span>
|
||||
|
||||
### Description
|
||||
Returns all the values of the hash at key.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Returns all the values of the hash at key:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
values, err := db.HVals("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Returns all the values of the hash at key:
|
||||
```
|
||||
> HVALS key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
1
docs/docs/commands/hash/index.md
Normal file
1
docs/docs/commands/hash/index.md
Normal file
@ -0,0 +1 @@
|
||||
# Hash
|
||||
5
docs/docs/commands/index.md
Normal file
5
docs/docs/commands/index.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
# Commands
|
||||
1
docs/docs/commands/list/index.md
Normal file
1
docs/docs/commands/list/index.md
Normal file
@ -0,0 +1 @@
|
||||
# List
|
||||
47
docs/docs/commands/list/lindex.mdx
Normal file
47
docs/docs/commands/list/lindex.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# LINDEX
|
||||
|
||||
### Syntax
|
||||
```
|
||||
LINDEX key index
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">list</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">list</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Returns the list element at the given index.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Returns the list element at the given index:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
element, err := db.LIndex("key", 2)
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Returns the list element at the given index:
|
||||
```
|
||||
> LINDEX key 2
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
47
docs/docs/commands/list/llen.mdx
Normal file
47
docs/docs/commands/list/llen.mdx
Normal file
@ -0,0 +1,47 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# LLEN
|
||||
|
||||
### Syntax
|
||||
```
|
||||
LLEN key
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">list</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">fast</span>
|
||||
<span className="acl-category">list</span>
|
||||
<span className="acl-category">read</span>
|
||||
|
||||
### Description
|
||||
Returns the length of a list.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Returns the length of a list:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
length, err := db.LLen("key")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Returns the length of a list:
|
||||
```
|
||||
> LLEN key
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
48
docs/docs/commands/list/lmove.mdx
Normal file
48
docs/docs/commands/list/lmove.mdx
Normal file
@ -0,0 +1,48 @@
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# LMOVE
|
||||
|
||||
### Syntax
|
||||
```
|
||||
LMOVE source destination <LEFT | RIGHT> <LEFT | RIGHT>
|
||||
```
|
||||
|
||||
### Module
|
||||
<span className="acl-category">list</span>
|
||||
|
||||
### Categories
|
||||
<span className="acl-category">list</span>
|
||||
<span className="acl-category">slow</span>
|
||||
<span className="acl-category">write</span>
|
||||
|
||||
### Description
|
||||
Move element from one list to the other specifying left/right for both lists.
|
||||
LEFT represents the start of a list. RIGHT represents the end of a list.
|
||||
|
||||
### Examples
|
||||
|
||||
<Tabs
|
||||
defaultValue="go"
|
||||
values={[
|
||||
{ label: 'Go (Embedded)', value: 'go', },
|
||||
{ label: 'CLI', value: 'cli', },
|
||||
]}
|
||||
>
|
||||
<TabItem value="go">
|
||||
Move an element from the beginning of the source list to the end of the destination list:
|
||||
```go
|
||||
db, err := sugardb.NewSugarDB()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
ok, err := db.LMove("source", "destination", "LEFT", "RIGHT")
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="cli">
|
||||
Move an element from the beginning of the source list to the end of the destination list:
|
||||
```
|
||||
> LMOVE source destination LEFT RIGHT
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user