@things-factory/dataset 5.0.0-alpha.1 → 5.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/client/bootstrap.js +0 -2
  2. package/client/pages/data-entry-form.js +74 -0
  3. package/client/pages/data-item-list.js +47 -9
  4. package/client/pages/data-sample.js +52 -8
  5. package/client/pages/data-sensor.js +446 -0
  6. package/client/pages/data-set.js +46 -7
  7. package/client/route.js +4 -0
  8. package/dist-server/index.js +1 -0
  9. package/dist-server/index.js.map +1 -1
  10. package/dist-server/routes.js +64 -0
  11. package/dist-server/routes.js.map +1 -1
  12. package/dist-server/service/data-item/data-item-type.js +10 -5
  13. package/dist-server/service/data-item/data-item-type.js.map +1 -1
  14. package/dist-server/service/data-item/data-item.js +17 -4
  15. package/dist-server/service/data-item/data-item.js.map +1 -1
  16. package/dist-server/service/data-sample/data-sample-mutation.js +41 -7
  17. package/dist-server/service/data-sample/data-sample-mutation.js.map +1 -1
  18. package/dist-server/service/data-sample/data-sample-type.js +23 -2
  19. package/dist-server/service/data-sample/data-sample-type.js.map +1 -1
  20. package/dist-server/service/data-sample/data-sample.js +44 -5
  21. package/dist-server/service/data-sample/data-sample.js.map +1 -1
  22. package/dist-server/service/data-sensor/data-sensor-mutation.js +120 -0
  23. package/dist-server/service/data-sensor/data-sensor-mutation.js.map +1 -0
  24. package/dist-server/service/data-sensor/data-sensor-query.js +108 -0
  25. package/dist-server/service/data-sensor/data-sensor-query.js.map +1 -0
  26. package/dist-server/service/data-sensor/data-sensor-type.js +147 -0
  27. package/dist-server/service/data-sensor/data-sensor-type.js.map +1 -0
  28. package/dist-server/service/data-sensor/data-sensor.js +168 -0
  29. package/dist-server/service/data-sensor/data-sensor.js.map +1 -0
  30. package/dist-server/service/data-sensor/index.js +9 -0
  31. package/dist-server/service/data-sensor/index.js.map +1 -0
  32. package/dist-server/service/data-set/data-set-type.js +18 -0
  33. package/dist-server/service/data-set/data-set-type.js.map +1 -1
  34. package/dist-server/service/data-set/data-set.js +22 -3
  35. package/dist-server/service/data-set/data-set.js.map +1 -1
  36. package/dist-server/service/data-spec/data-spec-manager.js +20 -0
  37. package/dist-server/service/data-spec/data-spec-manager.js.map +1 -0
  38. package/dist-server/service/data-spec/data-spec-query.js +48 -0
  39. package/dist-server/service/data-spec/data-spec-query.js.map +1 -0
  40. package/dist-server/service/data-spec/data-spec.js +78 -0
  41. package/dist-server/service/data-spec/data-spec.js.map +1 -0
  42. package/dist-server/service/data-spec/index.js +8 -0
  43. package/dist-server/service/data-spec/index.js.map +1 -0
  44. package/dist-server/service/index.js +10 -2
  45. package/dist-server/service/index.js.map +1 -1
  46. package/package.json +13 -11
  47. package/server/index.ts +2 -0
  48. package/server/routes.ts +76 -0
  49. package/server/service/data-item/data-item-type.ts +7 -4
  50. package/server/service/data-item/data-item.ts +13 -2
  51. package/server/service/data-sample/data-sample-mutation.ts +55 -5
  52. package/server/service/data-sample/data-sample-type.ts +17 -2
  53. package/server/service/data-sample/data-sample.ts +37 -2
  54. package/server/service/data-sensor/data-sensor-mutation.ts +110 -0
  55. package/server/service/data-sensor/data-sensor-query.ts +56 -0
  56. package/server/service/data-sensor/data-sensor-type.ts +98 -0
  57. package/server/service/data-sensor/data-sensor.ts +139 -0
  58. package/server/service/data-sensor/index.ts +6 -0
  59. package/server/service/data-set/data-set-type.ts +14 -0
  60. package/server/service/data-set/data-set.ts +17 -1
  61. package/server/service/data-spec/data-spec-manager.ts +21 -0
  62. package/server/service/data-spec/data-spec-query.ts +21 -0
  63. package/server/service/data-spec/data-spec.ts +44 -0
  64. package/server/service/data-spec/index.ts +5 -0
  65. package/server/service/index.ts +12 -4
  66. package/things-factory.config.js +4 -0
  67. package/translations/en.json +17 -4
  68. package/translations/ko.json +16 -3
  69. package/translations/ms.json +17 -4
  70. package/translations/zh.json +17 -4
@@ -16,25 +16,33 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.schema = exports.entities = void 0;
18
18
  /* IMPORT ENTITIES AND RESOLVERS */
19
+ const data_sensor_1 = require("./data-sensor");
19
20
  const data_sample_1 = require("./data-sample");
20
21
  const data_item_1 = require("./data-item");
21
22
  const data_set_1 = require("./data-set");
23
+ const data_spec_1 = require("./data-spec");
22
24
  /* EXPORT ENTITY TYPES */
25
+ __exportStar(require("./data-sensor/data-sensor"), exports);
23
26
  __exportStar(require("./data-sample/data-sample"), exports);
24
27
  __exportStar(require("./data-item/data-item"), exports);
25
28
  __exportStar(require("./data-set/data-set"), exports);
29
+ __exportStar(require("./data-spec/data-spec"), exports);
26
30
  exports.entities = [
27
31
  /* ENTITIES */
32
+ ...data_sensor_1.entities,
28
33
  ...data_sample_1.entities,
29
34
  ...data_item_1.entities,
30
- ...data_set_1.entities
35
+ ...data_set_1.entities,
36
+ ...data_spec_1.entities
31
37
  ];
32
38
  exports.schema = {
33
39
  resolverClasses: [
34
40
  /* RESOLVER CLASSES */
41
+ ...data_sensor_1.resolvers,
35
42
  ...data_sample_1.resolvers,
36
43
  ...data_item_1.resolvers,
37
- ...data_set_1.resolvers
44
+ ...data_set_1.resolvers,
45
+ ...data_spec_1.resolvers
38
46
  ]
39
47
  };
40
48
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAmC;AACnC,+CAAgG;AAChG,2CAA0F;AAC1F,yCAAuF;AAEvF,yBAAyB;AACzB,4DAAyC;AACzC,wDAAqC;AACrC,sDAAmC;AAEtB,QAAA,QAAQ,GAAG;IACtB,cAAc;IACf,GAAG,sBAAkB;IACpB,GAAG,oBAAgB;IACnB,GAAG,mBAAe;CACnB,CAAA;AAEY,QAAA,MAAM,GAAG;IACpB,eAAe,EAAE;QACf,sBAAsB;QACxB,GAAG,uBAAmB;QACpB,GAAG,qBAAiB;QACpB,GAAG,oBAAgB;KACpB;CACF,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/service/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAmC;AACnC,+CAAgG;AAChG,+CAAgG;AAChG,2CAA0F;AAC1F,yCAAuF;AACvF,2CAA0F;AAE1F,yBAAyB;AACzB,4DAAyC;AACzC,4DAAyC;AACzC,wDAAqC;AACrC,sDAAmC;AACnC,wDAAqC;AAExB,QAAA,QAAQ,GAAG;IACtB,cAAc;IACd,GAAG,sBAAkB;IACrB,GAAG,sBAAkB;IACrB,GAAG,oBAAgB;IACnB,GAAG,mBAAe;IAClB,GAAG,oBAAgB;CACpB,CAAA;AAEY,QAAA,MAAM,GAAG;IACpB,eAAe,EAAE;QACf,sBAAsB;QACtB,GAAG,uBAAmB;QACtB,GAAG,uBAAmB;QACtB,GAAG,qBAAiB;QACpB,GAAG,oBAAgB;QACnB,GAAG,qBAAiB;KACrB;CACF,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/dataset",
3
- "version": "5.0.0-alpha.1",
3
+ "version": "5.0.0-alpha.4",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "client/index.js",
6
6
  "things-factory": true,
@@ -24,15 +24,17 @@
24
24
  "migration:create": "node ../../node_modules/typeorm/cli.js migration:create -d ./server/migrations"
25
25
  },
26
26
  "dependencies": {
27
- "@operato/data-grist": "^0.4.1",
28
- "@operato/graphql": "^0.4.1",
29
- "@operato/i18n": "^0.4.1",
30
- "@operato/layout": "^0.4.1",
31
- "@operato/shell": "^0.4.1",
32
- "@operato/styles": "^0.4.1",
33
- "@operato/utils": "^0.4.1",
34
- "@things-factory/auth-base": "^5.0.0-alpha.1",
35
- "@things-factory/shell": "^5.0.0-alpha.1"
27
+ "@operato/data-grist": "1.0.0-alpha.4",
28
+ "@operato/dataset": "1.0.0-alpha.4",
29
+ "@operato/graphql": "1.0.0-alpha.4",
30
+ "@operato/i18n": "1.0.0-alpha.4",
31
+ "@operato/layout": "1.0.0-alpha.4",
32
+ "@operato/shell": "1.0.0-alpha.4",
33
+ "@operato/styles": "1.0.0-alpha.4",
34
+ "@operato/utils": "1.0.0-alpha.4",
35
+ "@things-factory/auth-base": "^5.0.0-alpha.4",
36
+ "@things-factory/env": "^5.0.0-alpha.4",
37
+ "@things-factory/shell": "^5.0.0-alpha.4"
36
38
  },
37
- "gitHead": "2b3e3818a5d7ab7fdfff9214cc65f56885b27ad0"
39
+ "gitHead": "77253f86954dc6f5c14356ea85887c323fd2511a"
38
40
  }
package/server/index.ts CHANGED
@@ -3,3 +3,5 @@ import './routes'
3
3
  export * from './migrations'
4
4
  export * from './middlewares'
5
5
  export * from './service'
6
+
7
+ export * from './service/data-spec/data-spec-manager'
package/server/routes.ts CHANGED
@@ -1,3 +1,9 @@
1
+ import { getConnection } from 'typeorm'
2
+
3
+ import { DataSample } from './service'
4
+ import { DataItem } from './service/data-item/data-item'
5
+ import { DataSensor } from './service/data-sensor/data-sensor'
6
+
1
7
  const debug = require('debug')('things-factory:dataset:routes')
2
8
 
3
9
  process.on('bootstrap-module-global-public-route' as any, (app, globalPublicRouter) => {
@@ -7,6 +13,76 @@ process.on('bootstrap-module-global-public-route' as any, (app, globalPublicRout
7
13
  * ex) routes.get('/path', async(context, next) => {})
8
14
  * ex) routes.post('/path', async(context, next) => {})
9
15
  */
16
+
17
+ globalPublicRouter.post('/sensor-data', async (context, next) => {
18
+ // 데이타 검증
19
+ const { deviceId, data, rawData, timestamp = Date.now() } = context.request.body
20
+ if (!deviceId || !data) {
21
+ throw new Error(`deviceId(${deviceId}) and data(${JSON.stringify(data)}) properties are mandatory`)
22
+ }
23
+
24
+ // make new data-sample
25
+ await getConnection().transaction(async tx => {
26
+ // find sensor through deviceId
27
+ const sensor = await tx.getRepository(DataSensor).findOne({
28
+ where: { deviceId },
29
+ relations: ['domain', 'appliance', 'dataSet']
30
+ })
31
+
32
+ if (!sensor) {
33
+ throw new Error(`Sensor having given deviceId(${deviceId}) not found`)
34
+ }
35
+
36
+ if (!sensor.active) {
37
+ throw new Error(`State of the sensor given deviceId(${deviceId}) is not active`)
38
+ }
39
+
40
+ if (!sensor.appliance) {
41
+ throw new Error(`Appliance of the sensor given deviceId(${deviceId}) is not set up`)
42
+ }
43
+
44
+ if (!sensor.dataSet) {
45
+ throw new Error(`DataSet of the sensor given deviceId(${deviceId}) is not set up`)
46
+ }
47
+
48
+ const domain = sensor.domain
49
+ const dataSet = sensor.dataSet
50
+ const user = sensor.appliance
51
+
52
+ const dataItems = await tx.getRepository(DataItem).find({
53
+ where: {
54
+ domain,
55
+ dataSet
56
+ },
57
+ order: {
58
+ sequence: 'DESC'
59
+ }
60
+ })
61
+
62
+ var spec = {} as any
63
+
64
+ dataItems.forEach(dataItem => {
65
+ spec[dataItem.name] = dataItem.spec
66
+ })
67
+
68
+ await tx.getRepository(DataSample).save({
69
+ domain,
70
+ name: dataSet.name,
71
+ description: dataSet.description,
72
+ partitionKeys: dataSet.partitionKeys,
73
+ dataSet,
74
+ data,
75
+ rawData,
76
+ spec,
77
+ source: deviceId,
78
+ collectedAt: new Date(timestamp),
79
+ creator: user,
80
+ updater: user
81
+ })
82
+ })
83
+
84
+ return 'OK'
85
+ })
10
86
  })
11
87
 
12
88
  process.on('bootstrap-module-global-private-route' as any, (app, globalPrivateRouter) => {
@@ -21,20 +21,23 @@ export class DataItemPatch {
21
21
  @Field(type => Int, { nullable: true })
22
22
  sequence?: number
23
23
 
24
+ @Field({ nullable: true })
25
+ tag?: string
26
+
24
27
  @Field(type => DataItemType, { nullable: true })
25
28
  type?: DataItemType
26
29
 
30
+ @Field(type => ScalarObject, { nullable: true })
31
+ options?: ScalarObject
32
+
27
33
  @Field(type => Int, { nullable: true })
28
34
  quota?: number
29
35
 
30
- @Field({ nullable: true })
31
- options?: string
32
-
33
36
  @Field({ nullable: true })
34
37
  active?: boolean
35
38
 
36
39
  @Field(type => ScalarObject, { nullable: true })
37
- spec?: object
40
+ spec?: ScalarObject
38
41
 
39
42
  @Field({ nullable: true })
40
43
  cuFlag?: string
@@ -19,7 +19,8 @@ export enum DataItemType {
19
19
  number = 'number',
20
20
  text = 'text',
21
21
  boolean = 'boolean',
22
- select = 'select'
22
+ select = 'select',
23
+ file = 'file'
23
24
  }
24
25
 
25
26
  registerEnumType(DataItemType, {
@@ -63,6 +64,12 @@ export class DataItem {
63
64
  @Field(type => Int, { nullable: true })
64
65
  sequence: number
65
66
 
67
+ @Column({
68
+ nullable: true
69
+ })
70
+ @Field({ nullable: true })
71
+ tag?: string
72
+
66
73
  @Column({
67
74
  nullable: true
68
75
  })
@@ -75,6 +82,10 @@ export class DataItem {
75
82
  @Field({ nullable: true })
76
83
  type?: DataItemType
77
84
 
85
+ @Column('simple-json', { nullable: true })
86
+ @Field(type => ScalarObject, { nullable: true })
87
+ options?: ScalarObject
88
+
78
89
  @Column({
79
90
  nullable: true
80
91
  })
@@ -83,7 +94,7 @@ export class DataItem {
83
94
 
84
95
  @Column('simple-json', { nullable: true })
85
96
  @Field(type => ScalarObject, { nullable: true })
86
- spec?: object
97
+ spec?: ScalarObject
87
98
 
88
99
  @CreateDateColumn()
89
100
  @Field({ nullable: true })
@@ -6,6 +6,35 @@ import { DataSet } from '../data-set/data-set'
6
6
  import { DataSample } from './data-sample'
7
7
  import { DataSamplePatch, NewDataSample } from './data-sample-type'
8
8
 
9
+ import moment from 'moment'
10
+
11
+ const debug = require('debug')('things-factory:dataset:data-sample:data-sample-mutation')
12
+
13
+ // parse variable javascript string pattern
14
+ const replaceVariables = (keys, dic) => {
15
+ for (const k in keys) {
16
+ const matches = keys[k].match(/\$\{\w*\}/g)
17
+ matches &&
18
+ matches.forEach(m => {
19
+ keys[k] = keys[k].replace(m, dic[m.slice(2, -1)])
20
+ })
21
+ }
22
+ return keys
23
+ }
24
+
25
+ // It is required UTC date for Partitioning File System like AWS S3.
26
+ // ex) %YYYY, %MM, %DD
27
+ const formatDate = (keys, _moment) => {
28
+ for (const k in keys) {
29
+ const matches = keys[k].match(/%\w*/g)
30
+ matches &&
31
+ matches.forEach(m => {
32
+ keys[k] = keys[k].replace(m, _moment.format(m.substr(1)))
33
+ })
34
+ }
35
+ return keys
36
+ }
37
+
9
38
  @Resolver(DataSample)
10
39
  export class DataSampleMutation {
11
40
  @Directive('@privilege(category: "data-sample", privilege: "mutation", domainOwnerGranted: true)')
@@ -16,19 +45,38 @@ export class DataSampleMutation {
16
45
 
17
46
  const dataSet = await tx.getRepository(DataSet).findOne({ id: dataSample.dataSetId })
18
47
  const dataItems = await tx.getRepository(DataItem).find({
19
- select: {
48
+ where: {
20
49
  domain,
21
- dataSetId: dataSample.dataSetId
50
+ dataSet
22
51
  },
23
52
  order: {
24
53
  sequence: 'DESC'
25
54
  }
26
55
  })
27
56
 
28
- var spec = {} as any
57
+ const spec = dataItems.reduce((spec, dataItem) => {
58
+ spec[dataItem.tag] = {
59
+ ...dataItem.spec,
60
+ name: dataItem.name /* do we need ? */
61
+ }
62
+
63
+ return spec
64
+ }, {})
65
+
66
+ var partitionKeys = {
67
+ ...dataSet.partitionKeys,
68
+ year: '%YYYY',
69
+ month: '%MM',
70
+ date: '%DD',
71
+ variableX: '${x}',
72
+ variableDataSetId: '${dataSetId}'
73
+ }
29
74
 
30
- dataItems.sortforEach(dataItem => {
31
- spec[dataItem.name] = dataItem.spec
75
+ const collectedAt = dataSample.collectedAt || new Date()
76
+ partitionKeys = formatDate(partitionKeys, moment(collectedAt).utc())
77
+ partitionKeys = replaceVariables(partitionKeys, {
78
+ dataSetId: dataSample.dataSetId,
79
+ ...dataSample.data
32
80
  })
33
81
 
34
82
  return await tx.getRepository(DataSample).save({
@@ -36,7 +84,9 @@ export class DataSampleMutation {
36
84
  description: dataSet.description,
37
85
  ...dataSample,
38
86
  domain,
87
+ partitionKeys,
39
88
  spec,
89
+ collectedAt,
40
90
  creator: user,
41
91
  updater: user
42
92
  })
@@ -16,7 +16,16 @@ export class NewDataSample {
16
16
  dataSetId?: string
17
17
 
18
18
  @Field(type => ScalarObject, { nullable: true })
19
- data?: object
19
+ data?: ScalarObject
20
+
21
+ @Field({ nullable: true })
22
+ rawData?: string
23
+
24
+ @Field({ nullable: true })
25
+ source?: string
26
+
27
+ @Field({ nullable: true })
28
+ collectedAt?: Date
20
29
  }
21
30
 
22
31
  @InputType()
@@ -34,7 +43,13 @@ export class DataSamplePatch {
34
43
  dataSetId?: string
35
44
 
36
45
  @Field(type => ScalarObject, { nullable: true })
37
- data?: object
46
+ data?: ScalarObject
47
+
48
+ @Field({ nullable: true })
49
+ rawData?: string
50
+
51
+ @Field({ nullable: true })
52
+ source?: string
38
53
 
39
54
  @Field()
40
55
  cuFlag: string
@@ -11,10 +11,13 @@ import {
11
11
  } from 'typeorm'
12
12
 
13
13
  import { User } from '@things-factory/auth-base'
14
+ import { config } from '@things-factory/env'
14
15
  import { Domain, ScalarObject } from '@things-factory/shell'
15
16
 
16
17
  import { DataSet } from '../data-set/data-set'
17
18
 
19
+ const ORMCONFIG = config.get('ormconfig', {})
20
+ const DATABASE_TYPE = ORMCONFIG.type
18
21
  @Entity()
19
22
  @Index('ix_data_sample_0', (dataSample: DataSample) => [dataSample.domain, dataSample.dataSet], { unique: false })
20
23
  @ObjectType({ description: 'Entity for DataSample' })
@@ -40,6 +43,16 @@ export class DataSample {
40
43
  @Field({ nullable: true })
41
44
  description?: string
42
45
 
46
+ @Column({
47
+ nullable: true
48
+ })
49
+ @Field({ nullable: true })
50
+ type?: string
51
+
52
+ @Column('simple-json', { nullable: true })
53
+ @Field(type => ScalarObject, { nullable: true })
54
+ partitionKeys?: ScalarObject
55
+
43
56
  @ManyToOne(type => DataSet, dataSet => dataSet.dataSamples)
44
57
  @Field(type => DataSet, { nullable: true })
45
58
  dataSet?: DataSet
@@ -50,11 +63,33 @@ export class DataSample {
50
63
 
51
64
  @Column('simple-json', { nullable: true })
52
65
  @Field(type => ScalarObject, { nullable: true })
53
- data?: object
66
+ data?: ScalarObject
54
67
 
55
68
  @Column('simple-json', { nullable: true })
56
69
  @Field(type => ScalarObject, { nullable: true })
57
- spec?: object
70
+ spec?: ScalarObject
71
+
72
+ @Column({
73
+ nullable: true,
74
+ type:
75
+ DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
76
+ ? 'longtext'
77
+ : DATABASE_TYPE == 'oracle'
78
+ ? 'clob'
79
+ : 'varchar'
80
+ })
81
+ @Field({ nullable: true })
82
+ rawData?: string
83
+
84
+ @Column({
85
+ nullable: true
86
+ })
87
+ @Field({ nullable: true })
88
+ source?: string
89
+
90
+ @Column({ nullable: true })
91
+ @Field({ nullable: true })
92
+ collectedAt?: Date
58
93
 
59
94
  @CreateDateColumn()
60
95
  @Field({ nullable: true })
@@ -0,0 +1,110 @@
1
+ import { Arg, Ctx, Directive, Mutation, Resolver } from 'type-graphql'
2
+ import { In } from 'typeorm'
3
+
4
+ import { DataSensor } from './data-sensor'
5
+ import { DataSensorPatch, NewDataSensor } from './data-sensor-type'
6
+
7
+ @Resolver(DataSensor)
8
+ export class DataSensorMutation {
9
+ @Directive('@transaction')
10
+ @Mutation(returns => DataSensor, { description: 'To create new DataSensor' })
11
+ async createDataSensor(@Arg('dataSensor') dataSensor: NewDataSensor, @Ctx() context: any): Promise<DataSensor> {
12
+ const { domain, user, tx } = context.state
13
+
14
+ return await tx.getRepository(DataSensor).save({
15
+ ...dataSensor,
16
+ domain,
17
+ creator: user,
18
+ updater: user
19
+ })
20
+ }
21
+
22
+ @Directive('@transaction')
23
+ @Mutation(returns => DataSensor, { description: 'To modify DataSensor information' })
24
+ async updateDataSensor(
25
+ @Arg('id') id: string,
26
+ @Arg('patch') patch: DataSensorPatch,
27
+ @Ctx() context: any
28
+ ): Promise<DataSensor> {
29
+ const { domain, user, tx } = context.state
30
+
31
+ const repository = tx.getRepository(DataSensor)
32
+ const dataSensor = await repository.findOne({
33
+ where: { domain, id }
34
+ })
35
+
36
+ return await repository.save({
37
+ ...dataSensor,
38
+ ...patch,
39
+ updater: user
40
+ })
41
+ }
42
+
43
+ @Directive('@transaction')
44
+ @Mutation(returns => [DataSensor], { description: "To modify multiple DataSensors' information" })
45
+ async updateMultipleDataSensor(
46
+ @Arg('patches', type => [DataSensorPatch]) patches: DataSensorPatch[],
47
+ @Ctx() context: any
48
+ ): Promise<DataSensor[]> {
49
+ const { domain, user, tx } = context.state
50
+
51
+ let results = []
52
+ const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
53
+ const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
54
+ const dataSensorRepo = tx.getRepository(DataSensor)
55
+
56
+ if (_createRecords.length > 0) {
57
+ for (let i = 0; i < _createRecords.length; i++) {
58
+ const newRecord = _createRecords[i]
59
+
60
+ const result = await dataSensorRepo.save({
61
+ ...newRecord,
62
+ domain,
63
+ creator: user,
64
+ updater: user
65
+ })
66
+
67
+ results.push({ ...result, cuFlag: '+' })
68
+ }
69
+ }
70
+
71
+ if (_updateRecords.length > 0) {
72
+ for (let i = 0; i < _updateRecords.length; i++) {
73
+ const newRecord = _updateRecords[i]
74
+ const dataSensor = await dataSensorRepo.findOne(newRecord.id)
75
+
76
+ const result = await dataSensorRepo.save({
77
+ ...dataSensor,
78
+ ...newRecord,
79
+ updater: user
80
+ })
81
+
82
+ results.push({ ...result, cuFlag: 'M' })
83
+ }
84
+ }
85
+
86
+ return results
87
+ }
88
+
89
+ @Directive('@transaction')
90
+ @Mutation(returns => Boolean, { description: 'To delete DataSensor' })
91
+ async deleteDataSensor(@Arg('id') id: string, @Ctx() context: any): Promise<boolean> {
92
+ const { domain, tx } = context.state
93
+
94
+ await tx.getRepository(DataSensor).delete({ domain, id })
95
+ return true
96
+ }
97
+
98
+ @Directive('@transaction')
99
+ @Mutation(returns => Boolean, { description: 'To delete multiple dataSensors' })
100
+ async deleteDataSensors(@Arg('ids', type => [String]) ids: string[], @Ctx() context: any): Promise<boolean> {
101
+ const { domain, tx } = context.state
102
+
103
+ await tx.getRepository(DataSensor).delete({
104
+ domain,
105
+ id: In(ids)
106
+ })
107
+
108
+ return true
109
+ }
110
+ }
@@ -0,0 +1,56 @@
1
+ import { Arg, Args, Ctx, FieldResolver, Query, Resolver, Root } from 'type-graphql'
2
+ import { getRepository } from 'typeorm'
3
+
4
+ import { Appliance, User } from '@things-factory/auth-base'
5
+ import { convertListParams, Domain, ListParam } from '@things-factory/shell'
6
+
7
+ import { DataSet } from '../data-set/data-set'
8
+ import { DataSensor } from './data-sensor'
9
+ import { DataSensorList } from './data-sensor-type'
10
+
11
+ @Resolver(DataSensor)
12
+ export class DataSensorQuery {
13
+ @Query(returns => DataSensor, { description: 'To fetch a DataSensor' })
14
+ async dataSensor(@Arg('id') id: string, @Ctx() context: any): Promise<DataSensor> {
15
+ const { domain } = context.state
16
+
17
+ return await getRepository(DataSensor).findOne({
18
+ where: { domain, id }
19
+ })
20
+ }
21
+
22
+ @Query(returns => DataSensorList, { description: 'To fetch multiple DataSensors' })
23
+ async dataSensors(@Args() params: ListParam, @Ctx() context: any): Promise<DataSensorList> {
24
+ const { domain } = context.state
25
+
26
+ const convertedParams = convertListParams(params, domain.id)
27
+ const [items, total] = await getRepository(DataSensor).findAndCount(convertedParams)
28
+
29
+ return { items, total }
30
+ }
31
+
32
+ @FieldResolver(type => Appliance)
33
+ async appliance(@Root() dataSensor: DataSensor): Promise<Appliance> {
34
+ return await getRepository(Appliance).findOne(dataSensor.applianceId || '')
35
+ }
36
+
37
+ @FieldResolver(type => Appliance)
38
+ async dataSet(@Root() dataSensor: DataSensor): Promise<DataSet> {
39
+ return await getRepository(DataSet).findOne(dataSensor.dataSetId || '')
40
+ }
41
+
42
+ @FieldResolver(type => Domain)
43
+ async domain(@Root() dataSensor: DataSensor): Promise<Domain> {
44
+ return await getRepository(Domain).findOne(dataSensor.domainId)
45
+ }
46
+
47
+ @FieldResolver(type => User)
48
+ async updater(@Root() dataSensor: DataSensor): Promise<User> {
49
+ return await getRepository(User).findOne(dataSensor.updaterId)
50
+ }
51
+
52
+ @FieldResolver(type => User)
53
+ async creator(@Root() dataSensor: DataSensor): Promise<User> {
54
+ return await getRepository(User).findOne(dataSensor.creatorId)
55
+ }
56
+ }