3️Basic Usage

Glacier primarily has the following core parts:

Let's see how to use them.

👨‍💼 GlacierClient

As we mentioned in the previous chapter, GlacierClient is the carrier we use to access Glacier. If you want to create a read-only client, you don't need to specify privateKey when instantiating or provider. You only need to specify the endpoint of the service, such as:

import { GlacierClient } from '@glacier-network/client';

const client = new GlacierClient('https://p0.onebitdev.com/glacier-gateway');

You can query Glacier for data through the above client.

But suppose you need to write to Glacier. In that case, you need to specify the privateKey or provider required for the signature. Usually, privateKey is only used for the Node.js server or script code. However, since it needs to be signed by the browser wallet at runtime in the browser, so provider is passed in, as in the following example:

src/server.ts

import { GlacierClient } from '@glacier-network/client';

const privateKey = `0xf7311f908890f7aeaf46d0185cf4234ae926cf896b2c50590d6735a37c827045`;
const client = new GlacierClient('https://p0.onebitdev.com/glacier-gateway', {
  privateKey,
});

src/browser.ts

import { GlacierClient } from '@glacier-network/client';

const client = new GlacierClient('https://p0.onebitdev.com/glacier-gateway', {
  provider: window.ethereum,
});

📇 Namespace

Namespace is the first-level unit in Glacier. There are usually only two operations: creation and enumeration. The code for creation is as follows:

src/createNamespace.ts

async function createNamespace() {
  const result = await client.createNamespace('myproject');
  console.log(result);
}

Output result:

{
  insertedId: 'myproject';
}

The codes to enumerate Namespace is as follows:

src/namespaces.ts

async function namespaces() {
  const result = await client.namespaces(
    '0xb4c42d4b15aa65f782b81ac01eaba2472f83b4e9'
  );
  console.log(result);
}

Output result:

[
  {
    owner: '0xb4c42d4b15aa65f782b81ac01eaba2472f83b4e9',
    network: 'ethereum',
    namespace: 'myproject',
    seqId: 0,
    dataset: [],
    createdAt: 1672026246,
    updatedAt: 1672036876,
  },
];

🗄️ Dataset

Dataset is a secondary unit in Glacier, similar to the MongoDB database, but each Dateset must belong to a Namespace.

The codes for creating Dataset is as follows, you need to get Namespace to which it belongs through client.namespace(name) firstly:

src/createDataset.ts

async function createDataset() {
  const myproject = client.namespace('myproject');
  const result = await myproject.createDataset('mydataset');
  console.log(result);
}

Output result:

{
  insertedId: 'mydataset';
}

If you want to query the details of a Dataset, you can use the queryDataset method provided by Namespace, the example is as follows:

src/queryDataset.ts

async function queryDataset() {
  const myproject = client.namespace('myproject');
  const result = await myproject.queryDataset('mydataset');
  console.log(result);
}

Output result:

{
  owner: '0xb4c42d4b15aa65f782b81ac01eaba2472f83b4e9',
  network: 'ethereum',
  namespace: 'myproject',
  dataset: 'mydataset',
  seqId: 0,
  collections: [
    {
      collection: 'notes',
      owner: '0xb4c42d4b15aa65f782b81ac01eaba2472f83b4e9',
      network: 'ethereum',
      schema: '{"title":"notes","type":"object","properties":{"title":{"type":"string","title":"","description":""},"content":{"type":"string","title":"","description":""},"createdAt":{"type":"number","title":"","description":""}},"required":["title","content","createdAt"]}',
      seqId: 0,
      createdAt: 1672069218,
      updatedAt: 1672069218
    }
  ],
  createdAt: 1672036876,
  updatedAt: 1672069218
}

collections from the above codes is Collection contained in this Dataset.

🗃️ Collection

Collection is a third-level unit in Glacier, it corresponds to Collection in MongoDB, and it needs to belong to a Dataset.

To create a Collection, you can use the createCollection method provided by Dataset, and you need to specify the data verification model required to create a Collection, that is, JSON Schema. The sample code is as follows:

src/createCollection.ts

async function createCollection() {
  const result = await client
    .namespace('myproject')
    .dataset('mydataset')
    .createCollection('notes', {
      title: 'Notes',
      type: 'object',
      properties: {
        title: {
          type: 'string',
          maxLength: 200,
        },
        content: {
          type: 'string',
          maxLength: 5000,
        },
        createdAt: {
          type: 'number',
        },
        updatedAt: {
          type: 'number',
        },
      },
      required: ['title', 'content'],
    });
  console.log(result);
}

Output result:

{
  insertedId: 'notes';
}

Collection is used to store each specific data record. You can get the Collection example to be operated through dataset.collection(name). The operations are addition, deletion, modification, and query. The sample is as follows:

Insert data

src/insertOne.ts

async function insertOne() {
  const now = Date.now();
  const notes = client
    .namespace('myproject')
    .dataset('mydataset')
    .collection('notes');
  const result = await notes.insertOne({
    title: `test title`,
    content: `test content`,
    createdAt: now,
    updatedAt: now,
  });
  console.log(result);
}

Query data

Collection provides a find method, which is analogous to MongoDB and supports most of MongoDB query conditions. Examples are as follows:

src/find.ts

async function find() {
  const notes = client
    .namespace('myproject')
    .dataset('mydataset')
    .collection('notes');
  const result = await notes
    .find({
      createdAt: {
        $gt: 1668149554498,
      },
    })
    .sort({
      createdAt: -1,
    })
    .skip(0)
    .limit(5)
    .toArray();
  console.log(result);
}

The advanced query syntax currently supported by Glacier SDK is as follows:

  • $eq

  • $gt

  • $gte

  • $in

  • $lt

  • $lte

  • $ne

  • $nin

  • $not

  • $exists

  • $regexp

  • $and

  • $nor

  • $or

CAUTION

In particular, find must call toArray() at the end to get the final query result.

Update data

Collection provides a updateOne method, which is used in a similar way to a combination of find and insertOne. Examples are as follows:

src/updateOne.ts

async function updateOne() {
  const now = Date.now();
  const result = await myCollection.updateOne(
    {
      _id: '1',
    },
    {
      updatedAt: now,
    }
  );
  console.log(result);
}

CAUTION

The data update in Glacier is different from MongoDB. Here updateOne is always a partial update rather than replacing the entire record when updating data, which is equivalent to using $set in MongoDB to update the data.

Delete data

Collection provides a deleteOne method, which is similar to the find method. The example is as follows:

src/deleteOne.ts

async function deleteOne() {
  const now = Date.now();
  const result = await myCollection.deleteOne({
    _id: '1',
  });
  console.log(result);
}

Last updated