Giter Site home page Giter Site logo

loopback-connector's Introduction

LoopBack Connector

CI

LoopBack Connector is a set of building blocks simplifying implementation of datasource-specific connectors like Oracle, MongoDB, REST.

For full documentation, see the official LoopBack documentation:

Installation

npm install loopback-connector

Usage

See loopback-connector-mysql for an example of connector using this module.

loopback-connector's People

Contributors

0candy avatar aaqilniz avatar achrinza avatar agnes512 avatar amir-61 avatar b-admike avatar bajtos avatar candytangnb avatar dhmlau avatar eugene-frb avatar ewrayjohnson avatar jannyhou avatar kallenboone avatar kjdelisle avatar lehni avatar loay avatar nabdelgadir avatar raymondfeng avatar renovate-bot avatar renovate[bot] avatar rmg avatar sam-github avatar samarpanb avatar setogit avatar shubhamp-sf avatar siddhipai avatar ssh24 avatar superkhau avatar virkt25 avatar yosimasu 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

Watchers

 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

loopback-connector's Issues

Automigrate & Autoupdate should use async.eachSeries

Suggestion

I'm running into issues with Loopback 4's migrateSchema() where it doesn't create tables in a predictable order. The docs indicate you can specify the order tables are created for Postgres: https://loopback.io/doc/en/lb4/todo-list-tutorial-sqldb.html

In my testing both automigrate() & autoupdate() use async.each which runs queries in parallel. I believe these should be rewritten to use async.eachSeries.

https://github.com/strongloop/loopback-connector/blob/master/lib/sql.js#L78

https://github.com/strongloop/loopback-connector/blob/master/lib/sql.js#L1607

Use Cases

Run table migrations in predictable order to eliminate missing relationship errors like relation "public.relationalTableName" does not exist. I believe this could be as simple as rewriting async.each to be async.eachSeries.

I'm happy to submit a PR if the maintainers thought this was an acceptable solution.

Acceptance criteria

TBD - will be filled by the team.

automigrate fails with foreign keys (on postgresql)

Steps to reproduce

  • Create two models A and B and a foreign key referencing from model B to model A
  • Pass the model order [A, B] to migrateSchema
  • Run migrateSchema({ existingSchema: 'drop' ... }) to create tables the first time
  • Run migrateSchema({ existingSchema: 'drop' ... }) to recreate

Current Behavior

When recreating, the tables are dropped and created table-by-table, so dropping table A will fail as there is a reference from table B.

Expected Behavior

One of:

  • dropping all foreign keys before recreating tables
  • dropping tables cascading
  • drop all tables in reverse order before recreating

Related Issues

#175

4.6.0 revert causes tests to fail

hello people, our tests are failing because the test suite can't find [email protected]. I saw that you reverted the release but while we are not directly using the loopback-connector in package.json, it's a dependency of a dependency (another loopback package I presume) and they use version 4.6.0 so it ends up in our package-lock.json.

The only workaround I found so far is to declare last version of loopback-connector ( v4.5.1) explicitly in package.json but I don't want to do it as it's not direct dependency.

Do you have another workaround to fix this ?

do you have an example, how to work email connector ?

datasources.json

"emailGoogle": {
    "name": "mail",
    "defaultForType": "mail",
    "connector": "mail",
    "transports": [
        {
            "type": "SMTP",
            "host": "smtp.gmail.com",
            "secure": true,
            "port": 465,
            "auth": {
                "user": "[email protected]",
                "pass": "XXXX"
            }
        }
    ]
}    

config-model.json

"Email": {
    "dataSource": "emailGoogle"
}

email.json

{
"name": "Email",
"base": "Model",
"properties": {
"to": {"type": "String", "required": true},
"from": {"type": "String", "required": true},
"subject": {"type": "String", "required": true},
"text": {"type": "String"},
"html": {"type": "String"}
}
}

email.js

module.exports = function(Email) {

// send an email

Email.sendEmail = function(cb) {
    Email.app.models.Email.send({
        to: '[email protected]',
        from: '[email protected]',
        subject: 'my subject',
        text: 'my text',
        html: 'my <em>html</em>'
    }, function(err, mail) {
        console.log('email sent!');
        cb(err);
    });
}

};

1
I don't view, the explorer api ?

2
I dont know, how to send an email !!!

http://localhost:3000/api/email/sendEmail

ror: {
name: "Error",
status: 404,
message: "There is no method to handle GET /email/sendEmail",
statusCode: 404,

Regards
Eduardo

loopback-connector-redis and include filter

there are no way to submit a bug in the loopback-connector-redis github project so i will submit it here.

I'm trying to create a hasOne relation between a mysql table with a model that uses a redis connector.

When you are querying only 1 element it works but when you query several elements, the redis indexes doesnt work properly and then return only the result of the first table without the relation.

I know that this connector are not for production enviroments but at least you sould accept bugs in that github.

Thank you for this awsome product.

edit: i fixed it creating the other way round relation. now I have a belongsTo in the redis side and this works.

Error on camelCase properties in autoupdate

Description/Steps to reproduce

  • Latest loopback-connector (4.6.0)
  • Run autoupdate procedure with AccessToken (for example) in model config. Anything else with camelCase properties will work as well.

The following error occurs:

Error: Invalid property path
    at Function.Connector.getNestedPropertyDefinition (/Users/simon/Projects/APPICS/src/appics-backend/node_modules/loopback-connector/lib/connector.js:159:11)
    at PostgreSQL.Connector.getPropertyDefinition (/Users/simon/Projects/APPICS/src/appics-backend/node_modules/loopback-connector/lib/connector.js:139:20)
    at PostgreSQL.SQLConnector.column (/Users/simon/Projects/APPICS/src/appics-backend/node_modules/loopback-connector/lib/sql.js:376:19)
    at /Users/simon/Projects/APPICS/src/appics-backend/node_modules/loopback-connector/lib/sql.js:157:27
    at Array.forEach (<anonymous>)
    at PostgreSQL.SQLConnector.searchForPropertyInActual (/Users/simon/Projects/APPICS/src/appics-backend/node_modules/loopback-connector/lib/sql.js:156:16)
    at /Users/simon/Projects/APPICS/src/appics-backend/node_modules/loopback-connector-postgresql/lib/migration.js:159:24
    at Array.forEach (<anonymous>)

In this case the reason is the principalType property, which is converted to principaltype at some point and consequentially is no longer found at this point in the code.

I reverted to 4.5.1 and the problem disappeared.

Ability to add Dynamic Request Headers

I should be able to add / manipulate request headers in a remote method . In my data source file, I've defined a data source with some default headers
"headers": {
"accepts": "application/json",
"content-type": "application/json"
}

I've also defined an operation (template (POST) + function) in the operations array. Now I have a remote method that uses this operation. How do I add two dynamic headers in the remote method. Even if I add them to the ctx.req object , they don't seem to make their way in the request that hits the backend.I tried this with loopback.getCurrentContext(). Is it even possible to add/manipulate request headers in loopback ? The backend seems to be fine. If I use some client say, POSTMAN , it does work with proper headers. I pass the context as the http source in the remote method definition and access the body using 'ctx.req.body'. If I hard-code some values for these headers in the data source itself, it works. But I need them to be dynamic.

Loopback process exit if JSON.parse throw error.

Description/Steps to reproduce

From sandbox

  1. run 'setup.mysql.sh' script to create mysql docker container.
  2. start loopback by npm start
  3. goto http://localhost:3000/explorer/#!/message/message_create and POST new message with {"body":"text"}
  4. open /server/models/message.json and change 'body' property type to 'object'
  5. restart loopback
  6. goto http://localhost:3000/explorer/#!/message/message_find
    then Loopback process will exit and console will show.
/Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/mysql/lib/protocol/Parser.js:80
        throw err; // Rethrow non-MySQL errors
        ^

SyntaxError: Unexpected token s in JSON at position 0
    at JSON.parse (<anonymous>)
    at MySQL.fromColumnValue (/Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-connector-mysql/lib/mysql.js:452:22)
    at MySQL.SQLConnector.fromRow.SQLConnector.fromDatabase (/Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-connector/lib/sql.js:1414:28)
    at /Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-connector/lib/sql.js:1446:19
    at Array.map (native)
    at /Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-connector/lib/sql.js:1445:21
    at /Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-datasource-juggler/lib/observer.js:172:22
    at doNotify (/Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-datasource-juggler/lib/observer.js:99:49)
    at MySQL.ObserverMixin._notifyBaseObservers (/Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-datasource-juggler/lib/observer.js:122:5)
    at MySQL.ObserverMixin.notifyObserversOf (/Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-datasource-juggler/lib/observer.js:97:8)
    at cbForWork (/Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-datasource-juggler/lib/observer.js:162:14)
    at /Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-connector/lib/sql.js:643:7
    at handleResponse (/Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-connector-mysql/lib/mysql.js:193:17)
    at Query._callback (/Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/loopback-connector-mysql/lib/mysql.js:204:7)
    at Query.Sequence.end (/Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/mysql/lib/protocol/sequences/Sequence.js:88:24)
    at Query._handleFinalResultPacket (/Users/phuttipong.aim/Documents/loopback-sandbox/node_modules/mysql/lib/protocol/sequences/Query.js:139:8)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `babel-node .`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

Expected result

Loopback process do not exit.

Additional information

darwin x64 8.1.4

[email protected] /Users/phuttipong.aim/Documents/loopback-sandbox
├─┬ [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├── [email protected]
├─┬ [email protected]
├─┬ [email protected]
│ ├── [email protected]
├─┬ [email protected]
│ ├── [email protected]
├─┬ [email protected]
│ ├── [email protected]

unbound parameter error

I try to use the CRUD operation methods for example create method but it throws the error as follows

SQL: INSERT INTO "PostWithNumId"("id","title","content") VALUES(?,?,?), params: [1000,"ab","AAAB"] +5ms Error: {"message":"not all variables bound: unbound parameter : 1 of 3, 1 out of 1 batches","code":340,"sqlState":"HY000","level":1,"position":0} +5ms

This error appears only when passing the parameters for all the CRUD methods, not for the simple statements
Can anyone help to resolve this issue @bajtos @raymondfeng

Model is re-created despite existence check

Needless to say, I'm using loopback-connector for writing a new connector.

In my connector, I try to create users and the first time it works reasonably well but the second time I can see calls to prototype.all() with a where clause like: { where: { email: '[email protected]' } } and upon returning a response to the loopback-connector's callback method ... it still goes ahead and makes another prototype.create() call.

You can run the example from: https://github.com/ShoppinPal/loopback-connector-elastic-search to see this problem in action.

Request to add the ability to modify the context in a connector hook

Please provide the ability to modify the query in the connector hook through the context object. I.e. use the passed in context object for the parameters when executingSQL in notifyObserversAround rather than using the parameter definitions from the closure.

I am using this in the MySQL connector to patch up the generated SQL queries with SQL calculated properties. I.e. to work around being able to generate JOINs and using Aggregates.

I can submit an example or pull request if desired.

Thank you,

Frank.

`Connector.prototype.isRelational` returns a function

Steps to reproduce

Call new Connector(/*...*/).isRelational()

Offending line:

return this.isRelational ||
(this.getTypes().indexOf('rdbms') !== -1);

Current Behavior

It returns itself (a function), which then requires a 2nd call to get the expected boolean value.

Expected Behavior

Connector.prototype.isRelational should strictly return a boolean.

Link to reproduction sandbox

N/A

Additional information

Related Issues

See Reporting Issues for more tips on writing good issues

Problems with API docs

In http://apidocs.strongloop.com/loopback-connector/, API docs for base Connector and SQLConnector are missing even though docs.json has:

{
      "title": "Base Connector",
      "depth": 2
    },
    "lib/connector.js",
    {
      "title": "SQL Connector",
      "depth": 2
    },
    "lib/sql.js",
    "lib/parameterized-sql.js"

However docs for ParameterizedSQL seem to be displayed correctly.

So, something's wrong / broken, but it's not obvious what.

@superkhau @richardpringle @hacksparrow If you can give me an idea of what's going on, I will fix it, but I'm at something of a loss.

sql.js creates invalid SQL if columns in an and/or filter are invalid

Description/Steps to reproduce

Use this filter on a model connected to a RDBMS (assuming asd and dsa are not columns, and that id is) and you will cause an SQL syntax error.

{"where": {"id": 1, "and": [{"asd": 1}, {"dsa": 2}]}}

Link to reproduction sandbox

  "db": {
    "host": "localhost",
    "database": "postgres",
    "password": "mysecretpassword",
    "name": "db",
    "user": "postgres",
    "connector": "postgresql"
  }

https://github.com/marvinirwin/loopback-sandbox/tree/empty-where

Expected result

Loopback ignores unknown columns in the where statement by convention. It should ignore and/or with all invalid columns as well.

Additional information

https://github.com/strongloop/loopback-connector/blob/master/lib/sql.js#L1163
These are the guilty statements.

Since _buildWhere returns '' when the column is invalid, an array of '' is returned which is JOINED into AND with no column names;

This is what I'll change in the pull request. It will only add strings to sqls if they exist thus preventing joining on empty array elements.

for (var k = 0, s = whereStmts.length; k < s; k++) {
  if (whereStmts[k].sql) {
    sqls.push(whereStmts[k].sql);
    params = params.concat(whereStmts[k].params);    
  }
}

Disable default dates encoding for BinaryPacker

Custom encodeDate, decodeDate functions are not used by msgpack5, because custom types encoding happens after Date type encoding inside msgpack.encode function.

This can be fixed by disabling default Dates encoding in following line adding disableTimestampEncoding: true option.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Awaiting Schedule

These updates are awaiting their schedule. Click on a checkbox to get an update now.

  • chore: lock file maintenance

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/continuous-integration.yaml
  • actions/checkout v4.1.6@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-node v4.0.2@60edb5dd545a775178f52524783378180af0d1f8
  • coverallsapp/github-action v2.3.0@643bc377ffa44ace6394b2b5d0d3950076de9f63
  • coverallsapp/github-action v2.3.0@643bc377ffa44ace6394b2b5d0d3950076de9f63
  • actions/checkout v4.1.6@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-node v4.0.2@60edb5dd545a775178f52524783378180af0d1f8
  • actions/checkout v4.1.6@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-node v4.0.2@60edb5dd545a775178f52524783378180af0d1f8
  • actions/checkout v4.1.6@a5ac7e51b41094c92402da3b24376905380afc29
  • github/codeql-action v3.25.5@b7cec7526559c32f1616476ff32d17ba4c59b2d6
  • github/codeql-action v3.25.5@b7cec7526559c32f1616476ff32d17ba4c59b2d6
npm
package.json
  • async ^3.2.5
  • bluebird ^3.7.2
  • debug ^4.3.4
  • msgpack5 ^4.5.1
  • strong-globalize ^6.0.6
  • uuid ^9.0.1
  • @commitlint/config-conventional ^19.2.2
  • chai ^4.4.1
  • chai-as-promised ^7.1.2
  • commitlint ^19.3.0
  • eslint ^8.57.0
  • eslint-config-loopback ^13.1.0
  • loopback-datasource-juggler ^5.0.9
  • mocha ^10.4.0
  • nyc ^15.1.0
travis
.travis.yml
  • node 10.24.1
  • node 12.22.12
  • node 14.21.3
  • node 16.20.2
  • node 17.9.1

  • Check this box to trigger a request for Renovate to run again on this repository

hasManyThough relation the generated SQL does't match the expected

When I use hasManyThough relation find the other Model data with or operator
.eg :
a App model and a User model is hasManyThough relation
use the Apps/{id}/users API find users
image
the filter is

{"limit":100,"where":{"or":[{"username":{"like":"%A%"}},{"nickname":{"like":"A"}}]}}

the lib/sql.js generated the SQL where clause does not match the expected
the expected sql like

select * from user where ((username like '%A%') or (nickname like '%A%')) and id in (1,2,3)

but the generated sql

select * from user where (username like '%A%') or (nickname like '%A%') and id in (1,2,3)

I think the lib\sql.js#L838 should be Add parentheses before and after

sql: '(' + branches.join(' ' + key.toUpperCase() + ' ') + ')'

Model-specific schema not respected by SQL building methods

We are working with a legacy database that has our data divided among different schemas.

As per the documentation, I should be able to set the schema for an individual model.
https://docs.strongloop.com/display/public/LB/Model+definition+JSON+file#ModeldefinitionJSONfile-Datasource-specificoptions

However, SQLConnector does not specify any schema in the SQL statements that it builds, even though there is a schema method that properly determines which schema to use for a given model.

We should use this schema method to always specify the schema in generated SQL.

@raymondfeng @bajtos What are the chances of this being implemented and released as version 3? It doesn't look like a complicated change, so I could probably implement it myself and submit a PR, if that increases the chances.

Are there any problems you can see with making this change? I know this would break loopback-connector-db2 since it needlessly overrides the schema method with a schema string property in the constructor, which is why I believe it should be released in the next major version.

Thanks :)

SQL Join

How do I get this to generate a true sql join?

Refactor the migration/discovery logic into base SqlConnector with extension points

There are common functions to handle migration and discovery for relational databases. As a developer, we would like to refactor such logic into the base SqlConnector class and allow connectors to extend from them.

Tasks:

  • loopback-connector base
    • Discovery
    • Migration
  • db2 (loopback-ibmdb extends SQLConnector in loopback-connector)
    • Discovery
    • Migration
  • dashdb
    • Discovery
    • Migration
  • db2iseries
    • Discovery
    • Migration
  • db2z
    • Discovery
    • Migration
  • informix
    • Discovery
    • Migration
  • mysql
    • Discovery
    • Migration
  • postgresql
    • Discovery
    • Migration
  • mssql
    • Discovery
    • Migration
  • oracle
    • Discovery
    • Migration

Discovery

  • discoverSchemas
  • discoverTables/Columns
  • discoverPrimaryKeys
  • discoverForeignKeys
  • discoverConstraints (such as uniqueness)
  • discoverIndexes
  • discoverStoredProcedures

Migration

Table:

  • createTable
  • dropTable
  • alterTable

Atomic Operations:

  • addColumn
  • updateColumn
  • dropColumn
  • addPrimaryKey
  • addForeignKey
  • dropPrimaryKey
  • dropForeignKey
  • createIndex

What's the etymology of ".ok\W+to\W+test."

I'm seeing ".ok\W+to\W+test." a lot. What does it mean? It seems that a branch is ok to be tested. I notice the \W+ too as in at least 1 some not \w character. I'm specifically curious about the etymology of this 'word'.

isNullable does not honor connector specific stanza's in property definitions

Connector.isNullable does not take into account relational database stanza's in the model definition. According to the docs the user should be able to specify a connector specific stanza for each column which contains a number of fields. Most need to be explicitly handled by the specific connector however nullable can be handled by loopback-connector since it is generic

create neo4j conector for lb4

Hi
I am trying to create lb4 connector for neo4j graph based on lb3 doc. beacuse there is not documentation for creating custom lb4 connector.
Am I should use typescript or i can use javascript??
beyond of this, please please please make a doc for javascript developer to use lb4 without hedache

Filtering with non existing / declared field is ignored / skipped

Bug or feature request

  • Bug
  • Feature request

Description of feature (or steps to reproduce if bug)

  1. Insert 10 rows in a model/table
  2. Model.find({where: { nonexistingfield: 'test' } })
  3. Return 10 rows

https://github.com/strongloop/loopback-connector/blob/97d2aea8686a2c66070696a73d23be0a76d14b97/lib/sql.js#L1096-L1100

Expected result

Return 0 (Memory connector return 0 and MongoDB Connector too)
In case of SQL this should throw an error ?

Actual result (if bug)

Return all the documents/rows

Additional information (Node.js version, LoopBack version, etc)

Only affect SQL connectors using lib/sql.js

MySQL full text seach

Suggestion

Suport full text search in mysql using match against

Examples

To query data i thought this:

{"where": {"fts": { "match": ["column1", "column2"], "against":"filter" }}}

I studied the code and implement this inside de method 'SQLConnector.prototype._buildWhere'

if (key === 'fts') {
  console.log("Full text search!!!");
  const matchObj = where[key]["match"];
  const match = Array.isArray(matchObj) 
    ? matchObj.map(c => self.columnEscaped(model, c)).join(",")
    : self.columnEscaped(model, matchObj);
  stmt.merge(`MATCH(${match}) AGAINST('${where[key]["against"]}')`);
  whereStmts.push(stmt);
  continue;
}

Acceptance criteria

There is any suggestion to enhance the solution?
This idea is in the scope of this project? If yes, how can i do a pull request?

updateAttributes race condition in loopback-connector-dashdb

Bug or feature request

  • Bug
  • Feature request

Description of feature (or steps to reproduce if bug)

loopback has a requirement on calls to the update function where it must return the number of rows modified. This is fine for MySQL which returns this information but for DB2/DashDB/DB2 z/DB2i/Informix and possibly others this has to be hacked at through complex SQL. In the DB2/DashDB case the complex SQL is SELECT <idField> FROM FINAL TABLE (UPDATE <tableName> SET <columnName> = <value> WHERE <idField> = <idValue> This complex SQL when run in parallel calls to updateAttributes will result in a deadlock scenario. Since updateAttributes is making use of the updateAll alias, it results in this deadlock.

Expected result

Calling updateAttributes should result in an update to the specified rows, even when done in parallel.

Actual result (if bug)

Calling updateAttributes results in a deadlock with other parallel calls to update since the nested update/select logic required to provide a row-count creates a deadlock scenario.

Additional information (Node.js version, LoopBack version, etc)

Rebase RDB connectors' CRUD implementations to the refactored SqlConnector

  • Update mssql connector implementation to leverage the base SqlConnector
  • Update oracle connector implementation to leverage the base SqlConnector
  • PR for loopback-connector
  • PR for loopback-datasource-juggler
  • PR for loopback-connector-mysql
  • PR for loopback-connector-postgresql
  • PR for loopback-connector-mssql
  • PR for loopback-connector-oracle
  • Release loopback-connector and all RDB connectors as 2.0

Forced order by ID in sql.js causing 40+ second queries for single row queries.

On tables with 100 million+ rows, when querying for a single row using loopback it'll insert an "order by id" forcing the entire table read.

Steps to reproduce

I am using a postgres server, but it is for pretty much all sql queries.

Example:
We have a model "foo" attached to a SQL table with the columns id and hash, where id is unique, and hash is not unique. This table has 100,000,000 Rows. and some hashes have up to 100,000 rows. (note this is simplified, in my database there are far more columns and every row is unique)

We use this curl command to query the loopback API (I know that I can use findOne instead, but it'll still go toprototype.all so it really doesn't make a difference besides returning a single object rather than an array):

curl --location --request GET 'localhost:3000/api/foos' --header 'Content-Type: application/x-www-form-urlencoded' --form 'filter={"where": { "hash": "d41d8cd98f00b204e9800998ecf8427e" }, "limit": 1 }'

Current Behavior

Loopback generates the following SQL statement

SELECT * FROM "public"."foo" WHERE "hash"='d41d8cd98f00b204e9800998ecf8427e' ORDER BY "id" LIMIT 1

Because hash is non-unique, and can have thousands of rows, (in this case, 115,000) this takes 40.632s on my server to complete.

Expected Behavior

Loopback should instead generate the following SQL statement:

SELECT hash FROM "public"."foo" WHERE "hash"='d41d8cd98f00b204e9800998ecf8427e' LIMIT 1

resulting in a query time of on my server of 12ms.

Link to reproduction sandbox

If you really need me to setup a reproduction sandbox I can, but the problem should be pretty apparent.

Additional information

link to offending code: https://github.com/strongloop/loopback-connector/blob/master/lib/sql.js#L1388

You could say that this is "working as intended" and that its the database structure is bad/wrong/whatever, but there is no reason why the connector should be dictating an order on all queries.

This functionality should be defined in the default scope of the datasource and model, not built into the base loopback connector.

Acceptance Criteria

  • add a flag to disable default order by the identifier on queries. Reference: loopbackio/loopback-connector-postgresql#417
  • add test cases for main SQL connectors (MySQL for example) + mongodb
  • update documentations. Might need to update several README files of connectors

MaxListenersExceededWarning: Possible EventEmitter memory leak detected

Good evening. I have been working with your connector for about 2 months on one project and had this error message all the time, since adding your connector:
(node:13848) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 connected listeners added. Use emitter.setMaxListeners() to increase limit

Today I started looking for a way to get rid of this warning and found almost the last answer to this issue #1186 , provided by user loay
After adding the line, described there, the message got disappeared. Could you, please, clarify this issue and fix it, if it is a bug and not my mistake.

I am working with postgresql database and loopback-connector-postgresql, but I had to add that line to your module, that is why I am writing here

undefined is not a function (testing connection via Arc)

trying to test the Oracle connector (via Arc) results in the following:

Oops! Something is wrong
undefined is not a function
Show/hide details
Message: undefined is not a function
Request: /workspace/api/DataSourceDefinitions/server.jeani/testConnection
Staus: 500
TypeError: undefined is not a function
    at Oracle.SQLConnector.execute (/vagrant/node_modules/loopback-connector-oracle/node_modules/loopback-connector/lib/sql.js:407:8)
    at DataSource.<anonymous> (/vagrant/node_modules/loopback-connector-oracle/node_modules/loopback-connector/lib/sql.js:397:12)
    at DataSource.g (events.js:199:16)
    at DataSource.emit (events.js:104:17)
    at DataSource.postInit (/vagrant/node_modules/loopback-datasource-juggler/lib/datasource.js:310:14)
    at /vagrant/node_modules/loopback-connector-oracle/lib/oracle.js:123:19

Digging in reveals https://github.com/strongloop/loopback-connector/blob/master/lib/sql.js#L407, which references a method called notifyObserversAround, which for all I've been able to tell isn't defined anywhere in the project.

Allow only sql string type limits mysql connector usage

Hi, I'm using loopback-connector in a loopback 4 project and I'm trying to use nestTables option from mysql lib (https://www.npmjs.com/package/mysql#joins-with-overlapping-column-names).

In the mysql library and with this specific use case, the option is an object and not a string but loopback-connector prevents me to use this option because of this assertion.

It's in opposition with the allowed types in the typescript declaration of datasource execute

I found a workaround by calling directly executeSQL. It's working but it's not promisfied.

Incorrect error exposed in `isActual` method call

Steps to reproduce

Call the isActual method on a datasource during a migration.

Current Behavior

The isActual method eventually calls the execute method. When execute calls back with the maxOfflineRequests error, it is swallowed as other code continues to execute before calling back with the error (back in the isActual method), the other code that executes generates the error as it's expecting a fields array

Expected Behavior

The getTableStatus callback should handle the error instead of executing any further code.

Link to reproduction sandbox

There is no link but it's clear the error handling in getTableStatus needs to be changed.

AutoUpdate needs to have order when executing index related opertaions

Description/Steps to reproduce

Auto update generates ordered statements on indexes, so that it will drop the existing index and recreate it.
Because of the async execution of all the statements, the add index can run before the drop index which causes the update to fail.

Expected result

index related operations while updating should be done in a dependent matter and only after all coulmns were updated. The best approach will be to do the following:

  1. run async all columns related statements and all drop indexes related statements
  2. run async all create indexes related statments

No possibility to create update query - missing parameter excludeIds

Hello guys,

I would like to use updateAll() function to update a row in DB2 database. My connection to resource is okay, I can work with data (Get, or Create), but in case I am trying to use update functionality, it's returning an error.

I was debugging in code, and found that my problem is with options, concretely with excludeIds parameter. In case this parameter is not sent, in function buildFieldsForReplace is this parameter automatically set to true, and then this function is returning only empty array of fields.

Then, my sql query looks like that (missing fields after SET) -
UPDATE "TABLE_NAME" SET WHERE "COLUMN_NAME"=(?)

My solution:

/lib/sql.js
you have definition of function
SQLConnector.prototype.buildUpdate = function(model, where, data, options)
which has parameter "options".
then, function buildFieldsForUpdate is called,
var fields = this.buildFieldsForUpdate(model, data);
but with one missing parameter. I would prefer to update this row by
var fields = this.buildFieldsForUpdate(model, data, options.excludeIds);

reason is that function buildFieldsForUpdate is already defined with this property.
SQLConnector.prototype.buildFieldsForUpdate = function(model, data, excludeIds)

This parameter is also defined and not used with buildFieldsForReplace function, which I am not using now, but maybe good point for you to consider both functions.

Thanks for your response !

Connector helpers to obtain INDEX and FOREIGN KEY configurations from model definitions

This is a follow-up task for the proposal outlined in loopbackio/loopback-next#2712.

Implement a helper functions in base Connector class to process index and foreign-key definitions in an unified way and convert them into data suitable for consumption by connector implementations. The helpers should gather both model-level and property-level definitions, apply database/connector-specific options, merge keys/properties fields in index definitions, etc. and produce a final definition that can be directly mapped to database commands.

See _SPIKE_.md in loopbackio/loopback-next#2712 for the full description of index/PK definition syntax.

This is a prerequisite for implementation of indexes & foreign keys in other connectors, most notably memory connector (loopbackio/loopback-next#2333) and SqlConnector (https://github.com/strongloop/loopback-connector-rest/issues/135)

Acceptance criteria

  • Implement a helper to process INDEX definitions, include tests and API docs
  • Implement a helper to process FOREIGN KEY definitions, include tests and API docs
  • Deprecate ModelDefinition.prototype.indexes() API in favor of this new Connector method.
  • Create follow-up tasks to leverage the new helper in our NoSQL connectors and thus let the connectors understand the new FK/INDEX definition syntax. One GH issue per connector please.
    • MongoDB
    • CouchDB
    • Cloudant
    • Cassandra

temporary tables support

Does loopback provide support for temporary tables creation in database (giving table a session scope)? If so how can it be supported like the steps for creation of temporary tables.
It is no where seen in the documentation. Is it really supported or implemented by loopback or any of the connector's , regarding the temporary tables concept with loopback ORM.

Would be nice to hear some thing about it @bajtos @raymondfeng

autoupdate with postgresql connector no longer creates tables before foreign keys

Steps to reproduce

upgrade from "4.10.2" to "4.11.0"

On an empty database using a schema with many relations, from server.js call
app.datasources.pg.autoupdate();

The problem is foreign keys to tables are attempting to be added before the tables are created. I have never seen this before. For example, after the accesstoken table
is successfully created I get: [UnhandledPromiseRejectionWarning: error: relation "public.user" does not exist] because the connector is trying to add to accesstoken, a the foreign key to user which does not yet exist.

Expected Behavior

I expect tables to be created before the foreign key constraints that reference them.

Additional information

I did not explicitly upgrade, the upgrade likely came as a dependency (e.g. to loopback-datasource-juggler).

TypeError: this.dataSource.getMaxOfflineRequests is not a function

Hi guys, after latest update I'm having next error in my loopback instance

Description/Steps to reproduce

TypeError: this.dataSource.getMaxOfflineRequests is not a function
    at PostgreSQL.SQLConnector.execute (/var/app/current/node_modules/loopback-connector-postgresql/node_modules/loopback-connector/lib/sql.js:628:25)
    at PostgreSQL.showFields (/var/app/current/node_modules/loopback-connector-postgresql/lib/migration.js:28:10)
    at PostgreSQL.SQLConnector.getTableStatus (/var/app/current/node_modules/loopback-connector-postgresql/node_modules/loopback-connector/lib/sql.js:240:8)
    at /var/app/current/node_modules/loopback-connector-postgresql/node_modules/loopback-connector/lib/sql.js:84:10
    at /var/app/current/node_modules/loopback-connector-postgresql/node_modules/loopback-connector/node_modules/async/dist/async.js:2158:44
    at eachOfArrayLike (/var/app/current/node_modules/loopback-connector-postgresql/node_modules/loopback-connector/node_modules/async/dist/async.js:504:13)
    at eachOf (/var/app/current/node_modules/loopback-connector-postgresql/node_modules/loopback-connector/node_modules/async/dist/async.js:555:16)
    at awaitable(eachOf) (/var/app/current/node_modules/loopback-connector-postgresql/node_modules/loopback-connector/node_modules/async/dist/async.js:208:32)
    at Object.eachLimit (/var/app/current/node_modules/loopback-connector-postgresql/node_modules/loopback-connector/node_modules/async/dist/async.js:2220:16)
    at Object.awaitable(eachLimit) (/var/app/current/node_modules/loopback-connector-postgresql/node_modules/loopback-connector/node_modules/async/dist/async.js:208:32)
    at PostgreSQL.SQLConnector.autoupdate (/var/app/current/node_modules/loopback-connector-postgresql/node_modules/loopback-connector/lib/sql.js:78:9)
    at DataSource.autoupdate (/var/app/current/node_modules/loopback-datasource-juggler/lib/datasource.js:905:18)
    at /var/app/current/server/boot/autoupdate.js:13:51
    at Array.forEach (<anonymous>)
    at autoUpdateAll (/var/app/current/server/boot/autoupdate.js:10:25)
    at Object.module.exports [as func] (/var/app/current/server/boot/autoupdate.js:36:3)

It raises when calling autoUpdate function for a postgresql model

Additional information

darwin x64 8.16.0

├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]

Spike: a template implementation of index & constraint migration in SqlConnector

This is a follow-up task for the proposal outlined in loopbackio/loopback-next#2712.

The intention is to share as much of index/FK migration logic among all SQL connectors, to ensure consistent behavior. This spike will allow us to better understand the effort needed to implement migration in our SQL connectors (loopbackio/loopback-next#2332).

When working on the spike, use the existing implementation in MySQL, PostgreSQL and MSSQL connectors for inspiration. Try to preserve as much backwards compatibility as feasible. We should keep support for connector-specific behavior that's easy to implement in the shared base class. It's ok to drop support for use cases that would be difficult to preserve or that would complicate the codebase too much. Take notes about what will not work so that we can write helpful release notes and a migration guide.

The implementation needs to detect index/FK metadata not supported by SQL and report warnings to console.

Acceptance criteria

  • A draft pull request with a PoC implementation showing a template implementation of INDEX and FOREIGN KEY migration in SqlConnector.
  • In the PoC, propose how to test this functionality in automated way in all SQL connectors. It's important to test both autoupdate (incremental changes to existing schema) and automigrate (creating new tables). Do we want to create a shared test suite in loopback-connector to be executed by all SQL connectors to verify that they are supporting all common INDEX/FK configurations?
  • A draft pull request in MySQL or PostgreSQL connector leveraging the new template implementation to replace connector-specific migration.
  • Create a follow-up story (or multiple stories if needed) to implement the template in production quality.
  • Create follow-up tasks to leverage the new template in our SQL connectors and thus let the connectors understand the new FK/INDEX definition syntax. For each SQL connector, create a new GH issue in the connector repository. As part of each story, we need to assess backwards compatibility and compile a list of breaking changes.
    • MySQL
    • PostgreSQL
    • MSSQL
    • Oracle
    • DB2
    • db2iseries
    • dashdb
    • informix
    • db2x
  • Update loopbackio/loopback-next#2332 with links to newly created GH issues.

Wrong queries causes unhandled exceptions

Steps to reproduce

Run a select query (all()) with order by on a bogus field that includes ? char in it
https://github.com/strongloop/loopback-connector/blob/deb461ea62e6226f053774fb10c1f023d6061f8c/lib/sql.js#L1455-L1459

Current Behavior

an unhandled exception caused by the buildSelect() method due to ParameterizedSQL class assertion error:

https://github.com/strongloop/loopback-connector/blob/deb461ea62e6226f053774fb10c1f023d6061f8c/lib/parameterized-sql.js#L38-L42

Which in turn means that the callback is never called, causing connections to hang

Expected Behavior

cb() should be called with the proper error

Add support for filter-through-relation

Bug or feature request

  • Bug
  • Feature request

Description of feature

Provide the ability to query models by their relations (using joins or subqueries).

Example Models:

Appointments belongsTo ServiceCall
ServiceCall hasMany Appointments

Relation filter options:

Simple equality through relation:

/appointments?filter={"relation":{"serviceCall":{"status":"OPEN"}}}

Expected Result:

Should return all Appointments having serviceCall with status 'OPEN'

/serviceCalls?filter={"relation":{"appointments":{"type":"CL"}}}

Expected Result:

Should return all ServiceCalls having at least 1 Appointment with type 'CL'

Additional information

I have a feature branch with this already implemented that was branched from latest master. I cannot push code right now as I get a 403. Waiting on access.

breaking change in 4.9.0 due to drop of node 6 support

Hi,

You have dropped support for node 6 in version 4.9.0 which is completely acceptable as it is EOL, but that is a braking change and in order to adhere to semver, you can't publish that breaking change under the same major version.
Sadly, I'm still using node 6 and your change broke all my repositories.

Can you please roll back the release and make the changes in a new major version?

Thanks,

Issue - there is an error in lib/sql.js:638 of the latest version of code

Description/Steps to reproduce

loopback-connector/lib/sql.js:638
),
^
SyntaxError: Unexpected token )
at createScript (vm.js:53:10)
at Object.runInThisContext (vm.js:95:10)
at Module._compile (module.js:543:28)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.require (module.js:498:17)
at require (internal/module.js:20:19)
at Object. (/usr/src/microservice/caapp/node_modules/loopback-connector/index.js:12:47)
at Module._compile (module.js:571:32)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.require (module.js:498:17)

Link to reproduction sandbox

Expected result

Additional information

Support for NoSQL connector ?

Are their any plans to create respective NoSQL connector, which forces to implement functions like applyPagination etc?

It's obvious that a connector which transforms a certain structure into a structured language (and vice versa) is somehow restricting the concept of a "No"SQL database ;).

The intention behind my question is that I'm currently re-factoring the loopback-connector-arangodb. ArangoDB (although being a NoSQL database) comes with a structured language called AQL and supports transactions.

So I'm considering to extend the SQLConnector instead the normal connector.

Are there any known caveats or restrictions ? I know that I could just start, but before that I wanted to ask if there is already a plan for NoSQL connectors and/or any experience/thoughts about transforming the SQLConnector for NoSQL Databases

Add support for stored procedures as a model method

It would be nice to support stored procedures as model methods, for example:

MyModel.myProc = function(x, y, cb) {
...
}

For the SQL based connectors, we can declare such mapping as part of the model settings, for example,

"MyModel": {
  "storedProcedures": {
    "myProc": {
       parameters: [],
       returns: []
    } 
}

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.