Git Product home page Git Product logo

immudb-node's People

Contributors

hextar avatar napiergit avatar rafaelveggi avatar scarg avatar temii avatar tomekkolo avatar user3232 avatar vchain-us-mgmt avatar vchaindz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

immudb-node's Issues

version 2.0.0 stable Roadmap

First of all congratulations for the great work.

I would like to know if version 2 alpha is usable in production and if we have a forecast for stable version 2?

Thanks

ReferenceError: TextEncoder is not defined with old Node

What happened
I tried the SDK with an old version of Node, previous to 11.x.x, and encountered that error

ReferenceError: TextEncoder is not defined

Possible enhancement
TextEncoder has been added to node version >= 11.
Node LTS it's 12.13.0, but maybe could be helpful to add a recomended node version in the Readme.md.

API Reference?

Installed the new alpha version of immudb-node but looks like all methods changed signature. Is there an API Reference somewhere?

undefined value for TIMESTAMP field on SELECT

Hi :)

I have a TIMESTAMP field called created_at in our db.
To populate that field I use CAST(@created_at AS TIMESTAMP) (or NOW()) in the INSERT process.

When querying in the immuclient I can see the data in that field, it looks like that:
2022-06-23 09:04:37 (its not surrounded by " like VARCHAR fields)

But I can't find a way to get the data in Node,
When using SELECT * or SELECT created_at the value I get back is undefined (for other fields I do get the data, all of them are VARCHAR fields except the id which is INTEGER)

I've tried to use:
select CAST(created_at AS VARCHAR) and got SQLQuery error Error: 2 UNKNOWN: syntax error: unexpected CAST
CONVERT(VARCHAR, created_at) and select STR(created_at,10) and got SQLQuery error Error: 2 UNKNOWN: syntax error: unexpected '(',

What is the correct way to get the TIMESTAMP data back from the db?

If this question is not considered as an issue and doesn't belong here, sorry! just point me to the correct place to post this please :)

Thanks a lot,
Ziv.

client can be configured to keep the connection open indefinitely

Currently, inactive sessions are automatically closed by the server after a designated timeout period. By default, the timeout period is two minutes.

Provide configuration or a function that can be called periodically to ensure that the connection remains active. Possible implementation options include a keepAlive() function, or client configuration that accepts a keep alive flag. The implementation approach should be made consistent across SDK's.

What is the current proper way to set up parameters for a query ?

Hello, I'm trying to utilize the latest version, but I'm currently struggling to pass parameters to my query.
Doesn't matter what I do, I receive an stop application exception without stack.

My existing database script:

CREATE TABLE IF NOT EXISTS unit_area (
    serial_area VARCHAR(50),
    created VARCHAR(50),
    updated VARCHAR(50),
    label VARCHAR(50),
    format VARCHAR(50),
    decimal VARCHAR(50),
    PRIMARY KEY (serial_area)
);

My main class:

const dynamicImport = async (packageName: string) => new Function(`return import('${packageName}')`)(); 
import { QueryImmudb } from './database.dto';
import { SqlExecProps } from '@codenotary/immudb-node/dist/immu-api/sql-exec';
import { HttpStatus, Injectable } from '@nestjs/common'; 
@Injectable()
export class ImmudbService extends MainService {

    public async insertData(queryBuilder: QueryImmudb): Promise<boolean> {
        const con = await this.getConnection();
        try {
            this.logDebug("[ImmudbService] [insertData] INIT-->", { sql: queryBuilder.sql, params: queryBuilder.params });
            const tst = queryBuilder.getParams();
            console.log(tst)
            console.log(queryBuilder.sql)
            const sqlExecReq: SqlExecProps = {
                sql: queryBuilder.sql,
                params: [
                    {name: ':label', type: 'VARCHAR', value: 'TESTE'},
                    {name: ':format', type: 'VARCHAR', value: 'TESTE'},
                    {name: ':decimal', type: 'VARCHAR', value: 'TESTE'},
                       ]
            }; 
            const sqlExecRes = await con.sqlExec(sqlExecReq);

            this.logInfo("[ImmudbService] [insertData] SUCCESS:", sqlExecRes);
            return true;

        } catch (ex: any) {
            console.error(ex.message)
            throw new ErrorManager("ImmudbService-->insertData", ex.message,
                null, null, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

My QueryImmudb parameters:{

    const insertQuery = new QueryImmudb();
    insertQuery.sql = `
    INSERT INTO unit_date (
       serial_date,
       created ,
       updated,
       label,
       format,
       decimal
    )
    VALUES (
       ${'cast(random_uuid() as VARCHAR)'},
       cast( NOW() as VARCHAR) ,
       cast( NOW() as VARCHAR) ,
       :label,
       :format,
       :decimal
    )
 `;
 
 // Add the remaining parameters using addParams
 insertQuery.addParams('label', 'Date Label 1');
 insertQuery.addParams('format', 'YYYY-MM-DD');
 insertQuery.addParams('decimal', '2'); 
}

My QueryImmudb class:

export class QueryImmudb {

    sql: string;
    params: { name: string; type: string; value: any }[];

    constructor() {
        this.sql = '';
        this.params = [];
    }

    addParams(column: string, value: any, type: string = 'VARCHAR'): void {
        const param: { name: string; type: string; value: any } = {
            name: `:${column}`,
            type: type,
            value: value,   
        };
        this.params.push(param);
    }

    getParams(): any[] {
        return this.params.map(param => ({
            name: param.name,
            type: param.type, // Convert type to SqlType
            value: param.value,
        }));
    }
}

Error Require ES Module

Error [ERR_REQUIRE_ESM]: require() of ES Module \www\skeleton-api\node_modules@codenotary\immudb-node\dist\index.js from \www\skeleton-api\dist\src\app\app.service.js not supported.
Instead change the require of index.js in \www\skeleton-api\dist\src\app\app.service.js to a dynamic import() which is available in all CommonJS modules.

nest -v
9.1.5
node -v
v16.15.0

import { Client } from '@codenotary/immudb-node';
import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  async createTable(): Promise<void> {
    const client = new Client({
      host: '127.0.0.1',
      port: 3322,
      user: 'immudb',
      password: 'immudb',
      database: 'defaultdb',
    });
    const {
      subTxes: [{ tx: createTestTableTx }],
    } = await client.sqlExec({
      sql: `
        create table if not exists testtable (
            id1         integer not null,
            id2         varchar[3] null,
            created     timestamp null,
            data        varchar[512] not null,
            isActive    boolean not null,
            primary key (id1, id2)
        );
    `,
    });
    console.log('createTestTableTx:', createTestTableTx);
  }
}

Does immudb-node really support latest release?

Hi,

I was spending quite some time today figuring out why my node client always yielded corrupted data while the newest CLI client did not. Then I went ahead and simply installed the 1.1 version of immudb et voilà everything works.

Do I have to specify something for v1.3 to work?

Thanks!

TypeScript

Most of Node.js NoSQL db clients already have appropriate typings (mongoose, node-redis) or actually written in TypeScript (ioredis). I think this library is not an exception and it really needs some typings for a better development experience.

Better types

Is there any plans to improve the typings of the lib? Still having a hard time to grasp some concepts reading through immudb.io docs and the showcases of this library.

ImmudbClient is not a function

const ImmudbClient = require('immudb-node')
const config = {
address: '127.0.0.1:3322',
rootPath: '.',
}

ImmudbClient(config, (err, cl) => {
if (err) {
return console.log(err)
}

// Interact with the client.

})

Error handling when key is not present in db

What issue I am facing

Whenever I try to call await cl.get({key: 'somethingRandom'}) the code abruptly breaks, I have even wrapped it with try..catch block. But it never reaches catch block. The execution just stops and my node express server crashes.

My code setup & Steps to reproduce it

immudb.toml config file

dir = "./db"
network = "tcp"
address = "127.0.0.1"
port = 8001
dbname = "blockchain"
logfile = "./immudb.log"
pidfile = "./pid.log"
mtls = false
detached = false
auth = true
no-histograms = false
consistency-check = true
devmode = false
admin-password = "something"
maintenance = false
signingKey = ""
token-expiry-time = 5
web-server = true
web-server-port = 8002
pgsql-server = false
pgsql-server-port = 5432

config/db.js

const ImmudbClient = require('immudb-node')

const { DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD } = process.env

const cl = new ImmudbClient.default({
  host: DB_HOST,
  port: DB_PORT,
})

const connectImmuDB = async () => {
  try {
    const loginReq = { user: DB_USER, password: DB_PASSWORD }
    const loginRes = await cl.login(loginReq)
    console.log('immuDB connected', loginRes)
    const useDatabaseRes = await cl.useDatabase({ databasename: DB_NAME })
    console.log('success: useDatabase', useDatabaseRes)
  } catch (error) {
    console.error(error.message)
    process.exit(1)
  }
}

module.exports = { connector: connectImmuDB, cl }

utils/dbmethods.js

const { cl, connector } = require('../config/db')

// check if key exists
const isKeyPresent = async (key) => {
  try {
    await connector()
    let value = await cl.get({ key: key })      // This is the point where it tries to get value first time & things break if key doesnot exists in DB
    if (value) {
      return true 
    }
    return false
  } catch (err) {
    return false         // Execution context never reaches here
  }
}

const retrieveKeyValue = async (key) => {
  try {
    let isPresent = await isKeyPresent(key)
    if (isPresent) {
      let valueObj = await cl.get({ key: key })
      return valueObj
    }
    return undefined
  } catch (err) {
    return err.message
  }
}

module.exports = {
  retrieveKeyValue,
}

server.js

require('dotenv').config()
const express = require('express')
const { retrieveKeyValue } = require('./utils/dbmethods')
const app = express()

const { connector } = require('./config/db')
connector()

// Body parser
app.use(express.json({ extended: false }))

// Testing route
app.get('/:key', async (req, res) => {
  const respObj = { msg: 'ImmuDB Retrieve Data', success: false }
  const { key } = req.params
  try {
    const oldData = await retrieveKeyValue(key)
    if (oldData) {
      return res.status(200).json({ ...respObj, success: true, content: oldData })
    }
    return res.status(404).json({
      ...respObj,
      errors: [{ msg: `key ${key} doesnot exists` }],
    })
  } catch (err) {
    if (err.code) {
      return res.status(404).json({ ...respObj, errors: [{ msg: err.details, code: err.code }], })
    }
    return res.status(500).json({ ...respObj, errors: [{ msg: 'Server Error' }] })
  }
})


// Start server on PORT
const PORT = process.env.PORT
app.listen(PORT, () => {
  console.log(`Server started in port ${PORT}`)
})

package.json

{
  "name": "immudb-blockchain",
  "version": "1.0.0",
  "description": "Immudb based REST endpoints",
  "main": "server.js",
  "scripts": {
    "server": "nodemon server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "nodemon": "^2.0.7"
  },
  "dependencies": {
    "dotenv": "^10.0.0",
    "express": "^4.17.1",
    "immudb-node": "^1.0.10-rc.6"
  }
}

As you can see I have created a separate function two safely findout if key is present or not. But the execution context never reaches catch block, it fails before that. Please note everything works fine if key-value pair is present in db.

Error Message

Get error Error: 2 UNKNOWN: key not found
    at Object.callErrorFromStatus (/Users/xeuser/Desktop/node-express-immuDB/backend/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
    at Object.onReceiveStatus (/Users/xeuser/Desktop/node-express-immuDB/backend/node_modules/@grpc/grpc-js/build/src/client.js:176:52)
    at Object.onReceiveStatus (/Users/xeuser/Desktop/node-express-immuDB/backend/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:334:141)
    at Object.onReceiveStatus (/Users/xeuser/Desktop/node-express-immuDB/backend/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:297:181)
    at /Users/xeuser/Desktop/node-express-immuDB/backend/node_modules/@grpc/grpc-js/build/src/call-stream.js:129:78
    at processTicksAndRejections (internal/process/task_queues.js:75:11) {
  code: 2,
  details: 'key not found',
  metadata: Metadata { internalRepr: Map(0) {}, options: {} }
}

Version

immudb version
immudb 1.0.0
Commit  : fb5398fe7b7d69dd352685d477fbd01a86b64568
Built by: [email protected]
Built at: Fri, 21 May 2021 16:29:30 IST

login and useDatabase should be globally configured

it looks a bit weird to call login every time we need to do operations. having client interface logged in on a global level would be more helpful so that we can export it and use it in different places.

Current:

Having no flexibility to export logged in instance

    const client = new ImmudbClient({
        host: '127.0.0.1',
        port: '3322',
        // rootPath: 'rootfile'
    });
    const main = async() => {
         // asking for login. but login should be on global level.
         const loginRes = await client.login({ user: 'immudb', password: 'immudb' })
         console.log('success: login', loginRes)

         const useDatabaseRes = await client.useDatabase({ databasename: 'immudbdev' })
         console.log('success: use database',useDatabaseRes)

        const getRes = await client.get({ key: 'key1' });
        console.log('get res: ', getRes);
}

Expected: (Like how sequelize's authentication works)

db/connector.js
const client = new ImmudbClient({
    host: '127.0.0.1',
    port: '3322',
   database: 'immudb',
    rootPath: 'rootfile'
});
client.login({ user: 'immudb', password: 'immudb' })
    .then(() => { console.log('login success') })
    .catch(err => { console.log('login failed', err) });

export default client;
src/app.js
import client from './db/connector';

const getByKey = async()=>{
   // we shouldn't need to login again
    return client.get({ key: 'key1' });
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.