class Guff::UserModel < Guff::Model SQL = TemplateCache.new({ add_user: " INSERT INTO users(user_name) VALUES (:user_name) ", update_user: " UPDATE users SET %{sets} WHERE user_id = :user_id ", delete_login: " DELETE FROM user_logins WHERE user_id = :user_id ", add_login: " INSERT INTO user_logins(user_id, email, pass_hash) VALUES (:user_id, :email, :pass_hash) ", }) def initialize(models : Models) super(models, SQL) end def add_user(user_name : String) query(:add_user, { "user_name": user_name }, nil) # return user id last_insert_row_id end def update_user( user_id : Int32, user_name : String? = nil, active : Boolean? = nil, ) sets = [] of String args = { "user_id": user_id.to_s } if user_name != nil sets << "user_name = :user_name" args["user_name"] = user_name end if active != nil sets << "is_active = :is_active" args["is_active"] = active ? "1" : "0" end query(:update_user, args, { "sets": sets.join(","), }) if sets.length > 0 end def delete_login(user_id : Int32) query(:delete_login, { "user_id": user_id.to_s }, nil) end def add_login( user_id : Int32, email : String, password : String, ) # TODO: check password strength raise "password too short" if password.length < 4 # hash password pass_hash = Crypto::Bcrypt::Password.create(password, cost: 10) transaction do # clear old credentials delete_login(user_id) # add new credentials query(:add_login, { "user_id": user_id.to_s, "email": email, "pass_hash": pass_hash, }, nil) end end end