User Quickstart with immudb and immuclient

    To learn interactively and to get started with immudb from the command line and with programming languages, visit the immudb Playground at https://play.codenotary.com (opens new window)

    You may download the immudb binary from . Once you have downloaded immudb, rename it to , make sure to mark it as executable, then run it. The following example shows how to obtain v1.0 for linux amd64:

    Alternatively, you may use Docker to run immudb in a ready-to-use container:

    1. docker run -d --net host -it --rm --name immudb codenotary/immudb:latest

    You may download the immuclient binary from the latest releases on Github (opens new window). Once you have downloaded immuclient, rename it to immuclient, make sure to mark it as executable, then run it. The following example shows how to obtain v1.0.0 for linux amd64:

    1. wget https://github.com/vchain-us/immudb/releases/download/v1.0.0/immuclient-v1.0.0-linux-amd64
    2. mv immuclient-v1.0.0-linux-amd64 immuclient
    3. chmod +x immuclient
    4. # start the interactive shell
    5. ./immuclient

    Alternatively, you may use Docker to run immuclient in a ready-to-use container:

    1. docker run -it --rm --net host --name immuclient codenotary/immuclient:latest

    Before any operations can be run by immuclient, it is necessary to authenticate against the running immudb server.

    • Database name: defaultdb
    • User: immudb
    • Password: immudb
    • Port: 3322

    Running login immudb from within immuclient will use the default database name and port. All you need to supply is the user and password:

    1. immuclient> login immudb
    2. Password: immudb

    While immudb supports set and get for key-value storing and retrieving, its immutability means that we can verify the integrity of the underlying Merkle tree. To do this, we use the safeset and safeget commands. Let’s try setting a value of 100 for the key balance:

    Then, we can immediately overwrite the key balance with a value of 9001 instead:

      If we try to retrieve the current value of key balance, we should get :

      1. immuclient> safeget balance

      Note that at each step so far, the verified flag is set to true. This ensures that the Merkle tree remains consistent for each transaction.

      We can show the history of transactions for key balance using the history command:

      1. immuclient> history balance
      1. $ immuclient exec "CREATE TABLE people(id INTEGER, name VARCHAR, salary INTEGER, PRIMARY KEY id);"
      2. sql ok, Ctxs: 1 Dtxs: 0

      To insert data, use UPSERT (insert or update), which will add an entry, or overwrite it if already exists (based on the primary key):

      To query the data you can use the traditional SELECT:

      1. $ immuclient query "SELECT id, name, salary FROM people;"
      2. +-----------------------+-------------------------+---------------------------+
      3. | (DEFAULTDB PEOPLE ID) | (DEFAULTDB PEOPLE NAME) | (DEFAULTDB PEOPLE SALARY) |
      4. +-----------------------+-------------------------+---------------------------+
      5. | 1 | Joe | 10000 |
      6. | 2 | Bob | 30000 |
      7. +-----------------------+-------------------------+---------------------------+

      If we upsert again on the primary key “1”, the value for “Joe” will be overwriten:

      1. immuclient exec "UPSERT INTO people(id, name, salary) VALUES (1, 'Joe', 20000);"
      2. sql ok, Ctxs: 0 Dtxs: 1
      3. immuclient query "SELECT id, name, salary FROM people;"
      4. +-----------------------+-------------------------+---------------------------+
      5. | (DEFAULTDB PEOPLE ID) | (DEFAULTDB PEOPLE NAME) | (DEFAULTDB PEOPLE SALARY) |
      6. | 1 | Joe | 20000 |
      7. +-----------------------+-------------------------+---------------------------+

      immudb is a immutable database. History is always preserved. With immudb you can travel in time!

      1. immuclient query "SELECT id, name, salary FROM people WHERE name='Joe';"
      2. +-----------------------+-------------------------+---------------------------+
      3. | (DEFAULTDB PEOPLE ID) | (DEFAULTDB PEOPLE NAME) | (DEFAULTDB PEOPLE SALARY) |
      4. +-----------------------+-------------------------+---------------------------+
      5. | 1 | Joe | 20000 |
      6. +-----------------------+-------------------------+---------------------------+

      Eg. before the update:

      1. immuclient query "SELECT id, name, salary FROM (people BEFORE TX 3) WHERE name='Joe';"
      2. +-----------------------+-------------------------+---------------------------+
      3. | (DEFAULTDB PEOPLE ID) | (DEFAULTDB PEOPLE NAME) | (DEFAULTDB PEOPLE SALARY) |
      4. +-----------------------+-------------------------+---------------------------+
      5. | 1 | Joe | 10000 |
      6. +-----------------------+-------------------------+---------------------------+

      or even before the first time insert (guess what, it is empty!):

      1. immuclient query "SELECT peoplenow.id, peoplenow.name, peoplethen.salary, peoplenow.salary FROM (people BEFORE TX 3 AS peoplethen) INNER JOIN (people AS peoplenow) ON peoplenow.id=peoplethen.id;"
      2. +--------------------------+----------------------------+-------------------------------+------------------------------+
      3. | (DEFAULTDB PEOPLENOW ID) | (DEFAULTDB PEOPLENOW NAME) | (DEFAULTDB PEOPLETHEN SALARY) | (DEFAULTDB PEOPLENOW SALARY) |
      4. +--------------------------+----------------------------+-------------------------------+------------------------------+
      5. | 1 | Joe | 10000 | 20000 |
      6. | 2 | Bob | 30000 | 30000 |