{"analyzedAt":"2023-01-10T15:22:28.831Z","collected":{"metadata":{"name":"@sap/hdbext","scope":"sap","version":"7.7.1","description":"Hana-client extension library and utility functions for using SAP HANA in node.js","keywords":["HDB","hana","sap","sql","hdi"],"date":"2023-01-10T08:40:26.790Z","publisher":{"username":"sap_extncrepos","email":"mob.extrepo.stores@sap.com"},"maintainers":[{"username":"sap_extncrepos","email":"mob.extrepo.stores@sap.com"}],"repository":{"type":"git"},"links":{"npm":"https://www.npmjs.com/package/%40sap%2Fhdbext"},"dependencies":{"@sap/e2e-trace":"^3.1.0","@sap/hana-client":"2.15.19","accept-language":"2.0.16","async":"3.2.2","debug":"4.3.1","lodash":"4.17.21","verror":"1.10.0"},"devDependencies":{"chai":"3.5.0","eslint":"4.8.0","express":"4.14.0","filter-node-package":"2.2.0","istanbul":"0.4.5","mocha":"3.0.2","node-style":"2.0.0","proxyquire":"1.7.10","sinon":"1.17.5","supertest":"2.0.0"},"releases":[{"from":"2022-12-11T00:00:00.000Z","to":"2023-01-10T00:00:00.000Z","count":0},{"from":"2022-10-12T00:00:00.000Z","to":"2023-01-10T00:00:00.000Z","count":4},{"from":"2022-07-14T00:00:00.000Z","to":"2023-01-10T00:00:00.000Z","count":6},{"from":"2022-01-10T00:00:00.000Z","to":"2023-01-10T00:00:00.000Z","count":10},{"from":"2021-01-10T00:00:00.000Z","to":"2023-01-10T00:00:00.000Z","count":19}],"hasTestScript":true,"hasSelectiveFiles":true,"readme":"@sap/hdbext\n============\n\nThis package provides convenient functions on top of the *@sap/hana-client* module.\n\nThe [change log](CHANGELOG.md) describes notable changes in this package.\n\n## Usage\n\n```js\nvar hdbext = require('@sap/hdbext');\n```\n\n## API\n\n### createConnection(hanaConfig, callback)\n\nCreates a connection to a HANA database:\n\n```js\nvar hanaConfig = {\n  host     : 'hostname',\n  port     : 30015,\n  user     : 'user',\n  password : 'secret'\n};\nhdbext.createConnection(hanaConfig, function(error, client) {\n  if (error) {\n    return console.error(error);\n  }\n\n  client.exec(...);\n});\n```\n\nThe `hanaConfig` argument contains [database connection options](#database-connection-options) and [additional options](#additional-options).\nThe callback provides a connected `client` object.\n\nIf the application will be deployed on Cloud Foundry or XS Advanced, you can use _@sap/xsenv_ package to\nlookup the bound HANA service, like this:\n```js\nvar xsenv = require('@sap/xsenv');\n\nvar hanaConfig = xsenv.cfServiceCredentials({ tag: 'hana' });\nhdbext.createConnection(hanaConfig, function(error, client) {\n  //...\n});\n```\n\n#### Database connection options\n\nThe HANA options provided to *@sap/hdbext* should be in the same format as expected by the *@sap/hana-client* package.\n\nFor convenience these properties set by the HANA service broker are also accepted:\n* `schema` - can be used instead of the `currentSchema` property of *@sap/hana-client*.\n* `db_hosts` - can be used instead of the `hosts` property of *@sap/hana-client*.\n* `certificate` - can be used instead of `ca` property of *@sap/hana-client*.\n__Note:__ `certificate` is a string containing one certificate, while `ca` is an array of certificates.\n* `hostname_in_certificate` - can be used instead of `sslHostNameInCertificate` property of *@sap/hana-client*.\n* `validate_certificate ` - can be used instead of `sslValidateCertificate` property of *@sap/hana-client*. The default value is `true`.\n* `client_authentication_certificate` - can be used instead of `cert` property of *@sap/hana-client*.\n* `client_authentication_private_key` - can be used instead of `key` property of *@sap/hana-client*. \n\n#### Additional options\n\nA connection created with *@sap/hdbext* can be further configured with the following options:\n\nOption   | Type | Description\n-------- | ---- | -----------\n`autoCommit` | boolean | Sets the autoCommit flag. If no option is specified it defaults to `true`.\n\n**Note**: the *@sap/hana-client* package also accepts other configurations like `isolationLevel` (one can use the isolation level constants in `require('@sap/hana-client/extension/Enums')`), `locale` and `sessionVariable:<name-of-the-session-variable>`.\n\n##### Special session variables\n\nSome session variables are handled in a special way.\n\n* `XS_APPLICATIONUSER` - can be set to a user token (SAML/JWT) to associate the application user with the database connection\n* `SAP_PASSPORT` - used to propagate SAP passport to SAP HANA, used for end-to-end tracing\n* `APPLICATION` - the name of the application initiating the database connection\n\n**Note**: If providing the `SAP_PASSPORT` session variable, the SAP Passport in\nit should have already been updated with data, specific to the component that consumes *@sap/hdbext*.\nFor more information, see the documentation of the *@sap/e2e-trace* package.\n\n#### Example\n\nSample configuration with both [database connection options](#database-connection-options) and [additional options](#additional-options):\n\n```js\nvar enums = require('@sap/hana-client/extension/Enums');\n\n{\n  host: 'my.host',\n  port: 30015,\n  user: 'my_user',\n  password: 'secret',\n  schema: 'name_of_the_schema',\n  isolationLevel: enums.SERIALIZABLE,\n  locale: 'en_US',\n  autoCommit: false,\n  'sessionVariable:APPLICATION': 'myapp',\n  'sessionVariable:SAP_PASSPORT': 'passport'\n}\n```\n\n### connectionOptions.getGlobalOptions()\n\nReturns an object with the following properties:\n* `sessionVariable:APPLICATION` - extracted from VCAP_APPLICATION, fallbacks to process's pid and machine's hostname.\n* `sessionVariable:APPLICATIONVERSION` - extracted from package.json in current directory. May not be present if the file is not present or not in valid JSON format.\n\n### connectionOptions.getRequestOptions(req)\n\nReturns an object with the following properties, based on the given HTTP request (_req_):\n* `sessionVariable:SAP_PASSPORT` - may not be present if the SAP Passport header is not present. The passport is updated with default component data.\n* `sessionVariable:XS_APPLICATIONUSER` - only present for authenticated requests that do not use client credentials token.\n* `locale` - only present if _req_ has either a `x-sap-request-language` or `accept-language` header.\n\n### loadProcedure(client, schemaName, procedureName, callback)\n\n*@sap/hdbext* provides functionalities to simplify stored procedure calls.\n\nFor example, if you have the following stored procedure:\n\n```sql\ncreate procedure PROC_DUMMY (in a int, in b int, out c int, out d DUMMY, out e TABLES)\n  language sqlscript\n  reads sql data as\n  begin\n    c := :a + :b;\n    d = select * from DUMMY;\n    e = select TOP 3 * from TABLES;\n  end\n```\n\nyou can call it via the *@sap/hana-client* package in the following way:\n\n```js\nvar dbStream = require('@sap/hana-client/extension/Stream');\ndbStream.createProcStatement(client, 'CALL PROC_DUMMY (?, ?, ?, ?, ?)', function (err, stmt) {\n  if (err) {\n    return console.error('createProcStatement error:', err);\n  }\n\n  stmt.exec({ A: 3, B: 4 }, function (err, params, dummyRows, tablesRows) {\n    if (err) {\n      return console.error('exec error:', err);\n    }\n\n    stmt.drop(function (err) {\n      if (err) {\n        return console.error('drop error:', err);\n      }\n\n      console.log('C:', params.C);\n      console.log('Dummy rows:', dummyRows);\n      console.log('Tables rows:', tablesRows);\n    });\n  });\n});\n```\n\nWith *@sap/hdbext* you don't need to construct a `CALL` statement. The procedure can be loaded by its name.\nThe code can look like this:\n\n```js\nhdbext.loadProcedure(client, null, 'PROC_DUMMY', function(err, sp) {\n  sp({ A: 3, B: 4 }, function(err, parameters, dummyRows, tablesRows) {\n    if (err) {\n      return console.error(err);\n    }\n\n    console.log('C:', parameters.C);\n    console.log('Dummy rows:', dummyRows);\n    console.log('Tables rows:', tablesRows);\n  });\n});\n```\n\nTo use the current schema, pass an empty string `''`, `null` or `undefined` for schema.\n\n`loadProcedure(client, schemaName, procedureName, callback)` returns a JavaScript function which you can call directly.\nThe function has the `paramsMetadata` property containing metadata for all parameters of the stored procedure.\nThis could be useful if you need to implement generic stored procedures calling.\n\nYou can also pass the input parameters directly in the proper order:\n\n```js\nsp(3, 4, function(err, parameters, dummyRows, tableRows) {\n  // ...\n});\n```\n\nor as an array:\n\n```js\nsp([3, 4], function(err, parameters, dummyRows, tableRows) {\n  // ...\n});\n```\n\nWhere the big advantage comes in is with table parameters.\nYou can pass an array of objects and *@sap/hdbext* will automatically convert it into a table parameter.\nSay we have a `customer` table with `ID` and `NAME` columns and a procedure:\n\n```sql\ncreate table \"customer\" (ID integer, NAME VARCHAR(100), primary key (ID));\n\ncreate procedure \"getCustomers\" (in in_table_1 \"customer\")\nlanguage sqlscript reads sql data as begin\nselect * from :in_table_1;\nend;\n```\n\nYou can call it like this:\n\n```js\nhdbext.loadProcedure(client, null, 'getCustomers', function (err, sp) {\n  if (err) {\n    return console.error(err);\n  }\n\n  sp([\n    { ID: 1, NAME: 'Alex' },\n    { ID: 2, NAME: 'Peter' }\n  ], function (err, parameters, tableRows) {\n    if (err) {\n      return console.error(err);\n    }\n\n    console.log(parameters);\n    console.log(tableRows);\n  });\n});\n```\n\nIn this example each array element represents a table row. Property names should case-sensitively match the corresponding column names.\n\nInternally *@sap/hdbext* creates a local temporary table in the current schema for each table parameter.\nThus, the current user needs the respective permissions.\n\nIt is also possible to explicitly state an existing table to be used as input table parameter:\n\n```js\n  sp({ schema: 'my-schema', table: 'my-table' }, function (err, parameters, tableRows) {\n    // ...\n  });\n```\n\nThe `schema` property is optional.\n\nEvery output table has a `columnInfo` property which contains info about each of the table's columns.\n\nInput arguments for parameters that have default values can be skipped in order to use the defined defaults.\nIt is recommended to pass the input as an object in those cases. In this way the application code would be independent\nfrom the order in which parameters with default values are defined in the procedure.\nWhen the parameters are passed in a sequence (i.e. as an array or are passed directly in the proper order),\ninput arguments can be skipped only for the parameters which are after the last mandatory parameter in the procedure's list.\n\n### Middleware\n\n*@sap/hdbext* provides a middleware which allows easy database connection creation in a middleware-based application.\nThe `close` method of the database client is invoked when the request is closed or finished.\n\n```js\nvar hdbext = require('@sap/hdbext');\nvar express = require('express');\n\nvar app = express();\napp.use(hdbext.middleware(hanaConfig));\n\napp.get('/execute-query', function (req, res) {\n  var client = req.db;\n\n  client.exec('SELECT * FROM DUMMY', function (err, rs) {\n    if (err) {\n      return res.end('Error: ' + err.message);\n    }\n\n    res.end(JSON.stringify(rs));\n  });\n});\n```\n\nThe argument `hanaConfig` may contain both [database connection options](#database-connection-options) and [additional options](#additional-options).\n\nThe middleware uses [connectionOptions.getGlobalOptions()](#connectionoptionsgetglobaloptions) and [connectionOptions.getRequestOptions(req)](#connectionoptionsgetrequestoptionsreq) for extracting options. It is possible for applications to override the default global options by setting them explicitly in `hanaConfig`.\n\n### SQL Parameter Utilities\n\nThe `hdbext.sqlInjectionUtils` object contains several synchronous utility functions that can be used to prevent SQL injections.\n\n#### isAcceptableParameter(value, maxToken)\n\nReturns true if `value` can be used to construct SQL statements.\nThe number of tokens a value is allowed to contain is set via the optional `maxToken` argument. Defaults to 1.\n\n#### isAcceptableQuotedParameter(value)\n\nReturns true if the provided `value` is quoted correctly and can be used in an SQL statement.\n\n#### escapeDoubleQuotes(value)\n\nReturns the `value` parameter with all double quotation marks escaped (i. e. doubled).\n\n#### escapeSingleQuotes(value)\n\nReturns the `value` parameter with all single quotation marks escaped (i. e. doubled).\n\n## Troubleshooting\n\nTo enable tracing, you should set the environment variable `DEBUG` to `hdbext:*`.\n\n## Migration guide\n\nGuide on how to adopt new major versions of the library can be found [here](./migration.md)."},"npm":{"downloads":[{"from":"2023-01-09T00:00:00.000Z","to":"2023-01-10T00:00:00.000Z","count":3557},{"from":"2023-01-03T00:00:00.000Z","to":"2023-01-10T00:00:00.000Z","count":16053},{"from":"2022-12-11T00:00:00.000Z","to":"2023-01-10T00:00:00.000Z","count":68446},{"from":"2022-10-12T00:00:00.000Z","to":"2023-01-10T00:00:00.000Z","count":258550},{"from":"2022-07-14T00:00:00.000Z","to":"2023-01-10T00:00:00.000Z","count":529646},{"from":"2022-01-10T00:00:00.000Z","to":"2023-01-10T00:00:00.000Z","count":1024143}],"starsCount":0},"source":{"files":{"readmeSize":11139,"testsSize":0,"hasShrinkwrap":true,"hasChangelog":true},"linters":["eslint"],"outdatedDependencies":{"verror":{"required":"1.10.0","stable":"1.10.1","latest":"1.10.1"},"accept-language":{"required":"2.0.16","stable":"3.0.18","latest":"3.0.18"},"async":{"required":"3.2.2","stable":"3.2.4","latest":"3.2.4"},"debug":{"required":"4.3.1","stable":"4.3.4","latest":"4.3.4"}}}},"evaluation":{"quality":{"carefulness":0.6699999999999999,"tests":0,"health":0.5,"branding":0},"popularity":{"communityInterest":0,"downloadsCount":86183.33333333333,"downloadsAcceleration":-96.93283866057845,"dependentsCount":0},"maintenance":{"releasesFrequency":1,"commitsFrequency":0,"openIssues":0,"issuesDistribution":0}},"score":{"final":0.28300412941590114,"detail":{"quality":0.4463685935706945,"popularity":0.09264824193721755,"maintenance":0.3333333333333333}}}