I'm creating a table to store user sessions in. I'm going to store the IP address as an integer, using these methods: IP-addresses stored as int results in overflow?
I would like to specify a getter and setter for the IP field so that it may automatically convert between an IP and int.
Unfortunately I get the following error and I have no idea what's happening. I've been trying to fix it for hours and Google yields me no results:
RangeError: Maximum call stack size exceeded
Model:
model = db.define(name, {
id: {type: Sequelize.STRING, allowNull: false, primaryKey: true},
ipAddress: {type: Sequelize.INTEGER(11).UNSIGNED, allowNull: false},
userAgent: {type: Sequelize.STRING, allowNull: false},
username: {type: Sequelize.STRING, allowNull: false},
password: {type: Sequelize.STRING, allowNull: false},
firstName: {type: Sequelize.STRING, allowNull: false},
lastName: {type: Sequelize.STRING, allowNull: false},
email: {type: Sequelize.STRING}
}, {
getterMethods: {
name: function() { return this.firstName + this.lastName },
ipAddress: function() {
ip = this.getDataValue("ipAddress");
return ((ip >> 24) & 255) + "." + ((ip >> 16) & 255) + "." + ((ip >> 8) & 255) + "." + (ip & 255);
}
},
setterMethods: {
ipAddress: function(ip) {
var parts = ip.split(".");
var ret = 0;
ret += parseInt(parts[0], 10) << 24;
ret += parseInt(parts[1], 10) << 16;
ret += parseInt(parts[2], 10) << 8;
ret += parseInt(parts[3], 10);
return ret;
}
}
});
Inserting an IP:
model.findOrCreate({id: sessionId}, {
id: sessionId,
ipAddress: req.ip, // === "192.168.1.79"
userAgent: req.get("user-agent"),
username: "test",
password: "test",
firstName: "first",
lastName: "last",
email: "email"
})
I can confirm that the getter/setter code does convert as desired, but it is not functioning in Sequelize properly.
I'm creating a table to store user sessions in. I'm going to store the IP address as an integer, using these methods: IP-addresses stored as int results in overflow?
I would like to specify a getter and setter for the IP field so that it may automatically convert between an IP and int.
Unfortunately I get the following error and I have no idea what's happening. I've been trying to fix it for hours and Google yields me no results:
RangeError: Maximum call stack size exceeded
Model:
model = db.define(name, {
id: {type: Sequelize.STRING, allowNull: false, primaryKey: true},
ipAddress: {type: Sequelize.INTEGER(11).UNSIGNED, allowNull: false},
userAgent: {type: Sequelize.STRING, allowNull: false},
username: {type: Sequelize.STRING, allowNull: false},
password: {type: Sequelize.STRING, allowNull: false},
firstName: {type: Sequelize.STRING, allowNull: false},
lastName: {type: Sequelize.STRING, allowNull: false},
email: {type: Sequelize.STRING}
}, {
getterMethods: {
name: function() { return this.firstName + this.lastName },
ipAddress: function() {
ip = this.getDataValue("ipAddress");
return ((ip >> 24) & 255) + "." + ((ip >> 16) & 255) + "." + ((ip >> 8) & 255) + "." + (ip & 255);
}
},
setterMethods: {
ipAddress: function(ip) {
var parts = ip.split(".");
var ret = 0;
ret += parseInt(parts[0], 10) << 24;
ret += parseInt(parts[1], 10) << 16;
ret += parseInt(parts[2], 10) << 8;
ret += parseInt(parts[3], 10);
return ret;
}
}
});
Inserting an IP:
model.findOrCreate({id: sessionId}, {
id: sessionId,
ipAddress: req.ip, // === "192.168.1.79"
userAgent: req.get("user-agent"),
username: "test",
password: "test",
firstName: "first",
lastName: "last",
email: "email"
})
I can confirm that the getter/setter code does convert as desired, but it is not functioning in Sequelize properly.
Share Improve this question edited May 23, 2017 at 11:45 CommunityBot 11 silver badge asked Aug 5, 2013 at 0:52 Jacob BrunsonJacob Brunson 1,4924 gold badges24 silver badges37 bronze badges3 Answers
Reset to default 5I too ran into this problem with Sequelize. I was reading and re-reading the official documentation, searching everywhere I knew to search on the internet, and I finally wound up here. Once I found your question, with no answers, I decided to search the source code of Sequelize itself. Sure enough, I found the answer!
If you look at the file sequelize/test/dao-factory.test.js
in Sequelize's source code, you'll discover the following bit of code lurking inside a test case:
setterMethods: {
price1: function(v) { this.setDataValue('price1', v * 100) }
},
I copied the syntax above, used it in my own setter method, and it works!
They really should update the documentation on the sequelize website.. Hmm.. Perhaps I should look into helping them out with that? Any way, best of luck to you!
I don't know if someone is still running this error, but if you are having troubles with this here is how I've solved the issue.
I had a similar situation where I had a UserModel object which was looking like this:
var UserModel = sequelize.define("users", {
ID: {
type: Sequelize.INTEGER,
field: "ID",
primaryKey: true,
autoIncrement: true
},
Username: {
type: Sequelize.STRING,
field: "Username"
},
Password: {
type: Sequelize.STRING,
field: "Password"
},
Sector: {
type: Sequelize.INTEGER,
field: "Sector"
},
SubSector: {
type: Sequelize.INTEGER,
field: "SubSector"
},
Email: {
type: Sequelize.STRING,
field: "email"
},
Status: {
type: Sequelize.INTEGER,
field: "status"
}
}
And my setters and getters were:
{
getterMethods: {
Sector: function() {
return this.Sector;
},
Status: function() {
return this.Status;
}
},
setterMethods: {
Sector: function(val) {
this.setDataValue('Sector',val);
},
Status: function(val) {
this.setDataValue('Status',val);
}
}
});
And of course I had the stack error.
To solve this, I've just changed my setters and getters to this:
{
getterMethods: {
currSector: function() {
return this.Sector;
},
currStatus: function() {
return this.Status;
}
},
setterMethods: {
newSector: function(val) {
this.setDataValue('Sector',val);
},
newStatus: function(val) {
this.setDataValue('Status',val);
}
}
});
And everything went magically well, despite in many examples online I've seen people suggesting the approach of providing the same setters / getters name as the fields.
So, in a nutshell, changing to setters and getters name so that their name won't match any of the defined fields solved my issue. Good practice? I'm not sure, but it solved my problem.
I had a similar situation and I resolve in this way
const ProductImages = db.define('product_images', {
product_image_id: {type: Sequelize.INTEGER, primaryKey: true,
autoIncrement: true},
url: Sequelize.TEXT,
product_id: Sequelize.INTEGER,
is_primary: Sequelize.INTEGER,
}, {
timestamps: false,
getterMethods: {
is_primary() {
return parseInt(this.dataValues.is_primary)
},
},
scopes: {
byDefault() {
return {
include: [{
model: ProductDescriptions, as:
'product_description', where: {language_id: 1}
}]
};
},
}
})
module.exports = ProductImages;
When I call this.davaValues.column_name it not call recoursive getterMethod for that column