Skip to content

Commit b6510df

Browse files
committed
feat(model): complete getAttributes feature
1 parent 65df938 commit b6510df

7 files changed

Lines changed: 112 additions & 26 deletions

File tree

lib/model.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,13 @@ class Model {
288288
this.primaryKeys.id = this.rawAttributes.id;
289289
}
290290
}
291-
/*
292-
returns object of attributes
293-
*/
294291

295-
static getAttributes(){
292+
/**
293+
* Returns the attributes of the model.
294+
*
295+
* @returns {object|any}
296+
*/
297+
static getAttributes() {
296298
return this.rawAttributes;
297299
}
298300

lib/sequelize.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ class Sequelize {
341341
break;
342342
case 'db2':
343343
Dialect = require('./dialects/db2');
344-
break;
344+
break;
345345
case 'snowflake':
346346
Dialect = require('./dialects/snowflake');
347347
break;
Lines changed: 97 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,101 @@
11
'use strict';
22

3-
const chai = require('chai'),
4-
expect = chai.expect,
5-
Support = require('../support'),
6-
current = Support.sequelize,
7-
_ = require('lodash'),
8-
DataTypes = require('sequelize/lib/data-types');
9-
10-
describe(Support.getTestDialectTeaser('Model'), () => {
11-
describe('getAttributes', () => {
12-
it('should return attributes with getAttributes()', () => {
13-
const Model = current.define('User', {
14-
username:DataTypes.STRING,
15-
}, {
16-
timestamps: false
17-
});
18-
expect(Model.getAttributes()).to.haveOwnProperty('username');
19-
});
3+
const chai = require('chai');
4+
const expect = chai.expect;
5+
const Support = require('../support');
6+
const current = Support.sequelize;
7+
const _ = require('lodash');
8+
const DataTypes = require('sequelize/lib/data-types');
9+
10+
describe(Support.getTestDialectTeaser('Model'), () => {
11+
describe('getAttributes', () => {
12+
it('should return attributes with getAttributes()', () => {
13+
const Model = current.define(
14+
'User',
15+
{ username: DataTypes.STRING },
16+
{ timestamps: false }
17+
);
18+
const attributes = Model.getAttributes();
19+
20+
expect(Object.keys(attributes)).to.eql(['id', 'username']);
21+
22+
// Type must be casted or it will cause circular references errors
23+
expect(attributes.id.type.toString()).to.equal('INTEGER');
24+
expect(attributes.username.type.toString()).to.equal('VARCHAR(255)');
25+
26+
expect(attributes.id).to.include({
27+
Model,
28+
allowNull: false,
29+
primaryKey: true,
30+
autoIncrement: true,
31+
_autoGenerated: true,
32+
fieldName: 'id',
33+
_modelAttribute: true,
34+
field: 'id'
35+
});
36+
expect(attributes.username).to.include({
37+
Model,
38+
fieldName: 'username',
39+
_modelAttribute: true,
40+
field: 'username'
41+
});
42+
});
43+
44+
it('will contain timestamps if enabled', () => {
45+
const Model = current.define('User', { username: DataTypes.STRING });
46+
const attributes = Model.getAttributes();
47+
48+
expect(Object.keys(attributes)).to.include.members([
49+
'createdAt',
50+
'updatedAt'
51+
]);
52+
53+
// Type must be casted or it will cause circular references errors
54+
expect(attributes.createdAt.type.toString()).to.equal('DATETIME');
55+
expect(attributes.updatedAt.type.toString()).to.equal('DATETIME');
56+
57+
expect(attributes.createdAt).to.include({
58+
allowNull: false,
59+
_autoGenerated: true,
60+
Model,
61+
fieldName: 'createdAt',
62+
_modelAttribute: true,
63+
field: 'createdAt'
64+
});
65+
expect(attributes.updatedAt).to.include({
66+
allowNull: false,
67+
_autoGenerated: true,
68+
Model,
69+
fieldName: 'updatedAt',
70+
_modelAttribute: true,
71+
field: 'updatedAt'
72+
});
73+
});
74+
75+
it('will contain timestamps if enabled', () => {
76+
const Model = current.define(
77+
'User',
78+
{
79+
username: DataTypes.STRING,
80+
virtual: {
81+
type: DataTypes.VIRTUAL,
82+
get() {
83+
return 1;
84+
}
85+
}
86+
},
87+
{ timestamps: false }
88+
);
89+
const attributes = Model.getAttributes();
90+
91+
expect(Object.keys(attributes)).to.include.members(['virtual']);
92+
expect(attributes.virtual.type.toString()).to.equal('VIRTUAL');
93+
expect(attributes.virtual).to.include({
94+
Model,
95+
fieldName: 'virtual',
96+
_modelAttribute: true,
97+
field: 'virtual'
98+
});
2099
});
21100
});
22-
101+
});

test/unit/sql/delete.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => {
124124
sqlite: "DELETE FROM `public.test_users` WHERE rowid IN (SELECT rowid FROM `public.test_users` WHERE `name` = 'foo'';DROP TABLE mySchema.myTable;' LIMIT 10)",
125125
mssql: "DELETE TOP(10) FROM [public].[test_users] WHERE [name] = N'foo'';DROP TABLE mySchema.myTable;'; SELECT @@ROWCOUNT AS AFFECTEDROWS;",
126126
db2: "DELETE FROM \"public\".\"test_users\" WHERE \"name\" = 'foo'';DROP TABLE mySchema.myTable;' FETCH NEXT 10 ROWS ONLY",
127-
snowflake: 'DELETE FROM "public"."test_users" WHERE "id" IN (SELECT "id" FROM "public"."test_users" WHERE "name" = \'foo\'\';DROP TABLE mySchema.myTable;\' LIMIT 10);',
127+
snowflake: 'DELETE FROM "public"."test_users" WHERE "id" IN (SELECT "id" FROM "public"."test_users" WHERE "name" = \'foo\'\';DROP TABLE mySchema.myTable;\' LIMIT 10);',
128128
default: "DELETE FROM [public.test_users] WHERE `name` = 'foo\\';DROP TABLE mySchema.myTable;' LIMIT 10"
129129
}
130130
);

test/unit/sql/insert.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ describe(Support.getTestDialectTeaser('SQL'), () => {
3131
mssql: 'DECLARE @tmp TABLE ([id] INTEGER,[user_name] NVARCHAR(255)); INSERT INTO [users] ([user_name]) OUTPUT INSERTED.[id],INSERTED.[user_name] INTO @tmp VALUES ($1); SELECT * FROM @tmp;',
3232
postgres: 'INSERT INTO "users" ("user_name") VALUES ($1) RETURNING "id","user_name";',
3333
db2: 'SELECT * FROM FINAL TABLE(INSERT INTO "users" ("user_name") VALUES ($1));',
34-
snowflake: 'INSERT INTO "users" ("user_name") VALUES ($1);',
34+
snowflake: 'INSERT INTO "users" ("user_name") VALUES ($1);',
3535
default: 'INSERT INTO `users` (`user_name`) VALUES ($1);'
3636
},
3737
bind: ['triggertest']

types/lib/model.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1602,8 +1602,11 @@ export abstract class Model<TModelAttributes extends {} = any, TCreationAttribut
16021602
* The attributes of the model
16031603
*/
16041604
public static readonly rawAttributes: { [attribute: string]: ModelAttributeColumnOptions };
1605-
public static getAttributes(): { [attribute: string]: ModelAttributeColumnOptions };
16061605

1606+
/**
1607+
* Returns the attributes of the model
1608+
*/
1609+
public static getAttributes(): { [attribute: string]: ModelAttributeColumnOptions };
16071610

16081611
/**
16091612
* Reference to the sequelize instance the model was initialized with

types/test/model.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ UserModel.findCreateFind({
116116
}
117117
})
118118

119+
UserModel.getAttributes();
120+
119121
/**
120122
* Tests for findOrCreate() type.
121123
*/

0 commit comments

Comments
 (0)