ibmdb / node-ibm_db

IBM DB2 and IBM Informix bindings for node
MIT License
188 stars 151 forks source link

Still having problems using node ibm_db with node v18.9 and electron 20.1 #882

Closed markddrake closed 1 year ago

markddrake commented 1 year ago

Using the latest node and ibm_db@v3.0.0

C:\Development\YADAMU\src>node -v
v18.9.0

C:\Development\YADAMU\src> npm uninstall ibm_db

removed 33 packages, and audited 781 packages in 2s

45 packages are looking for funding
  run `npm fund` for details

5 vulnerabilities (1 low, 4 moderate)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

C:\Development\YADAMU\src>npm install ibm_db@latest

added 33 packages, and audited 814 packages in 24s

45 packages are looking for funding
  run `npm fund` for details

5 vulnerabilities (1 low, 4 moderate)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

C:\Development\YADAMU\src>node  scratch\db2\BlankPaddingArray.js
[]
[]
{
  sql: 'insert into VARCHAR_TAB (VC30) values (?)',
  params: [
    {
      ParamType: 'ARRAY',
      SQLType: 1,
      Data: [ 'Alberta', 'A', 'AA', ' ', '' ],
      Length: 10
    }
  ],
  ArraySize: 5
}
[]
[
  { VC30: 'Alberta', LEN: 7 },
  { VC30: 'A', LEN: 1 },
  { VC30: 'AA', LEN: 2 },
  { VC30: ' ', LEN: 1 },
  { VC30: '', LEN: 0 }
]
success

Everything works as expected.

However I need to be able to use both node and electron from the same environment If I load the version of idb_db with the electron flag and repeat the same test I get

C:\Development\YADAMU\src> npm uninstall ibm_db

removed 33 packages, and audited 781 packages in 1s

45 packages are looking for funding
  run `npm fund` for details

5 vulnerabilities (1 low, 4 moderate)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

C:\Development\YADAMU\src> npm install ibm_db@latest -electron=20.1.0

added 33 packages, and audited 814 packages in 12s

45 packages are looking for funding
  run `npm fund` for details

5 vulnerabilities (1 low, 4 moderate)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

C:\Development\YADAMU\src>node  scratch\db2\BlankPaddingArray.js
node:internal/modules/cjs/loader:1203
  return process.dlopen(module, path.toNamespacedPath(filename));
                 ^

Error: The module '\\?\C:\Development\YADAMU\src\node_modules\ibm_db\build\Release\odbc_bindings.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 107. This version of Node.js requires
NODE_MODULE_VERSION 108. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).
    at Module._extensions..node (node:internal/modules/cjs/loader:1203:18)
    at Module.load (node:internal/modules/cjs/loader:997:32)
    at Module._load (node:internal/modules/cjs/loader:838:12)
    at Module.require (node:internal/modules/cjs/loader:1021:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at bindings (C:\Development\YADAMU\src\node_modules\bindings\bindings.js:112:48)
    at Object.<anonymous> (C:\Development\YADAMU\src\node_modules\ibm_db\lib\odbc.js:57:31)
    at Module._compile (node:internal/modules/cjs/loader:1119:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1173:10)
    at Module.load (node:internal/modules/cjs/loader:997:32) {
  code: 'ERR_DLOPEN_FAILED'
}

Node.js v18.9.0

C:\Development\YADAMU\src>

My electron version is

C:\Development\YADAMU\src>node_modules\.bin\electron.cmd -v

v20.1.0

Is there a way to configure my environment so I can run node applications and electron applications?. I have a primarily command and server-based application, that can also be used using an electron-based user interface.

bimalkjha commented 1 year ago

@markddrake Electron uses its own node.js embedded with electron having own NODE_MODULE_VERSION which is always different from NODE_MODULE_VERSION of system wide Node.js. You can check NODE_MODULE_VERSION for Electron and Node.js here: https://github.com/nodejs/node/blob/master/doc/abi_version_registry.json For electron v20.x, NODE_MODULE_VERSION is 107 and for Node.js V18.x, NODE_MODULE_VERSION is 108. So, basically you have two Node.js environments. One that comes with electron and other the system wide node.js (v18.x). You can not compile a node-add on for electron and use with system Node.js and vice-versa. It is how electron works. So, the behavior observed by you is correct. If ibm_db is installed for electron, you can use it only with electron applications like VSCode. You can not use it with normal Node.js applications. If ibm_db is installed for node.js application, you can not use it for electron application. You need to find a way to use the embedded node.js of electron as library and use it. Probably info on this page help you: https://www.electronjs.org/blog/electron-internals-using-node-as-a-library The behavior observed by you is explained on this page in detail: http://blog.cinan.sk/2018/02/22/integrate-native-node-dot-js-modules-into-an-electron-app-1-slash-2/ Thanks.

markddrake commented 1 year ago

I assume this is a side effect of ibm_db using ODBC under the covers, and all the other databases using a more 'node native' transport protocol?.

Is there anyway that you are aware of to have both versions of ibm_db installed in different location and configure node to look in one location and electron to look in another ?

Other wise I guess I need to pick up a node version that using NODE_MODULE_VERSION 107 for this to work.

markddrake commented 1 year ago

I think I can do something like this

npm install ibm_db_electron@npm:ibm_db -electron=20.1.0

And then use a conditional import to load the electron version of the package when running under electron. Will need to experiment further

markddrake commented 1 year ago

And then dynamically load ibm_db as follows

  async testConnection() {   
    const ibmdb = await ( import(process.versions.hasOwnProperty('electron') ? "ibm_db_electron" : "ibm_db"))
    const stack = new Error().stack
    const connection = await new Promise((resolve,reject) => {
      ibmdb.open(this.createConnectionString(),(err,conn) => {
        if (err) reject(new DB2Error(this.DRIVER_ID,err,stack,'DB2.open()'))
        resolve(conn)
      })
    })
    return connection
  }