451 lines
15 KiB
C#
451 lines
15 KiB
C#
//
|
|
// NpgsqlSkillProvider.cs
|
|
//
|
|
// Author:
|
|
// Paul Schneider <paul@pschneider.fr>
|
|
//
|
|
// 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 <http://www.gnu.org/licenses/>.
|
|
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
|
|
{
|
|
/// <summary>
|
|
/// Npgsql skill provider.
|
|
/// </summary>
|
|
public class NpgsqlSkillProvider : SkillProvider
|
|
{
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="WorkFlowProvider.NpgsqlSkillProvider"/> class.
|
|
/// </summary>
|
|
public NpgsqlSkillProvider ()
|
|
{
|
|
|
|
}
|
|
|
|
string connectionString = null;
|
|
string applicationName = null;
|
|
|
|
/// <summary>
|
|
/// Initialize this object using the specified name and config.
|
|
/// </summary>
|
|
/// <param name="name">Name.</param>
|
|
/// <param name="config">Config.</param>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Gets the user skills.
|
|
/// </summary>
|
|
/// <returns>The user skills.</returns>
|
|
/// <param name="username">Username.</param>
|
|
public override PerformerProfile GetUserSkills (string username)
|
|
{
|
|
var skills = new List <UserSkill> ();
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create the specified skill.
|
|
/// </summary>
|
|
/// <param name="skill">skill.</param>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Declares the userskill.
|
|
/// </summary>
|
|
/// <returns>The userskill.</returns>
|
|
/// <param name="userskill">userskill.</param>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Rate the specified user's skill.
|
|
/// It creates the record describing the user's skill
|
|
/// if not existent.
|
|
/// </summary>
|
|
/// <param name="userSkill">UserSkillRating.</param>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Rate the specified skill.
|
|
/// The access to this method
|
|
/// should be restricted to an Admin,
|
|
/// or a rating engine
|
|
/// </summary>
|
|
/// <param name="skill">Skill.</param>
|
|
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 ();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finds the skills.
|
|
/// </summary>
|
|
/// <returns>The skill identifier.</returns>
|
|
/// <param name="pattern">Pattern.</param>
|
|
/// <param name="MEACode">MEA Code.</param>
|
|
public override SkillEntity[] FindSkill (string pattern, string MEACode)
|
|
{
|
|
List<SkillEntity> skills = new List<SkillEntity> ();
|
|
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 ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finds the performer.
|
|
/// </summary>
|
|
/// <returns>The performer.</returns>
|
|
/// <param name="MEACode">MEACode.</param>
|
|
/// <param name="skills">Skills.</param>
|
|
public override string[] FindPerformer (string MEACode, SkillRating [] skills)
|
|
{
|
|
var res = new List<string> ();
|
|
|
|
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 ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes the skill.
|
|
/// </summary>
|
|
/// <param name="skillId">Skill identifier.</param>
|
|
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 ();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deletes the user skill.
|
|
/// </summary>
|
|
/// <param name="userSkillId">User skill identifier.</param>
|
|
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
|
|
}
|
|
}
|
|
|