init
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
using DTS.Common.Interface.Tags;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
// ReSharper disable InconsistentNaming
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace DTS.Common.Classes.Tags
|
||||
{
|
||||
public class TagsInstance
|
||||
{
|
||||
private static TagsInstance _tagsInstance;
|
||||
public static TagsInstance GetTagsInstance(TagsGetDelegate tagsGet)
|
||||
{
|
||||
if (null == _tagsInstance)
|
||||
{
|
||||
_tagsInstance = new TagsInstance(tagsGet);
|
||||
}
|
||||
return _tagsInstance;
|
||||
}
|
||||
private static readonly object LOCK_OBJECT = new object();
|
||||
public TagsInstance(TagsGetDelegate tagsGet)
|
||||
{
|
||||
_tagsLookup = new Dictionary<string, ITag>();
|
||||
UpdateList(tagsGet);
|
||||
}
|
||||
/// <summary>
|
||||
/// holds a cached collection of tags. This collection however is currently only populated on startup
|
||||
/// and not updated except explicitly when a user adds a tag
|
||||
/// </summary>
|
||||
// ReSharper disable once RedundantDefaultMemberInitializer
|
||||
private readonly Dictionary<string, ITag> _tagsLookup = null;
|
||||
|
||||
/// <summary>
|
||||
/// Adds a tag if not present in memory cache to db
|
||||
/// </summary>
|
||||
/// <param name="tagText"></param>
|
||||
/// <returns></returns>
|
||||
public static bool AddTag(string tagText, GetSqlCommandDelegate getSqlCommand, TagsGetDelegate tagsGet,
|
||||
TagsGetIdDelegate tagsGetId, TagsInsertDelegate tagsInsert)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tagText)) { return false; }
|
||||
|
||||
// is it already in the dictionary?
|
||||
var tags = GetTagsInstance(tagsGet);
|
||||
if (tags.ContainsTag(tagText)) return false;
|
||||
tags.Commit(new Tag(tagText, Tag.INVALID_ID), tagsGet, tagsGetId, tagsInsert);
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
/// Changes the ID of a tag during database migration
|
||||
/// </summary>
|
||||
/// <param name="tagText"></param>
|
||||
/// <returns></returns>
|
||||
public static bool MigrateTag(string tagText, GetSqlCommandDelegate getSqlCommand, TagsGetDelegate tagsGet,
|
||||
TagsGetIdDelegate tagsGetId, TagsInsertDelegate tagsInsert)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tagText)) { return false; }
|
||||
|
||||
GetTagsInstance(tagsGet).Commit(new Tag(tagText, Tag.INVALID_ID), tagsGet, tagsGetId, tagsInsert);
|
||||
return true;
|
||||
}
|
||||
/// <summary>
|
||||
/// commits a tag to db if doesn't already exist in db
|
||||
/// </summary>
|
||||
/// <param name="tag"></param>
|
||||
private void Commit(Tag tag, TagsGetDelegate tagsGet,
|
||||
TagsGetIdDelegate tagsGetId, TagsInsertDelegate tagsInsert)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (-1 == GetIDFromTagText(tag.Text, tagsGet, tagsGetId))
|
||||
{
|
||||
Insert(tag, tagsInsert);
|
||||
}
|
||||
else { UpdateAll(tag, tagsGetId); }
|
||||
|
||||
lock (LOCK_OBJECT)
|
||||
{
|
||||
_tagsLookup[tag.Text] = tag;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(ex);
|
||||
}
|
||||
}
|
||||
private void UpdateAll(Tag tag, TagsGetIdDelegate tagsGetId)
|
||||
{
|
||||
//nothing to do currently? (we don't let you rename or edit, or obsolete, or delete ...)
|
||||
tag.ID = GetTagIdFromText(tag.Text, tagsGetId);
|
||||
}
|
||||
public delegate ulong TagAssignmentsGet(TagTypes? tagType, out ITagAssignment[] records);
|
||||
public delegate SqlCommand GetSqlCommandDelegate(bool bNewConnection);
|
||||
public delegate ulong TagAssignmentsDelete(TagTypes objectType, int objectId);
|
||||
public delegate ulong TagAssignmentsInsert(ITagAssignment tagAssignment);
|
||||
public delegate ulong TagsGetIdDelegate(string text, out int? id);
|
||||
public delegate ulong TagsGetDelegate(int? id, out ITag[] tags);
|
||||
public delegate ulong TagsInsertDelegate(ref ITag tag);
|
||||
/// <summary>
|
||||
/// inserts a tag into the db
|
||||
/// </summary>
|
||||
/// <param name="tag"></param>
|
||||
private void Insert(Tag tag, TagsInsertDelegate tagsInsert)
|
||||
{
|
||||
var itag = (ITag)tag;
|
||||
_ = tagsInsert(ref itag);
|
||||
}
|
||||
/// <summary>
|
||||
/// retrieves a string text associated with an ID FROM CACHED copies
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
private string GetTagTextFromId(int id)
|
||||
{
|
||||
lock (LOCK_OBJECT)
|
||||
{
|
||||
if (_tagsLookup == null) return null;
|
||||
var e = _tagsLookup.GetEnumerator();
|
||||
while (e.MoveNext())
|
||||
{
|
||||
if (e.Current.Value.ID != id) continue;
|
||||
var returnText = e.Current.Value.Text;
|
||||
e.Dispose();
|
||||
return returnText;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets an ID for a given tag text FROM DB
|
||||
/// returns InvalidID if not found
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
private int GetTagIdFromText(string text, TagsGetIdDelegate tagsGetId)
|
||||
{
|
||||
var hr = tagsGetId(text, out var id);
|
||||
if (0 != hr || null == id)
|
||||
{
|
||||
return Tag.INVALID_ID;
|
||||
}
|
||||
return (int)id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns true if a given tag text is contained in cached in memory tags
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <returns></returns>
|
||||
public bool ContainsTag(string text)
|
||||
{
|
||||
lock (LOCK_OBJECT)
|
||||
{
|
||||
return _tagsLookup.ContainsKey(text);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// adds multiple tags at once
|
||||
/// note that tags will have their start trimmed before commiting
|
||||
/// </summary>
|
||||
/// <param name="tagText"></param>
|
||||
/// <returns></returns>
|
||||
public static bool[] AddRange(string[] tagText, GetSqlCommandDelegate getSqlCommand,
|
||||
TagsGetDelegate tagsGet, TagsGetIdDelegate tagsGetId, TagsInsertDelegate tagsInsert)
|
||||
{
|
||||
List<bool> rv = new List<bool>();
|
||||
if (null == tagText || 0 == tagText.Length) { return null; }
|
||||
foreach (string s in tagText)
|
||||
{
|
||||
var tag = s.TrimStart();
|
||||
rv.Add(AddTag(tag, getSqlCommand, tagsGet, tagsGetId, tagsInsert));
|
||||
}
|
||||
return rv.ToArray();
|
||||
}
|
||||
/// <summary>
|
||||
/// gets an ID for a given tag text FROM DB
|
||||
/// </summary>
|
||||
/// <param name="tagText"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetIDFromTagText(string tagText, TagsGetDelegate tagsGet,
|
||||
TagsGetIdDelegate tagsGetId)
|
||||
{
|
||||
return GetTagsInstance(tagsGet).GetTagIdFromText(tagText, tagsGetId);
|
||||
}
|
||||
/// <summary>
|
||||
/// gets an array of ids given an array of tag texts
|
||||
/// </summary>
|
||||
/// <param name="tagText"></param>
|
||||
/// <returns></returns>
|
||||
public static int[] GetIDsFromTagText(string[] tagText, TagsGetDelegate tagsGet,
|
||||
TagsGetIdDelegate tagsGetId)
|
||||
{
|
||||
if (null == tagText || 0 == tagText.Length) { return null; }
|
||||
|
||||
return tagText.Select(s => s.TrimStart()).Select(text => GetIDFromTagText(text, tagsGet, tagsGetId))
|
||||
.Where(id => id != Tag.INVALID_ID).ToArray();
|
||||
}
|
||||
/// <summary>
|
||||
/// returns a string for a given id from memory cache
|
||||
/// returns null if it doesn't exist or is an invalid id
|
||||
/// </summary>
|
||||
/// <param name="tagID"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetTagTextFromID(int tagID, TagsGetDelegate tagsGet)
|
||||
{
|
||||
if (0 > tagID || tagID == Tag.INVALID_ID)
|
||||
{
|
||||
// Not a valid ID
|
||||
return null;
|
||||
}
|
||||
return GetTagsInstance(tagsGet).GetTagTextFromId(tagID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// returns an array of tag text given an array of tag ids.
|
||||
/// skips invalid tags or tag text
|
||||
/// </summary>
|
||||
/// <param name="tagId"></param>
|
||||
/// <returns></returns>
|
||||
public static string[] GetTagTextFromIDs(int[] tagId, TagsGetDelegate tagsGet)
|
||||
{
|
||||
if (null == tagId || 0 == tagId.Length) { return new string[0]; }
|
||||
|
||||
return tagId.Where(i => i != Tag.INVALID_ID).Select(i => GetTagTextFromID(i, tagsGet)).Where(tag => !string.IsNullOrWhiteSpace(tag)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// retrieves all tags and updates the cached dictionary of tags
|
||||
/// </summary>
|
||||
public void UpdateList(TagsGetDelegate tagsGet)
|
||||
{
|
||||
var hr = tagsGet(null, out var tags);
|
||||
if (0 == hr && null != tags && tags.Any())
|
||||
{
|
||||
lock (LOCK_OBJECT)
|
||||
{
|
||||
_tagsLookup.Clear();
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
_tagsLookup[tag.Text] = tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user