Brewskey / spark-server

An API compatible open source server for interacting with devices speaking the spark-protocol
https://www.particle.io/
GNU Affero General Public License v3.0
54 stars 27 forks source link

NEdb Error if variable name contain "." #237

Closed straccio closed 7 years ago

straccio commented 7 years ago

I think that is cause because DeviceAtributes.variables is an Object Type.

`[2017-07-07T10:40:48.890Z] ERROR: Device.js/31122 on localhost: Device disconnected (disconnectCounter=1) logInfo: { "cache_key": "_8", "deviceID": "383433383335353334373931", "duration": 0.058 }

message: Error during connection: Error: Field names cannot contain a .: Error: Field names cannot contain a .
    at checkKey (/Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/model.js:36:11)
    at /Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/model.js:54:7
    at Array.forEach (native)
    at checkObject (/Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/model.js:53:22)
    at /Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/model.js:55:7
    at Array.forEach (native)
    at checkObject (/Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/model.js:53:22)
    at Object.modify (/Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/model.js:522:3)
    at /Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/datastore.js:680:33
    at /Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/datastore.js:379:14
    at /Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:421:16
    at replenish (/Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:941:25)
    at /Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:950:9
    at eachLimit$1 (/Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:3169:24)
    at Object.<anonymous> (/Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:980:16)
    at /Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/datastore.js:373:11
(node:31122) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 7): Error: Field names cannot contain a .
at nextTask (/Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:5297:14)
    at next (/Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:5304:9)
    at /Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:906:16
    at /Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/datastore.js:355:12
    at nextTask (/Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:5297:14)
    at Object.waterfall (/Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:5307:5)
    at Datastore.getCandidates (/Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/datastore.js:315:9)
    at /Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/datastore.js:670:10
    at nextTask (/Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:5297:14)
    at next (/Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:5304:9)
    at /Users/User/Documents/src/Domo/spark-server/node_modules/async/dist/async.js:906:16
    at /Users/User/Documents/src/Domo/spark-server/node_modules/nedb-core/lib/datastore.js:642:16`
straccio commented 7 years ago

This is caused because my Particle Device have variables with a dot in a name.

jlkalberer commented 7 years ago

Wow... nice catch.

I assume this worked with the Public cloud?

@AntonPuko - I think we just need to save vars/functions as serialized json

straccio commented 7 years ago

Yes it's work.... serializing can impact performance.... but is the solution. How can i test mongo db? i miss the configuration part.

jlkalberer commented 7 years ago

Serializing won't affect performance in this case -- it would be a huge micro-optimization.

Mongodb will also fail here. It doesn't support having . in property names. - https://github.com/louischatriot/nedb/issues/399

straccio commented 7 years ago

but it's not a "property", o better, a field. is a field type Object that need to be serialized on db site.

jlkalberer commented 7 years ago

No, when it gets saved as an object in the DB, it looks like it has properties with dots in them to NEDB.

Here is the type for device attributes:

export type DeviceAttributes = {
  appHash: ?string,
  currentBuildTarget: string,
  deviceID: string,
  functions?: ?Array<string>,
  imei?: string,
  ip: string,
  isCellular: boolean,
  last_iccid?: string,
  lastFlashedAppName: ?string,
  lastHeard: Date,
  name: string,
  ownerID: ?string,
  particleProductId: number,
  productFirmwareVersion: number,
  registrar: string,
  timestamp: Date,
  variables?: ?Object,
};

variables will be stored as something like this:

type Variable = {[key: string]: string};

// data is 
{'test.Var': 'INT'},

This will break NEDB/Mongo.

straccio commented 7 years ago

This can help! https://lodash.com/docs#toPairs

jlkalberer commented 7 years ago

I was thinking JSON.toString or Object.entries

AntonPuko commented 7 years ago

Ok, I'll make the change. But @straccio what is the idea behind name variables with dots? . is an operator almost in every language.

straccio commented 7 years ago

I use a dot as separator. <characteristic type %03d >-<accessory id %02d >.<characteristic id %02d> Its not a problem replace the dot with something else.

On the program side i don't have any dots or numbers for variables i have something like humidity, or temperature.