// // NpgsqlSkillProvider.cs // // Author: // Paul Schneider // // Copyright (c) 2015 GNU GPL // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . using System; using Yavsc.Model.Skill; using System.Configuration; using System.Collections.Specialized; using System.Collections.Generic; using Npgsql; using NpgsqlTypes; using Yavsc.Model.FrontOffice; namespace WorkFlowProvider { /// /// Npgsql skill provider. /// public class NpgsqlSkillProvider : SkillProvider { /// /// Initializes a new instance of the class. /// public NpgsqlSkillProvider () { } string connectionString = null; string applicationName = null; /// /// Initialize this object using the specified name and config. /// /// Name. /// Config. public override void Initialize (string name, NameValueCollection config) { if (string.IsNullOrWhiteSpace (config ["connectionStringName"])) throw new ConfigurationErrorsException ("No name for Npgsql connection string found"); connectionString = ConfigurationManager.ConnectionStrings [config ["connectionStringName"]].ConnectionString; applicationName = config ["applicationName"] ?? "/"; } #region implemented abstract members of SkillProvider /// /// Gets the user skills. /// /// The user skills. /// Username. public override PerformerProfile GetUserSkills (string username) { var skills = new List (); var profile = new PerformerProfile (username); using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "select p.uniqueid, d.rate, d.MEACode, u.email " + " from users u, profiles p, profiledata d where " + " u.username = :user and u.applicationname = :app " + " and p.username = u.username " + " and p.applicationname = u.applicationname " + " and p.uniqueid = d.uniqueid "; cmd.Parameters.AddWithValue ("user", NpgsqlTypes.NpgsqlDbType.Varchar, username); cmd.Parameters.AddWithValue ("app", NpgsqlTypes.NpgsqlDbType.Varchar, applicationName); using (var rdr = cmd.ExecuteReader ()) { rdr.Read (); profile.Id = rdr.GetInt64 (0); profile.Rate = rdr.GetInt32 (1); profile.MEACode = rdr.GetString (2); profile.EMail = rdr.GetString (3); } } using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = " select u._id, u.skillid, s.name, " + " u.comment, u.rate from userskills u, " + " skill s " + " where u.skillid = s._id and " + " u.username = :uname " + " and s.applicationname = u.applicationname " + " and s.applicationname = :app " + " and s.meacode = :mea " + " order by u.rate desc "; cmd.Parameters.AddWithValue ("uname", NpgsqlTypes.NpgsqlDbType.Varchar, username); cmd.Parameters.AddWithValue ("app", NpgsqlTypes.NpgsqlDbType.Varchar, applicationName); cmd.Parameters.AddWithValue ("mea", NpgsqlTypes.NpgsqlDbType.Varchar, profile.MEACode); cmd.Prepare (); using (var rdr = cmd.ExecuteReader ()) { if (rdr.HasRows) while (rdr.Read ()) { skills.Add (new UserSkill () { Id = rdr.GetInt64 (0), SkillId = rdr.GetInt64 (1), SkillName = rdr.GetString (2), Comment = rdr.GetString (3), Rate = rdr.GetInt32 (4) }); } profile.Skills = skills.ToArray (); } } cnx.Close (); } return profile; } /// /// Create the specified skill. /// /// skill. public override long Declare (SkillEntity skill) { long res = 0; using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); if (skill.Id == 0) { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "insert into skill (name,meacode,rate,applicationname) " + " values (:name,:mea,:rate,:app) " + " returning _id "; cmd.Parameters.AddWithValue ("name", NpgsqlTypes.NpgsqlDbType.Varchar, skill.Name); cmd.Parameters.AddWithValue ("mea", NpgsqlTypes.NpgsqlDbType.Varchar, skill.MEACode); cmd.Parameters.AddWithValue ("rate", NpgsqlTypes.NpgsqlDbType.Integer, skill.Rate); cmd.Parameters.AddWithValue ("app", NpgsqlTypes.NpgsqlDbType.Varchar, applicationName); res = (long)cmd.ExecuteScalar (); } } else { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "update skill set name = :name, rate = :rate where _id = :sid"; cmd.Parameters.AddWithValue ("name", NpgsqlTypes.NpgsqlDbType.Bigint, skill.Id); cmd.Parameters.AddWithValue ("rate", NpgsqlTypes.NpgsqlDbType.Integer, skill.Rate); cmd.ExecuteNonQuery (); } } cnx.Close (); } return res; } /// /// Declares the userskill. /// /// The userskill. /// userskill. public override long Declare (UserSkillDeclaration userskill) { long res = 0; using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); if (userskill.Id == 0) { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { if (userskill.Comment == null) userskill.Comment = ""; cmd.CommandText = "insert into userskills" + " (username, applicationname, skillid, rate, comment) " + " values (:uname,:app,:sid,:rate,:cmnt) returning _id"; cmd.Parameters.AddWithValue ("uname", NpgsqlTypes.NpgsqlDbType.Varchar, userskill.UserName); cmd.Parameters.AddWithValue ("app", NpgsqlTypes.NpgsqlDbType.Varchar, applicationName); cmd.Parameters.AddWithValue ("sid", NpgsqlTypes.NpgsqlDbType.Bigint, userskill.SkillId); cmd.Parameters.AddWithValue ("rate", NpgsqlTypes.NpgsqlDbType.Integer, userskill.Rate); cmd.Parameters.AddWithValue ("cmnt", NpgsqlTypes.NpgsqlDbType.Varchar, userskill.Comment); userskill.Id = res = (long)cmd.ExecuteScalar (); } } else { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "update userskills" + " set rate = :rate," + " comment = :cmnt) " + " where _id = :usid "; cmd.Parameters.AddWithValue ("cmnt", NpgsqlTypes.NpgsqlDbType.Varchar, userskill.Comment); cmd.Parameters.AddWithValue ("rate", NpgsqlTypes.NpgsqlDbType.Integer, userskill.Rate); cmd.Parameters.AddWithValue ("usid", NpgsqlTypes.NpgsqlDbType.Bigint, userskill.Id); cmd.ExecuteNonQuery (); } } cnx.Close (); } return res; } /// /// Rate the specified user's skill. /// It creates the record describing the user's skill /// if not existent. /// /// UserSkillRating. public override long Rate (UserSkillRating userSkill) { // TODO Use the Author value to choose // between a self rating that goes into the `userskills` table // and a client rating that goes into the // `statisfaction` table. long usid = 0; using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); using (NpgsqlCommand cmd = cnx.CreateCommand ()) { if (userSkill.Id == 0) { cmd.CommandText = "insert into userskills " + " ( skillid, rate, username, applicationname ) " + " values ( :sid, :rate, :uname, :app ) " + " returning _id "; cmd.Parameters.AddWithValue ("sid", NpgsqlDbType.Bigint, userSkill.Id); cmd.Parameters.AddWithValue ("rate", NpgsqlDbType.Integer, userSkill.Rate); cmd.Parameters.AddWithValue ("uname", NpgsqlDbType.Varchar, userSkill.Performer); cmd.Parameters.AddWithValue ("app", NpgsqlDbType.Varchar, applicationName); usid = (long)cmd.ExecuteScalar (); } else { cmd.CommandText = "update userskills " + " set rate = :rate " + " where _id = :usid "; cmd.Parameters.AddWithValue ("rate", NpgsqlDbType.Integer, userSkill.Rate); cmd.Parameters.AddWithValue ("usid", NpgsqlDbType.Bigint, userSkill.Id); cmd.ExecuteNonQuery (); } } cnx.Close (); } return usid; } /// /// Rate the specified skill. /// The access to this method /// should be restricted to an Admin, /// or a rating engine /// /// Skill. public override void Rate (AuthentificatedSkillRating skill) { // TODO Use the Author value to choose // between a global setting for the application // and an user setting on his needs // when the `Author` value is not null, // it's concerning a rating on a need of the Author // if not, it's a need of the site using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "update skill set rate = :rate where _id = :sid"; cmd.Parameters.AddWithValue ("sid", NpgsqlTypes.NpgsqlDbType.Bigint, skill.Id); cmd.Parameters.AddWithValue ("rate", NpgsqlTypes.NpgsqlDbType.Integer, skill.Rate); cmd.ExecuteNonQuery (); } cnx.Close (); } } /// /// Finds the skills. /// /// The skill identifier. /// Pattern. /// MEA Code. public override SkillEntity[] FindSkill (string pattern, string MEACode) { List skills = new List (); using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "select _id, name, rate, meacode " + " from skill " + " where name like :name "; if (MEACode != null) cmd.CommandText += " and meacode = :mea "; cmd.CommandText += " and applicationname = :app " + " order by rate desc"; cmd.Parameters.AddWithValue ("name", NpgsqlTypes.NpgsqlDbType.Varchar, pattern); if (MEACode != null) cmd.Parameters.AddWithValue ("mea", NpgsqlTypes.NpgsqlDbType.Varchar, MEACode); cmd.Parameters.AddWithValue ("app", NpgsqlTypes.NpgsqlDbType.Varchar, applicationName); cmd.Prepare (); using (var rdr = cmd.ExecuteReader ()) { if (rdr.HasRows) while (rdr.Read ()) { skills.Add (new SkillEntity () { Id = (long)rdr.GetInt64 (0), Name = (string)rdr.GetString (1), Rate = (int)rdr.GetInt32 (2), MEACode = (string)rdr.GetString (3), }); } } } cnx.Close (); } return skills.ToArray (); } /// /// Finds the performer. /// /// The performer. /// MEACode. /// Skills. public override string[] FindPerformer (string MEACode, SkillRating [] skills) { var res = new List (); using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); if (skills != null) { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { // on cherche ici simplement les prestataires // ayant déclaré les compétences spécifiées. cmd.CommandText = @" select u.username from userskills s, profiledata p, profiles q, users u where s.username = u.username and s.applicationname = u.applicationname and s.skillid = :sid and p.meacode = :mea and u.username = q.username and u.applicationname = q.applicationname and p.uniqueid = q.uniqueid and u.applicationname = :app and u.islockedout = FALSE and u.isapproved = TRUE order by s.rate desc "; cmd.Parameters.AddWithValue ("sid", NpgsqlDbType.Bigint, 0); cmd.Parameters.AddWithValue ("app", NpgsqlDbType.Varchar, applicationName); cmd.Parameters.AddWithValue ("mea", NpgsqlDbType.Varchar, MEACode); cmd.Prepare (); foreach (SkillRating skill in skills) { cmd.Parameters ["sid"].Value = skill.Id; using (var rdr = cmd.ExecuteReader ()) { while (rdr.Read ()) { string uname = rdr.GetString (0); if (!res.Contains (uname)) res.Add (uname); } } } } } if (res.Count < 10) { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { // Si on a trouvé trop peu de prestataire ayant // déclaré ces compétences (moins de 10), // On en cherche un ayant // simplement déclaré avoir l'activité // concernée. // TODO implement a configuration parameter : cmd.CommandText = " select u.username " + " from profiledata p, profiles q, users u " + " where u.username = q.username " + " and u.applicationname = q.applicationname " + " and p.uniqueid = q.uniqueid " + " and p.meacode = :mea " + " and u.applicationname = :app " + " and u.islockedout = FALSE " + " and u.isapproved = TRUE " + " order by p.rate desc " ; cmd.Parameters.AddWithValue ("app", NpgsqlDbType.Varchar, applicationName); cmd.Parameters.AddWithValue ("mea", NpgsqlDbType.Varchar, MEACode); using (var rdr = cmd.ExecuteReader ()) { while (rdr.Read ()) { string uname = rdr.GetString (0); if (!res.Contains (uname)) res.Add (uname); } } } } cnx.Close (); } return res.ToArray (); } /// /// Deletes the skill. /// /// Skill identifier. public override void DeleteSkill (long skillId) { using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = " delete from skill " + " where _id = :sid "; cmd.Parameters.AddWithValue ("sid", NpgsqlTypes.NpgsqlDbType.Bigint, skillId); cmd.ExecuteNonQuery (); } cnx.Close (); } } /// /// Deletes the user skill. /// /// User skill identifier. public override void DeleteUserSkill (long userSkillId) { using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = " delete from userskills " + " where _id = :usid "; cmd.Parameters.AddWithValue ("usid", NpgsqlTypes.NpgsqlDbType.Bigint, userSkillId); cmd.ExecuteNonQuery (); } cnx.Close (); } } #endregion } }