コード例 #1
0
        /// <summary>
        /// Loads <see cref="Node"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <returns>Collection of <see cref="Subscriber"/>.</returns>
        public static ObservableCollection <Subscriber> Load(AdoDataConnection database)
        {
            ObservableCollection <Subscriber> subscriberList;
            DataTable subscriberTable;
            bool      createdConnection = false;
            string    query;

            SslPolicyErrors      validPolicyErrors;
            X509ChainStatusFlags validChainFlags;

            try
            {
                createdConnection = CreateConnection(ref database);
                subscriberList    = new ObservableCollection <Subscriber>();

                query = database.ParameterizedQueryString("SELECT ID, NodeID, Acronym, Name, SharedSecret, AuthKey, ValidIPAddresses, RemoteCertificateFile," +
                                                          " ValidPolicyErrors, ValidChainFlags, AccessControlFilter, Enabled FROM Subscriber WHERE NodeID = {0} ORDER BY Name", "nodeID");

                subscriberTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID());

                foreach (DataRow row in subscriberTable.Rows)
                {
                    subscriberList.Add(new Subscriber()
                    {
                        ID                         = database.Guid(row, "ID"),
                        NodeID                     = database.Guid(row, "NodeID"),
                        Acronym                    = row.Field <string>("Acronym"),
                        Name                       = row.Field <string>("Name"),
                        SharedSecret               = row.Field <string>("SharedSecret"),
                        AuthKey                    = row.Field <string>("AuthKey"),
                        ValidIPAddresses           = row.Field <string>("ValidIPAddresses"),
                        RemoteCertificateFile      = row.Field <string>("RemoteCertificateFile"),
                        ValidPolicyErrors          = Enum.TryParse(row.Field <string>("ValidPolicyErrors"), out validPolicyErrors) ? validPolicyErrors : (SslPolicyErrors?)null,
                        ValidChainFlags            = Enum.TryParse(row.Field <string>("ValidChainFlags"), out validChainFlags) ? validChainFlags : (X509ChainStatusFlags?)null,
                        AccessControlFilter        = row.Field <string>("AccessControlFilter"),
                        Enabled                    = Convert.ToBoolean(row.Field <object>("Enabled")),
                        AllowedMeasurements        = GetAllowedMeasurements(database, database.Guid(row, "ID")),
                        DeniedMeasurements         = GetDeniedMeasurements(database, database.Guid(row, "ID")),
                        AvailableMeasurements      = GetAvailableMeasurements(database, database.Guid(row, "ID")),
                        AllowedMeasurementGroups   = GetAllowedMeasurementGroups(database, database.Guid(row, "ID")),
                        DeniedMeasurementGroups    = GetDeniedMeasurementGroups(database, database.Guid(row, "ID")),
                        AvailableMeasurementGroups = GetAvailableMeasurementGroups(database, database.Guid(row, "ID")),
                        StatusColor                = "gray",
                        Version                    = ""
                    });
                }

                return(subscriberList);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Saves <see cref="Subscriber"/> information to database.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="subscriber">Information about <see cref="Subscriber"/>.</param>
        /// <returns>String, for display use, indicating success.</returns>
        public static string Save(AdoDataConnection database, Subscriber subscriber)
        {
            bool                 createdConnection = false;
            SslPolicyErrors      validPolicyErrors;
            X509ChainStatusFlags validChainFlags;
            string               query;

            try
            {
                createdConnection = CreateConnection(ref database);
                validPolicyErrors = (subscriber.ValidPolicyErrors ?? SslPolicyErrors.None) | (subscriber.RemoteCertificateIsSelfSigned ? SslPolicyErrors.RemoteCertificateChainErrors : SslPolicyErrors.None);
                validChainFlags   = (subscriber.ValidChainFlags ?? X509ChainStatusFlags.NoError) | (subscriber.RemoteCertificateIsSelfSigned ? X509ChainStatusFlags.UntrustedRoot : X509ChainStatusFlags.NoError);

                if (subscriber.ID == Guid.Empty)
                {
                    query = database.ParameterizedQueryString("INSERT INTO Subscriber (NodeID, Acronym, Name, SharedSecret, AuthKey, ValidIPAddresses, RemoteCertificateFile, ValidPolicyErrors, ValidChainFlags, " +
                                                              "AccessControlFilter, Enabled, UpdatedBy, UpdatedOn, CreatedBy, CreatedOn) VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, " +
                                                              "{13}, {14})", "nodeID", "acronym", "name", "sharedSecret", "authKey", "validIPAddresses", "remoteCertificateFile", "validPolicyErrors", "validChainFlags",
                                                              "accessControlFilter", "enabled", "updatedBy", "updatedOn", "createdBy", "createdOn");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.CurrentNodeID(), subscriber.Acronym, subscriber.Name.ToNotNull(), subscriber.SharedSecret.ToNotNull(),
                                                        subscriber.AuthKey.ToNotNull(), subscriber.ValidIPAddresses.ToNotNull(), subscriber.RemoteCertificateFile.ToNotNull(), validPolicyErrors.ToString(),
                                                        validChainFlags.ToString(), subscriber.AccessControlFilter.ToNotNull(), database.Bool(subscriber.Enabled), CommonFunctions.CurrentUser, database.UtcNow,
                                                        CommonFunctions.CurrentUser, database.UtcNow);
                }
                else
                {
                    query = database.ParameterizedQueryString("UPDATE Subscriber SET NodeID = {0}, Acronym = {1}, Name = {2}, SharedSecret = {3}, AuthKey = {4}, ValidIPAddresses = {5}, RemoteCertificateFile = {6}, " +
                                                              "ValidPolicyErrors = {7}, ValidChainFlags = {8}, AccessControlFilter = {9}, Enabled = {10}, UpdatedBy = {11}, UpdatedOn = {12} WHERE ID = {13}", "nodeID",
                                                              "acronym", "name", "sharedSecret", "authKey", "validIPAddresses", "remoteCertificateFile", "validPolicyErrors", "validChainFlags", "accessControlFilter",
                                                              "enabled", "updatedBy", "updatedOn", "id");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(subscriber.NodeID), subscriber.Acronym, subscriber.Name.ToNotNull(), subscriber.SharedSecret.ToNotNull(),
                                                        subscriber.AuthKey.ToNotNull(), subscriber.ValidIPAddresses.ToNotNull(), subscriber.RemoteCertificateFile.ToNotNull(), validPolicyErrors.ToString(),
                                                        validChainFlags.ToString(), subscriber.AccessControlFilter.ToNotNull(), database.Bool(subscriber.Enabled), CommonFunctions.CurrentUser, database.UtcNow,
                                                        database.Guid(subscriber.ID));
                }

                try
                {
                    CommonFunctions.SendCommandToService("ReloadConfig");
                }
                catch (Exception ex)
                {
                    return("Subscriber information saved successfully. Failed to send ReloadConfig command to backend service." + Environment.NewLine + ex.Message);
                }

                return("Subscriber information saved successfully");
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #3
0
ファイル: UserAccount.cs プロジェクト: xj0229/gsf
        // Static Methods

        /// <summary>
        /// Loads <see cref="UserAccount"/> information as an OberservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <returns>Collection of <see cref="UserAccount"/></returns>
        public static ObservableCollection <UserAccount> Load(AdoDataConnection database)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                ObservableCollection <UserAccount> userAccountList = new ObservableCollection <UserAccount>();
                DataTable userAccountTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * From UserAccount WHERE DefaultNodeID = '" + database.CurrentNodeID() + "'  ORDER BY Name");

                foreach (DataRow row in userAccountTable.Rows)
                {
                    userAccountList.Add(new UserAccount()
                    {
                        ID                  = database.Guid(row, "ID"),
                        Name                = UserInfo.SIDToAccountName(row.Field <string>("Name")),
                        Password            = row.Field <object>("Password") == null ? string.Empty : row.Field <string>("Password"),
                        FirstName           = row.Field <object>("FirstName") == null ? string.Empty : row.Field <string>("FirstName"),
                        LastName            = row.Field <object>("LastName") == null ? string.Empty : row.Field <string>("LastName"),
                        DefaultNodeID       = database.Guid(row, "DefaultNodeID"),
                        Phone               = row.Field <object>("Phone") == null ? string.Empty : row.Field <string>("Phone"),
                        Email               = row.Field <object>("Email") == null ? string.Empty : row.Field <string>("Email"),
                        LockedOut           = Convert.ToBoolean(row.Field <object>("LockedOut")),
                        UseADAuthentication = Convert.ToBoolean(row.Field <object>("UseADAuthentication")),
                        ChangePasswordOn    = row.Field <object>("ChangePasswordOn") == null ? DateTime.MinValue : Convert.ToDateTime(row.Field <object>("ChangePasswordOn")),
                        CreatedOn           = Convert.ToDateTime(row["CreatedOn"]),
                        CreatedBy           = row.Field <string>("CreatedBy"),
                        UpdatedOn           = Convert.ToDateTime(row.Field <object>("UpdatedOn")),
                        UpdatedBy           = row.Field <string>("UpdatedBy")
                    });
                }

                userAccountList.Insert(0, new UserAccount
                {
                    ID = Guid.Empty,
                    ChangePasswordOn = DateTime.Now.AddDays(90)
                });

                return(userAccountList);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #4
0
ファイル: SecurityHub.cs プロジェクト: wqshabib/gsf
        // Static Constructor
        static SecurityHub()
        {
            CategorizedSettingsElementCollection systemSettings = ConfigurationFile.Current.Settings["systemSettings"];

            // Retrieve default NodeID
            DefaultNodeID = Guid.Parse(systemSettings["NodeID"].Value.ToNonNullString(Guid.NewGuid().ToString()));

            // Determine whether the node exists in the database and create it if it doesn't
            if (DefaultNodeID != Guid.Empty)
            {
                using (AdoDataConnection connection = new AdoDataConnection("securityProvider"))
                {
                    const string NodeCountFormat  = "SELECT COUNT(*) FROM Node";
                    const string NodeInsertFormat = "INSERT INTO Node(Name, Description, Enabled) VALUES('Default', 'Default node', 1)";
                    const string NodeUpdateFormat = "UPDATE Node SET ID = {0}";

                    int nodeCount = connection.ExecuteScalar <int?>(NodeCountFormat) ?? 0;

                    if (nodeCount == 0)
                    {
                        connection.ExecuteNonQuery(NodeInsertFormat);
                        connection.ExecuteNonQuery(NodeUpdateFormat, connection.Guid(DefaultNodeID));
                    }
                }
            }
        }
コード例 #5
0
ファイル: SecurityGroup.cs プロジェクト: sotaria/gsf
        /// <summary>
        /// Retrieves collection of <see cref="UserAccount"/>s currently NOT assinged to security group.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="groupID">ID of <see cref="SecurityGroup"/> to filter users.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> type collection of <see cref="UserAccount"/>s currently NOT assigned to <see cref="SecurityGroup"/>.</returns>
        public static Dictionary <Guid, string> GetPossibleUsers(AdoDataConnection database, Guid groupID)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);
                Dictionary <Guid, string> possibleGroupUsers = new Dictionary <Guid, string>();
                string    query = database.ParameterizedQueryString("SELECT ID, Name FROM UserAccount WHERE ID NOT IN (SELECT UserAccountID FROM SecurityGroupUserAccount WHERE SecurityGroupID = {0}) ORDER BY Name", "groupID");
                DataTable possibleUsersTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.Guid(groupID));

                foreach (DataRow row in possibleUsersTable.Rows)
                {
                    possibleGroupUsers[database.Guid(row, "ID")] = UserInfo.SIDToAccountName(row.Field <string>("Name"));
                }

                return(possibleGroupUsers);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Deletes <see cref="UserAccount"/> from <see cref="ApplicationRole"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="roleID">ID of <see cref="ApplicationRole"/> from which <see cref="UserAccount"/>s are being deleted.</param>
        /// <param name="usersToBeDeleted">List of <see cref="UserAccount"/> IDs to be deleted.</param>
        /// <returns>string, for display use, indicating success.</returns>
        public static string RemoveUsers(AdoDataConnection database, Guid roleID, List <Guid> usersToBeDeleted)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);
                foreach (Guid id in usersToBeDeleted)
                {
                    string userName = database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT Name FROM UserAccount WHERE ID = {0}", "userAccountID"), DefaultTimeout, database.Guid(id)).ToNonNullString();
                    string roleName = database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT Name FROM ApplicationRole WHERE ID = {0}", "applicationRoleID"), DefaultTimeout, database.Guid(roleID)).ToNonNullString();
                    string query    = database.ParameterizedQueryString("DELETE FROM ApplicationRoleUserAccount WHERE ApplicationRoleID = {0} AND UserAccountID = {1}", "roleID", "userID");
                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(roleID), database.Guid(id));
                    CommonFunctions.LogEvent($"User \"{UserInfo.SIDToAccountName(userName)}\" removed from role \"{roleName}\" by user \"{CommonFunctions.CurrentUser}\".", 5);
                }

                return("User accounts deleted from role successfully");
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// Adds <see cref="SecurityGroup"/> to <see cref="ApplicationRole"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="roleID">ID of <see cref="ApplicationRole"/> to which <see cref="SecurityGroup"/>s are being added.</param>
        /// <param name="groupsToBeAdded">List of <see cref="SecurityGroup"/> IDs to be added.</param>
        /// <returns>string, for display use, indicating success.</returns>
        public static string AddGroups(AdoDataConnection database, Guid roleID, List <Guid> groupsToBeAdded)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);
                foreach (Guid id in groupsToBeAdded)
                {
                    string groupName = database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT Name FROM SecurityGroup WHERE ID = {0}", "securityGroupID"), DefaultTimeout, database.Guid(id)).ToNonNullString();
                    string roleName  = database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT Name FROM ApplicationRole WHERE ID = {0}", "applicationRoleID"), DefaultTimeout, database.Guid(roleID)).ToNonNullString();
                    string query     = database.ParameterizedQueryString("INSERT INTO ApplicationRoleSecurityGroup (ApplicationRoleID, SecurityGroupID) Values ({0}, {1})", "roleID", "groupID");
                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(roleID), database.Guid(id));
                    CommonFunctions.LogEvent($"Group \"{UserInfo.SIDToAccountName(groupName)}\" added to role \"{roleName}\" by user \"{CommonFunctions.CurrentUser}\".", 10);
                }

                return("Security groups added to role successfully");
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #8
0
        /// <summary>
        /// Gets a <see cref="Dictionary{T1,T2}"/> style list of <see cref="Node"/> information.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="isOptional">Indicates if selection on UI is optional for this collection.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> containing ID and Name of nodes defined in the database.</returns>
        public static Dictionary <Guid, string> GetLookupList(AdoDataConnection database, bool isOptional = false)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                Dictionary <Guid, string> nodeList = new Dictionary <Guid, string>();

                if (isOptional)
                {
                    nodeList.Add(Guid.Empty, "Select Node");
                }

                string    query     = database.ParameterizedQueryString("SELECT ID, Name FROM Node WHERE Enabled = {0} ORDER BY LoadOrder", "enabled");
                DataTable nodeTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.Bool(true));

                foreach (DataRow row in nodeTable.Rows)
                {
                    nodeList[database.Guid(row, "ID")] = row.Field <string>("Name");
                }

                return(nodeList);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #9
0
        // Static Methods

        /// <summary>
        /// Loads <see cref="Node"/> IDs as an <see cref="IList{T}"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="sortMember">The field to sort by.</param>
        /// <param name="sortDirection"><c>ASC</c> or <c>DESC</c> for ascending or descending respectively.</param>
        /// <returns>Collection of <see cref="Guid"/>.</returns>
        public static IList <Guid> LoadKeys(AdoDataConnection database, string sortMember = "", string sortDirection = "")
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                IList <Guid> nodeList   = new List <Guid>();
                string       sortClause = string.Empty;
                DataTable    nodeTable;

                if (!string.IsNullOrEmpty(sortMember))
                {
                    sortClause = string.Format("ORDER BY {0} {1}", sortMember, sortDirection);
                }

                nodeTable = database.Connection.RetrieveData(database.AdapterType, string.Format("Select ID From NodeDetail {0}", sortClause));


                foreach (DataRow row in nodeTable.Rows)
                {
                    nodeList.Add(database.Guid(row, "ID"));
                }

                return(nodeList);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #10
0
ファイル: SecurityGroup.cs プロジェクト: sotaria/gsf
        /// <summary>
        /// Deletes <see cref="UserAccount"/> from <see cref="SecurityGroup"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="groupID">ID of <see cref="SecurityGroup"/> from which <see cref="UserAccount"/>s are being deleted.</param>
        /// <param name="usersToBeDeleted">List of <see cref="UserAccount"/> IDs to be deleted.</param>
        /// <returns>string, for display use, indicating success.</returns>
        public static string RemoveUsers(AdoDataConnection database, Guid groupID, List <Guid> usersToBeDeleted)
        {
            bool   createdConnection = false;
            string query;
            string userName;
            string securityGroupName;

            try
            {
                createdConnection = CreateConnection(ref database);
                foreach (Guid id in usersToBeDeleted)
                {
                    userName          = database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT Name FROM UserAccount WHERE ID = {0}", "userID"), database.Guid(id)).ToNonNullString();
                    securityGroupName = database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT Name FROM SecurityGroup WHERE ID = {0}", "securityGroupID"), database.Guid(groupID)).ToNonNullString();
                    query             = database.ParameterizedQueryString("DELETE FROM SecurityGroupUserAccount WHERE SecurityGroupID = {0} AND UserAccountID = {1}", "groupID", "userID");
                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(groupID), database.Guid(id));
                    CommonFunctions.LogEvent(string.Format("User \"{0}\" successfully removed from security group \"{1}\" by user \"{2}\".", UserInfo.SIDToAccountName(userName), UserInfo.SIDToAccountName(securityGroupName), CommonFunctions.CurrentUser), 9);
                }

                return("User accounts deleted from group successfully");
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #11
0
ファイル: ApplicationRole.cs プロジェクト: xj0229/gsf
        /// <summary>
        /// Retrieves collection of <see cref="SecurityGroup"/>s assigned to <see cref="ApplicationRole"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="roleID">ID of the <see cref="ApplicationRole"/> to search for.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> type collection of <see cref="SecurityGroup"/>.</returns>
        public static Dictionary <Guid, string> GetCurrentGroups(AdoDataConnection database, Guid roleID)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                Dictionary <Guid, string> currentGroups = new Dictionary <Guid, string>();
                string    query = database.ParameterizedQueryString("SELECT * FROM AppRoleSecurityGroupDetail WHERE ApplicationRoleID = {0} ORDER BY SecurityGroupName", "applicationRoleID");
                DataTable currentGroupsTable = database.Connection.RetrieveData(database.AdapterType, query, database.Guid(roleID));

                foreach (DataRow row in currentGroupsTable.Rows)
                {
                    currentGroups[database.Guid(row, "SecurityGroupID")] = UserInfo.SIDToAccountName(row.Field <string>("SecurityGroupName"));
                }

                return(currentGroups);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #12
0
        /// <summary>
        /// Gets a <see cref="Dictionary{T1,T2}"/> style list of <see cref="Subscriber"/> information.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="isOptional">Indicates if selection on UI is optional for this collection.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> containing ID and Name of subscribers defined in the database.</returns>
        public static Dictionary <Guid, string> GetLookupList(AdoDataConnection database, bool isOptional = false)
        {
            Dictionary <Guid, string> subscriberList;
            DataTable subscriberTable;
            bool      createdConnection = false;
            string    query;

            try
            {
                createdConnection = CreateConnection(ref database);
                subscriberList    = new Dictionary <Guid, string>();

                if (isOptional)
                {
                    subscriberList.Add(Guid.Empty, "Select Subscriber");
                }

                query           = database.ParameterizedQueryString("SELECT ID, Acronym FROM Subscriber WHERE Enabled = {0} AND NodeID = {1} ORDER BY Name", "enabled", "nodeID");
                subscriberTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.Bool(true), database.CurrentNodeID());

                foreach (DataRow row in subscriberTable.Rows)
                {
                    subscriberList[database.Guid(row, "ID")] = row.Field <string>("Acronym");
                }

                return(subscriberList);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #13
0
ファイル: ApplicationRole.cs プロジェクト: xj0229/gsf
        /// <summary>
        /// Deletes <see cref="SecurityGroup"/> from <see cref="ApplicationRole"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="roleID">ID of <see cref="ApplicationRole"/> from which <see cref="SecurityGroup"/>s are being deleted.</param>
        /// <param name="groupsToBeDeleted">List of <see cref="SecurityGroup"/> IDs to be deleted.</param>
        /// <returns>string, for display use, indicating success.</returns>
        public static string RemoveGroups(AdoDataConnection database, Guid roleID, List <Guid> groupsToBeDeleted)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);
                foreach (Guid id in groupsToBeDeleted)
                {
                    string groupName = database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT Name FROM SecurityGroup WHERE ID = {0}", "securityGroupID"), DefaultTimeout, database.Guid(id)).ToNonNullString();
                    string roleName  = database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT Name FROM ApplicationRole WHERE ID = {0}", "applicationRoleID"), DefaultTimeout, database.Guid(roleID)).ToNonNullString();
                    string query     = database.ParameterizedQueryString("DELETE FROM ApplicationRoleSecurityGroup WHERE ApplicationRoleID = {0} AND SecurityGroupID = {1}", "roleID", "groupID");
                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(roleID), database.Guid(id));
                    CommonFunctions.LogEvent(string.Format("Group \"{0}\" removed from role \"{1}\" by user \"{2}\".", UserInfo.SIDToAccountName(groupName), roleName, CommonFunctions.CurrentUser), 11);
                }

                return("Security groups deleted from role successfully");
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #14
0
        /// <summary>
        /// Retrieves <see cref="Dictionary{T1,T2}"/> type collection of <see cref="Measurement"/> denied for <see cref="Subscriber"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="subscriberID">ID of the <see cref="Subscriber"/> to filter data.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> type collection of SignalID and PointTag of <see cref="Measurement"/>.</returns>
        public static Dictionary <Guid, string> GetDeniedMeasurements(AdoDataConnection database, Guid subscriberID)
        {
            Dictionary <Guid, string> deniedMeasurements;
            DataTable deniedMeasurementTable;
            bool      createdConnection = false;
            string    query;

            try
            {
                createdConnection  = CreateConnection(ref database);
                deniedMeasurements = new Dictionary <Guid, string>();
                query = database.ParameterizedQueryString("SELECT SignalID, PointTag FROM SubscriberMeasurementDetail WHERE SubscriberID = {0} AND Allowed = {1} ORDER BY PointTag", "subscriberID", "allowed");
                deniedMeasurementTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.Guid(subscriberID), database.Bool(false));

                foreach (DataRow row in deniedMeasurementTable.Rows)
                {
                    deniedMeasurements[database.Guid(row, "SignalID")] = row.Field <string>("PointTag");
                }

                return(deniedMeasurements);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #15
0
ファイル: SecurityGroup.cs プロジェクト: sotaria/gsf
        /// <summary>
        /// Retrieves collection of <see cref="UserAccount"/>s currently assinged to security group.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="groupID">ID of <see cref="SecurityGroup"/> to filter users.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> type collection of <see cref="UserAccount"/>s currently assigned to <see cref="SecurityGroup"/>.</returns>
        public static Dictionary <Guid, string> GetCurrentUsers(AdoDataConnection database, Guid groupID)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                Dictionary <Guid, string> currentUsers = new Dictionary <Guid, string>();
                DataTable currentUsersTable            = database.Connection.RetrieveData(database.AdapterType, database.ParameterizedQueryString("SELECT * FROM SecurityGroupUserAccountDetail WHERE SecurityGroupID = {0} ORDER BY UserName", "groupID"), database.Guid(groupID));

                foreach (DataRow row in currentUsersTable.Rows)
                {
                    currentUsers[database.Guid(row, "UserAccountID")] = UserInfo.SIDToAccountName(row.Field <string>("UserName"));
                }

                return(currentUsers);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #16
0
ファイル: OutputStreamDevice.cs プロジェクト: sotaria/gsf
        /// <summary>
        /// Saves <see cref="OutputStreamDevice"/> information to database.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="outputStreamDevice">Information about <see cref="OutputStreamDevice"/>.</param>
        /// <returns>String, for display use, indicating success.</returns>
        public static string Save(AdoDataConnection database, OutputStreamDevice outputStreamDevice)
        {
            bool   createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);

                if (outputStreamDevice.ID == 0)
                {
                    query = database.ParameterizedQueryString("INSERT INTO OutputStreamDevice (NodeID, AdapterID, IDCode, Acronym, BpaAcronym, Name, " +
                                                              "PhasorDataFormat, FrequencyDataFormat, AnalogDataFormat, CoordinateFormat, LoadOrder, Enabled, UpdatedBy, UpdatedOn, CreatedBy, CreatedOn)" +
                                                              "VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15})", "nodeID", "adapterID", "idCode", "acronym",
                                                              "bpaAcronym", "name", "phasorDataFormat", "frequencyDataFormat", "analogDataFormat", "coordinateFormat", "loadOrder", "enabled",
                                                              "updatedBy", "updatedOn", "createdBy", "createdOn");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.CurrentNodeID(), outputStreamDevice.AdapterID, outputStreamDevice.IDCode,
                                                        outputStreamDevice.Acronym, outputStreamDevice.BpaAcronym.ToNotNull(), outputStreamDevice.Name, outputStreamDevice.PhasorDataFormat.ToNotNull(),
                                                        outputStreamDevice.FrequencyDataFormat.ToNotNull(), outputStreamDevice.AnalogDataFormat.ToNotNull(), outputStreamDevice.CoordinateFormat.ToNotNull(),
                                                        outputStreamDevice.LoadOrder, database.Bool(outputStreamDevice.Enabled), CommonFunctions.CurrentUser,
                                                        database.UtcNow, CommonFunctions.CurrentUser, database.UtcNow);
                }
                else
                {
                    OutputStreamDevice originalDevice = GetOutputStreamDevice(database, "WHERE ID = " + outputStreamDevice.ID);

                    query = database.ParameterizedQueryString("UPDATE OutputStreamDevice SET NodeID = {0}, AdapterID = {1}, IDCode = {2}, Acronym = {3}, BpaAcronym = {4}, " +
                                                              "Name = {5}, PhasorDataFormat = {6}, FrequencyDataFormat = {7}, AnalogDataFormat = {8}, CoordinateFormat = {9}, LoadOrder = {10}, Enabled = {11}, " +
                                                              " UpdatedBy = {12}, UpdatedOn = {13} WHERE ID = {14}", "nodeID", "adapterID", "idCode", "acronym", "bpaAcronym", "name",
                                                              "phasorDataFormat", "frequencyDataFormat", "analogDataFormat", "coordinateFormat", "loadOrder", "enabled", "updatedBy", "updatedOn", "id");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(outputStreamDevice.NodeID), outputStreamDevice.AdapterID, outputStreamDevice.IDCode,
                                                        outputStreamDevice.Acronym, outputStreamDevice.BpaAcronym.ToNotNull(), outputStreamDevice.Name, outputStreamDevice.PhasorDataFormat.ToNotNull(),
                                                        outputStreamDevice.FrequencyDataFormat.ToNotNull(), outputStreamDevice.AnalogDataFormat.ToNotNull(), outputStreamDevice.CoordinateFormat.ToNotNull(),
                                                        outputStreamDevice.LoadOrder, database.Bool(outputStreamDevice.Enabled), CommonFunctions.CurrentUser,
                                                        database.UtcNow, outputStreamDevice.ID);

                    if (originalDevice != null && originalDevice.Acronym != outputStreamDevice.Acronym)
                    {
                        IList <int> keys = OutputStreamMeasurement.LoadKeys(database, originalDevice.AdapterID);

                        foreach (OutputStreamMeasurement measurement in OutputStreamMeasurement.Load(database, keys))
                        {
                            measurement.SignalReference = measurement.SignalReference.Replace(originalDevice.Acronym + "-", outputStreamDevice.Acronym + "-");
                            OutputStreamMeasurement.Save(database, measurement);
                        }
                    }
                }

                return("OutputStreamDevice information saved successfully");
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #17
0
        /// <summary>
        /// Validates security roles for all defined nodes.
        /// </summary>
        /// <param name="database">Data connection to use for database operations.</param>
        /// <param name="defaultSecurityRoles">Default security roles that should exist.</param>
        private static void ValidateSecurityRoles(AdoDataConnection database, string defaultSecurityRoles)
        {
            // Queries
            const string RoleCountFormat = "SELECT COUNT(*) FROM ApplicationRole WHERE NodeID = {0} AND Name = {1}";

            if (string.IsNullOrEmpty(defaultSecurityRoles))
            {
                defaultSecurityRoles = "Administrator, Owner, Viewer";
            }

            string[] roles = defaultSecurityRoles.Split(',').Select(role => role.Trim()).Where(role => !string.IsNullOrEmpty(role)).ToArray();

            // For each Node in new database make sure all roles exist
            DataTable dataTable = database.RetrieveData("SELECT ID FROM Node");

            foreach (DataRow row in dataTable.Rows)
            {
                Guid nodeID = row.ConvertField <Guid>("ID");

                foreach (string role in roles)
                {
                    if ((database.ExecuteScalar <int?>(RoleCountFormat, database.Guid(nodeID), role) ?? 0) == 0)
                    {
                        AddRolesForNode(database, nodeID, role);
                    }
                }
            }
        }
コード例 #18
0
        /// <summary>
        /// Loads <see cref="IaonTree"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <returns>Collection of <see cref="IaonTree"/>.</returns>
        public static ObservableCollection <IaonTree> Load(AdoDataConnection database)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);
                ObservableCollection <IaonTree> iaonTreeList;
                DataTable rootNodesTable = new DataTable();
                rootNodesTable.Columns.Add(new DataColumn("AdapterType", Type.GetType("System.String")));

                DataRow row;
                row = rootNodesTable.NewRow();
                row["AdapterType"] = "Input Adapters";
                rootNodesTable.Rows.Add(row);

                row = rootNodesTable.NewRow();
                row["AdapterType"] = "Action Adapters";
                rootNodesTable.Rows.Add(row);

                row = rootNodesTable.NewRow();
                row["AdapterType"] = "Output Adapters";
                rootNodesTable.Rows.Add(row);

                DataSet resultSet = new DataSet();
                resultSet.Tables.Add(rootNodesTable);

                DataTable iaonTreeTable = database.Connection.RetrieveData(database.AdapterType, database.ParameterizedQueryString("SELECT * FROM IaonTreeView WHERE NodeID = {0}", "nodeID"), database.CurrentNodeID());
                resultSet.EnforceConstraints = false;
                resultSet.Tables.Add(iaonTreeTable.Copy());
                resultSet.Tables[0].TableName = "RootNodesTable";
                resultSet.Tables[1].TableName = "AdapterData";

                iaonTreeList = new ObservableCollection <IaonTree>(from item in resultSet.Tables["RootNodesTable"].AsEnumerable()
                                                                   select new IaonTree
                {
                    m_adapterType = item.Field <string>("AdapterType"),
                    m_adapterList = new ObservableCollection <Adapter>(from obj in resultSet.Tables["AdapterData"].AsEnumerable()
                                                                       where obj.Field <string>("AdapterType") == item.Field <string>("AdapterType")
                                                                       select new Adapter
                    {
                        NodeID           = database.Guid(obj, "NodeID"),
                        ID               = obj.ConvertField <int>("ID"),
                        AdapterName      = obj.Field <string>("AdapterName"),
                        AssemblyName     = obj.Field <string>("AssemblyName"),
                        TypeName         = obj.Field <string>("TypeName"),
                        ConnectionString = obj.Field <string>("ConnectionString")
                    })
                });

                return(iaonTreeList);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #19
0
        /// <summary>
        /// Retrieves a <see cref="Dictionary{T1,T2}"/> style list of <see cref="Measurement"/> assigned to <see cref="MeasurementGroup"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="measurementGroupId">ID of the <see cref="MeasurementGroup"/> to filter data.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> containing SignalID and PointTag of <see cref="Measurement"/>s assigned to <see cref="MeasurementGroup"/>.</returns>
        public static Dictionary <Guid, string> GetCurrentMeasurements(AdoDataConnection database, int measurementGroupId)
        {
            Dictionary <Guid, string> currentMeasurements;
            DataTable currentMeasurementTable;
            bool      createdConnection = false;
            string    query;

            try
            {
                createdConnection   = CreateConnection(ref database);
                currentMeasurements = new Dictionary <Guid, string>();
                query = database.ParameterizedQueryString("SELECT * FROM MeasurementGroupMeasDetail WHERE MeasurementGroupID = {0} ORDER BY PointID", "measurementGroupID");
                currentMeasurementTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, measurementGroupId);

                foreach (DataRow row in currentMeasurementTable.Rows)
                {
                    currentMeasurements[database.Guid(row, "SignalID")] = row.Field <string>("PointTag");
                }

                return(currentMeasurements);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #20
0
        /// <summary>
        /// Removed measurement groups from <see cref="Subscriber"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="subscriberID">ID of the <see cref="Subscriber"/> to which measurement groups to be removed.</param>
        /// <param name="measurementGroupsToBeRemoved">List of <see cref="MeasurementGroup"/> IDs to be removed.</param>
        /// <returns>string, indicating success for UI display.</returns>
        public static string RemoveMeasurementGroups(AdoDataConnection database, Guid subscriberID, List <int> measurementGroupsToBeRemoved)
        {
            bool   createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);

                foreach (int id in measurementGroupsToBeRemoved)
                {
                    query = database.ParameterizedQueryString("DELETE FROM SubscriberMeasurementGroup WHERE SubscriberID = {0} AND MeasurementGroupID = {1}", "subscriberID", "measurementGroupID");
                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(subscriberID), id);
                }

                return("Measurement groups removed from allowed measurement groups list for subscriber successfully");
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #21
0
        /// <summary>
        /// Removes measurements from <see cref="Subscriber"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="subscriberID">ID of the <see cref="Subscriber"/> from which measurements to be removed.</param>
        /// <param name="measurementsToBeRemoved">List of <see cref="Measurement"/> IDs to be removed.</param>
        /// <returns>string, indicating success for UI display.</returns>
        public static string RemoveMeasurements(AdoDataConnection database, Guid subscriberID, List <Guid> measurementsToBeRemoved)
        {
            bool   createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);

                foreach (Guid id in measurementsToBeRemoved)
                {
                    query = database.ParameterizedQueryString("DELETE FROM SubscriberMeasurement WHERE SubscriberID = {0} AND SignalID = {1}", "subscriberID", "signalID");
                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(subscriberID), database.Guid(id));
                }

                return("Selected measurements removed successfully");
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #22
0
ファイル: ApplicationRole.cs プロジェクト: xj0229/gsf
        /// <summary>
        /// Adds <see cref="UserAccount"/> to <see cref="ApplicationRole"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="roleID">ID of <see cref="ApplicationRole"/> to which <see cref="UserAccount"/>s are being added.</param>
        /// <param name="usersToBeAdded">List of <see cref="UserAccount"/> IDs to be added.</param>
        /// <returns>string, for display use, indicating success.</returns>
        public static string AddUsers(AdoDataConnection database, Guid roleID, List <Guid> usersToBeAdded)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                foreach (Guid id in usersToBeAdded)
                {
                    string userName = database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT Name FROM UserAccount WHERE ID = {0}", "userAccountID"), DefaultTimeout, database.Guid(id)).ToNonNullString();
                    string roleName = database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT Name FROM ApplicationRole WHERE ID = {0}", "applicationRoleID"), DefaultTimeout, database.Guid(roleID)).ToNonNullString();
                    string query    = database.ParameterizedQueryString("INSERT INTO ApplicationRoleUserAccount (ApplicationRoleID, UserAccountID) VALUES ({0}, {1})", "roleID", "userID");
                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(roleID), database.Guid(id));
                    CommonFunctions.LogEvent(string.Format("User \"{0}\" added to role \"{1}\" by user \"{2}\".", UserInfo.SIDToAccountName(userName), roleName, CommonFunctions.CurrentUser), 4);
                }

                return("User accounts added to role successfully");
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #23
0
ファイル: UserAccount.cs プロジェクト: xj0229/gsf
        /// <summary>
        /// Gets a <see cref="Dictionary{T1,T2}"/> style list of <see cref="UserAccount"/> information.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="isOptional">Indicates if selection on UI is optional for this collection.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> containing ID and Name of user accounts defined in the database.</returns>
        public static Dictionary <Guid, string> GetLookupList(AdoDataConnection database, bool isOptional = false)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                Dictionary <Guid, string> userAccountList = new Dictionary <Guid, string>();
                if (isOptional)
                {
                    userAccountList.Add(Guid.Empty, "Select UserAccount");
                }

                DataTable userAccountTable = database.Connection.RetrieveData(database.AdapterType, "SELECT ID, Name FROM UserAccount ORDER BY Name");

                foreach (DataRow row in userAccountTable.Rows)
                {
                    userAccountList[database.Guid(row, "ID")] = UserInfo.SIDToAccountName(row.Field <string>("Name"));
                }

                return(userAccountList);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #24
0
        /// <summary>
        /// Loads <see cref="OutputStreamDevice"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="keys">Keys of the measurement to be loaded from the datbase</param>
        /// <returns>Collection of <see cref="OutputStreamDevice"/>.</returns>
        public static ObservableCollection <OutputStreamDevice> Load(AdoDataConnection database, IList <int> keys)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string query;
                string commaSeparatedKeys;

                OutputStreamDevice[] outputStreamDeviceList = null;
                DataTable            outputStreamDeviceTable;
                int id;

                if ((object)keys != null && keys.Count > 0)
                {
                    commaSeparatedKeys = keys.Select(key => key.ToString()).Aggregate((str1, str2) => str1 + "," + str2);
                    query = string.Format("SELECT NodeID, AdapterID, ID, IDCode, Acronym, BpaAcronym, Name, PhasorDataFormat, " +
                                          "FrequencyDataFormat, AnalogDataFormat, CoordinateFormat, LoadOrder, Enabled, Virtual " +
                                          "FROM OutputStreamDeviceDetail WHERE ID IN ({0})", commaSeparatedKeys);

                    outputStreamDeviceTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout);
                    outputStreamDeviceList  = new OutputStreamDevice[outputStreamDeviceTable.Rows.Count];

                    foreach (DataRow row in outputStreamDeviceTable.Rows)
                    {
                        id = row.ConvertField <int>("ID");

                        outputStreamDeviceList[keys.IndexOf(id)] = new OutputStreamDevice()
                        {
                            NodeID              = database.Guid(row, "NodeID"),
                            AdapterID           = row.ConvertField <int>("AdapterID"),
                            ID                  = id,
                            IDCode              = row.ConvertField <int>("IDCode"),
                            Acronym             = row.Field <string>("Acronym"),
                            BpaAcronym          = row.Field <string>("BpaAcronym"),
                            Name                = row.Field <string>("Name"),
                            PhasorDataFormat    = row.Field <string>("PhasorDataFormat"),
                            FrequencyDataFormat = row.Field <string>("FrequencyDataFormat"),
                            AnalogDataFormat    = row.Field <string>("AnalogDataFormat"),
                            CoordinateFormat    = row.Field <string>("CoordinateFormat"),
                            LoadOrder           = row.ConvertField <int>("LoadOrder"),
                            Enabled             = Convert.ToBoolean(row.Field <object>("Enabled")),
                            m_virtual           = Convert.ToBoolean(row.Field <object>("Virtual"))
                        };
                    }
                }

                return(new ObservableCollection <OutputStreamDevice>(outputStreamDeviceList ?? new OutputStreamDevice[0]));
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #25
0
        /// <summary>
        /// Loads <see cref="Historian"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="keys">Keys to load, if any.</param>
        /// <returns>Collection of <see cref="Historian"/>.</returns>
        public static ObservableCollection <Historian> Load(AdoDataConnection database, IList <int> keys)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string query;
                string commaSeparatedKeys;

                Historian[] historianList = null;
                DataTable   historianTable;
                int         id;

                if ((object)keys != null && keys.Count > 0)
                {
                    commaSeparatedKeys = keys.Select(key => key.ToString()).Aggregate((str1, str2) => str1 + "," + str2);
                    query = database.ParameterizedQueryString(string.Format("SELECT NodeID, ID, Acronym, Name, AssemblyName, TypeName, " +
                                                                            "ConnectionString, IsLocal, Description, LoadOrder, Enabled, MeasurementReportingInterval, NodeName" +
                                                                            " FROM HistorianDetail WHERE NodeID = {{0}} AND ID IN ({0})", commaSeparatedKeys), "nodeID");

                    historianTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID());
                    historianList  = new Historian[historianTable.Rows.Count];

                    foreach (DataRow row in historianTable.Rows)
                    {
                        id = row.ConvertField <int>("ID");

                        historianList[keys.IndexOf(id)] = new Historian()
                        {
                            NodeID                       = database.Guid(row, "NodeID"),
                            ID                           = id,
                            Acronym                      = row.Field <string>("Acronym"),
                            Name                         = row.Field <string>("Name"),
                            AssemblyName                 = row.Field <string>("AssemblyName"),
                            TypeName                     = row.Field <string>("TypeName"),
                            ConnectionString             = row.Field <string>("ConnectionString"),
                            IsLocal                      = Convert.ToBoolean(row.Field <object>("IsLocal")),
                            Description                  = row.Field <string>("Description"),
                            LoadOrder                    = row.ConvertField <int>("LoadOrder"),
                            Enabled                      = Convert.ToBoolean(row.Field <object>("Enabled")),
                            MeasurementReportingInterval = row.ConvertField <int>("MeasurementReportingInterval"),
                            m_nodeName                   = row.Field <string>("NodeName")
                        };
                    }
                }

                return(new ObservableCollection <Historian>(historianList ?? new Historian[0]));
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #26
0
        /// <summary>
        /// Loads <see cref="Node"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="keys">Keys of the nodes to be loaded from the database.</param>
        /// <returns>Collection of <see cref="Node"/>.</returns>
        public static ObservableCollection <Node> Load(AdoDataConnection database, IList <Guid> keys)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string query;
                string commaSeparatedKeys;

                Node[]    nodeList = null;
                DataTable nodeTable;
                Guid      id;

                if ((object)keys != null && keys.Count > 0)
                {
                    commaSeparatedKeys = keys.Select(key => "'" + key.ToString() + "'").Aggregate((str1, str2) => str1 + "," + str2);
                    query = string.Format("Select ID, Name, CompanyID, Longitude, Latitude, Description, ImagePath, Settings, MenuData, " +
                                          "MenuType, Master, LoadOrder, Enabled, CompanyName From NodeDetail WHERE ID IN ({0})", commaSeparatedKeys);

                    nodeTable = database.Connection.RetrieveData(database.AdapterType, query);
                    nodeList  = new Node[nodeTable.Rows.Count];

                    foreach (DataRow row in nodeTable.Rows)
                    {
                        id = database.Guid(row, "ID");

                        nodeList[keys.IndexOf(id)] = new Node()
                        {
                            ID            = id,
                            Name          = row.Field <string>("Name"),
                            CompanyID     = row.ConvertNullableField <int>("CompanyID"),
                            Longitude     = row.ConvertNullableField <decimal>("Longitude"),
                            Latitude      = row.ConvertNullableField <decimal>("Latitude"),
                            Description   = row.Field <string>("Description"),
                            ImagePath     = row.Field <string>("ImagePath"),
                            Settings      = row.Field <string>("Settings"),
                            MenuType      = row.Field <string>("MenuType"),
                            MenuData      = row.Field <string>("MenuData"),
                            Master        = Convert.ToBoolean(row.Field <object>("Master")),
                            LoadOrder     = row.ConvertField <int>("LoadOrder"),
                            Enabled       = Convert.ToBoolean(row.Field <object>("Enabled")),
                            m_companyName = row.Field <string>("CompanyName")
                        };
                    }
                }

                return(new ObservableCollection <Node>(nodeList ?? new Node[0]));
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #27
0
        /// <summary>
        /// Retrieves an <see cref="Alarm"/> information from the database based on query string filter.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="whereClause">Filter clause to append to the SELECT query.</param>
        /// <returns><see cref="Alarm"/> information.</returns>
        public static Alarm GetAlarm(AdoDataConnection database, string whereClause)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);
                DataTable alarmTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM Alarm " + whereClause);

                if (alarmTable.Rows.Count == 0)
                {
                    return(null);
                }

                DataRow row = alarmTable.Rows[0];
                object  associatedMeasurementId = row.Field <object>("AssociatedMeasurementID");

                Alarm alarm = new Alarm
                {
                    NodeID   = database.Guid(row, "NodeID"),
                    ID       = row.ConvertField <int>("ID"),
                    TagName  = row.Field <string>("TagName"),
                    SignalID = database.Guid(row, "SignalID"),
                    AssociatedMeasurementID = ((object)associatedMeasurementId != null) ? Guid.Parse(associatedMeasurementId.ToString()) : (Guid?)null,
                    Description             = row.Field <string>("Description"),
                    Severity   = row.ConvertField <int>("Severity"),
                    Operation  = row.ConvertField <int>("Operation"),
                    SetPoint   = row.ConvertNullableField <double>("SetPoint"),
                    Tolerance  = row.ConvertNullableField <double>("Tolerance"),
                    Delay      = row.ConvertNullableField <double>("Delay"),
                    Hysteresis = row.ConvertNullableField <double>("Hysteresis"),
                    LoadOrder  = row.ConvertField <int>("LoadOrder"),
                    Enabled    = row.ConvertField <bool>("Enabled")
                };

                return(alarm);
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #28
0
        /// <summary>
        /// Adds role for newly added node, e.g., Administrator, Editor, Viewer.
        /// </summary>
        /// <param name="database">Data connection to use for database operations.</param>
        /// <param name="nodeID">Node ID to which roles are being assigned.</param>
        /// <param name="roleName">Name of role to be added.</param>
        private static void AddRolesForNode(AdoDataConnection database, Guid nodeID, string roleName)
        {
            // Queries
            const string InsertRoleFormat = "INSERT INTO ApplicationRole(Name, Description, NodeID, UpdatedBy, CreatedBy) VALUES('{0}', '{0} Role', {{0}}, {{1}}, {{2}})";

            string currentUserSID = UserInfo.UserNameToSID(UserInfo.CurrentUserID);

            database.ExecuteNonQuery(string.Format(InsertRoleFormat, roleName), database.Guid(nodeID), currentUserSID, currentUserSID);
        }
コード例 #29
0
        /// <summary>
        /// Loads <see cref="OutputStreamDevicePhasor"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="keys">Keys of the measuremnets to be loaded from the database</param>
        /// <returns>Collection of <see cref="OutputStreamDevicePhasor"/>.</returns>
        public static ObservableCollection <OutputStreamDevicePhasor> Load(AdoDataConnection database, IList <int> keys)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string query;
                string commaSeparatedKeys;

                OutputStreamDevicePhasor[] outputStreamDevicePhasorList = null;
                DataTable outputStreamDevicePhasorTable;
                int       id;

                if ((object)keys != null && keys.Count > 0)
                {
                    commaSeparatedKeys = keys.Select(key => "" + key.ToString() + "").Aggregate((str1, str2) => str1 + "," + str2);
                    query = database.ParameterizedQueryString(string.Format("SELECT NodeID, OutputStreamDeviceID, ID, Label, Type, Phase, ScalingValue, LoadOrder " +
                                                                            "FROM OutputStreamDevicePhasor WHERE ID IN ({0})", commaSeparatedKeys));

                    outputStreamDevicePhasorTable = database.Connection.RetrieveData(database.AdapterType, query);
                    outputStreamDevicePhasorList  = new OutputStreamDevicePhasor[outputStreamDevicePhasorTable.Rows.Count];

                    foreach (DataRow row in outputStreamDevicePhasorTable.Rows)
                    {
                        id = row.ConvertField <int>("ID");

                        outputStreamDevicePhasorList[keys.IndexOf(id)] = new OutputStreamDevicePhasor()
                        {
                            NodeID = database.Guid(row, "NodeID"),
                            OutputStreamDeviceID = row.ConvertField <int>("OutputStreamDeviceID"),
                            ID           = id,
                            Label        = row.Field <string>("Label"),
                            Type         = row.Field <string>("Type"),
                            Phase        = row.Field <string>("Phase"),
                            ScalingValue = row.ConvertField <int>("ScalingValue"),
                            LoadOrder    = row.ConvertField <int>("LoadOrder"),
                            m_phaseType  = row.Field <string>("Phase") == "+" ? "Positive Sequence" : row.Field <string>("Phase") == "-" ? "Negative Sequence" :
                                           row.Field <string>("Phase") == "0" ? "Zero Sequence" : row.Field <string>("Phase") == "A" ? "Phase A" :
                                           row.Field <string>("Phase") == "B" ? "Phase B" : "Phase C",
                            m_phasorType = row.Field <string>("Type") == "V" ? "Voltage" : "Current"
                        };
                    }
                }

                return(new ObservableCollection <OutputStreamDevicePhasor>(outputStreamDevicePhasorList ?? new OutputStreamDevicePhasor[0]));
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #30
0
        /// <summary>
        /// Loads <see cref="OutputStreamMeasurement"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="keys">Keys of the measurement to be loaded from the database</param>
        /// <returns>Collection of <see cref="OutputStreamMeasurement"/>.</returns>
        public static ObservableCollection <OutputStreamMeasurement> Load(AdoDataConnection database, IList <int> keys)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string query;
                string commaSeparatedKeys;

                OutputStreamMeasurement[] outputStreamMeasurementList = null;
                DataTable outputStreamMeasurementTable;
                int       id;

                if ((object)keys != null && keys.Count > 0)
                {
                    commaSeparatedKeys = keys.Select(key => "" + key.ToString() + "").Aggregate((str1, str2) => str1 + "," + str2);
                    query = string.Format("SELECT NodeID, AdapterID, ID, HistorianID, PointID, SignalReference, SourcePointTag, HistorianAcronym " +
                                          "FROM OutputStreamMeasurementDetail WHERE ID IN ({0})", commaSeparatedKeys);

                    outputStreamMeasurementTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout);
                    outputStreamMeasurementList  = new OutputStreamMeasurement[outputStreamMeasurementTable.Rows.Count];

                    foreach (DataRow row in outputStreamMeasurementTable.Rows)
                    {
                        id = row.ConvertField <int>("ID");

                        outputStreamMeasurementList[keys.IndexOf(id)] = new OutputStreamMeasurement()
                        {
                            NodeID             = database.Guid(row, "NodeID"),
                            AdapterID          = row.ConvertField <int>("AdapterID"),
                            ID                 = id,
                            HistorianID        = row.ConvertNullableField <int>("HistorianID"),
                            PointID            = row.ConvertField <int>("PointID"),
                            SignalReference    = row.Field <string>("SignalReference"),
                            m_sourcePointTag   = row.Field <string>("SourcePointTag"),
                            m_historianAcronym = row.Field <string>("HistorianAcronym")
                        };
                    }
                }

                return(new ObservableCollection <OutputStreamMeasurement>(outputStreamMeasurementList ?? new OutputStreamMeasurement[0]));
            }
            finally
            {
                if (createdConnection && database != null)
                {
                    database.Dispose();
                }
            }
        }
コード例 #31
0
ファイル: UserAccount.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Saves <see cref="UserAccount"/> information to database.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="userAccount">Information about <see cref="UserAccount"/>.</param>        
        /// <returns>String, for display use, indicating success.</returns>
        public static string Save(AdoDataConnection database, UserAccount userAccount)
        {
            const string ErrorMessage = "User name already exists.";

            bool createdConnection = false;
            string query;
            string userAccountSID;
            int existing;

            try
            {
                createdConnection = CreateConnection(ref database);

                string pColumn = "Password";

                if (database.IsJetEngine)
                    pColumn = "[Password]";

                object changePasswordOn = userAccount.ChangePasswordOn;

                if (userAccount.ChangePasswordOn == DateTime.MinValue)
                    changePasswordOn = (object)DBNull.Value;
                else if (database.IsJetEngine)
                    changePasswordOn = userAccount.ChangePasswordOn.ToOADate();

                userAccountSID = UserInfo.UserNameToSID(userAccount.Name);

                if (!userAccount.UseADAuthentication || !UserInfo.IsUserSID(userAccountSID))
                    userAccountSID = userAccount.Name;

                if (userAccount.ID == Guid.Empty)
                {
                    existing = Convert.ToInt32(database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT COUNT(*) FROM UserAccount WHERE Name = {0}", "name"), DefaultTimeout, userAccountSID));

                    if (existing > 0)
                        throw new InvalidOperationException(ErrorMessage);

                    query = database.ParameterizedQueryString("INSERT INTO UserAccount (Name, " + pColumn + ", FirstName, LastName, DefaultNodeID, Phone, Email, " +
                        "LockedOut, UseADAuthentication, ChangePasswordOn, UpdatedBy, UpdatedOn, CreatedBy, CreatedOn) VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, " +
                        "{9}, {10}, {11}, {12}, {13})", "name", "password", "firstName", "lastName", "defaultNodeID", "phone", "email", "lockedOut", "useADAuthentication",
                        "changePasswordOn", "updatedBy", "updatedOn", "createdBy", "createdOn");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, userAccountSID,
                        userAccount.Password.ToNotNull(), userAccount.FirstName.ToNotNull(), userAccount.LastName.ToNotNull(), database.CurrentNodeID(),
                        userAccount.Phone.ToNotNull(), userAccount.Email.ToNotNull(), database.Bool(userAccount.LockedOut), database.Bool(userAccount.UseADAuthentication),
                        changePasswordOn, CommonFunctions.CurrentUser, database.UtcNow, CommonFunctions.CurrentUser, database.UtcNow);

                    CommonFunctions.LogEvent(string.Format("New user \"{0}\" created successfully by user \"{1}\".", userAccount.Name, CommonFunctions.CurrentUser), 2);
                }
                else
                {
                    existing = database.ExecuteScalar<int>("SELECT COUNT(*) FROM UserAccount WHERE Name = {0} AND ID <> {1}", userAccountSID, userAccount.ID);

                    if (existing > 0)
                        throw new InvalidOperationException(ErrorMessage);

                    query = database.ParameterizedQueryString("UPDATE UserAccount SET Name = {0}, " + pColumn + " = {1}, FirstName = {2}, LastName = {3}, " +
                            "DefaultNodeID = {4}, Phone = {5}, Email = {6}, LockedOut = {7}, UseADAuthentication = {8}, ChangePasswordOn = {9}, UpdatedBy = {10}, " +
                            "UpdatedOn = {11} WHERE ID = {12}", "name", "password", "firstName", "lastName", "defaultNodeID", "phone", "email", "lockedOut",
                            "useADAuthentication", "changePasswordOn", "updatedBy", "updatedOn", "id");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, userAccountSID,
                            userAccount.Password.ToNotNull(), userAccount.FirstName.ToNotNull(), userAccount.LastName.ToNotNull(), database.Guid(userAccount.DefaultNodeID),
                            userAccount.Phone.ToNotNull(), userAccount.Email.ToNotNull(), database.Bool(userAccount.LockedOut), database.Bool(userAccount.UseADAuthentication),
                            changePasswordOn, CommonFunctions.CurrentUser, database.UtcNow, database.Guid(userAccount.ID));

                    CommonFunctions.LogEvent(string.Format("Information about user \"{0}\" updated successfully by user \"{1}\".", userAccount.Name, CommonFunctions.CurrentUser), 3);
                }

                return "User account information saved successfully";
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #32
0
ファイル: OutputStreamMeasurement.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Loads <see cref="OutputStreamMeasurement"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="keys">Keys of the measurement to be loaded from the database</param>
        /// <returns>Collection of <see cref="OutputStreamMeasurement"/>.</returns>
        public static ObservableCollection<OutputStreamMeasurement> Load(AdoDataConnection database, IList<int> keys)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string query;
                string commaSeparatedKeys;

                OutputStreamMeasurement[] outputStreamMeasurementList = null;
                DataTable outputStreamMeasurementTable;
                int id;

                if ((object)keys != null && keys.Count > 0)
                {
                    commaSeparatedKeys = keys.Select(key => "" + key.ToString() + "").Aggregate((str1, str2) => str1 + "," + str2);
                    query = string.Format("SELECT NodeID, AdapterID, ID, HistorianID, PointID, SignalReference, SourcePointTag, HistorianAcronym " +
                        "FROM OutputStreamMeasurementDetail WHERE ID IN ({0})", commaSeparatedKeys);

                    outputStreamMeasurementTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout);
                    outputStreamMeasurementList = new OutputStreamMeasurement[outputStreamMeasurementTable.Rows.Count];

                    foreach (DataRow row in outputStreamMeasurementTable.Rows)
                    {
                        id = row.ConvertField<int>("ID");

                        outputStreamMeasurementList[keys.IndexOf(id)] = new OutputStreamMeasurement()
                        {
                            NodeID = database.Guid(row, "NodeID"),
                            AdapterID = row.ConvertField<int>("AdapterID"),
                            ID = id,
                            HistorianID = row.ConvertNullableField<int>("HistorianID"),
                            PointID = row.ConvertField<int>("PointID"),
                            SignalReference = row.Field<string>("SignalReference"),
                            m_sourcePointTag = row.Field<string>("SourcePointTag"),
                            m_historianAcronym = row.Field<string>("HistorianAcronym")
                        };
                    }
                }

                return new ObservableCollection<OutputStreamMeasurement>(outputStreamMeasurementList ?? new OutputStreamMeasurement[0]);
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #33
0
ファイル: OutputStream.cs プロジェクト: avs009/gsf
        /// <summary>
        /// Saves <see cref="OutputStream"/> information to database.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="outputStream">Information about <see cref="OutputStream"/>.</param>        
        /// <param name="mirrorMode">Boolean value to use mirror mode when saving output stream.</param>
        /// <returns>String, for display use, indicating success.</returns>
        public static string Save(AdoDataConnection database, OutputStream outputStream, bool mirrorMode)
        {
            bool createdConnection = false;
            string query;

            try
            {
                OutputStream oldOutputStream;
                createdConnection = CreateConnection(ref database);

                if (outputStream.ID == 0)
                {
                    query = database.ParameterizedQueryString("INSERT INTO OutputStream (NodeID, Acronym, Name,  Type, ConnectionString, IDCode, CommandChannel, DataChannel, " +
                        "AutoPublishConfigFrame, AutoStartDataChannel, NominalFrequency, FramesPerSecond, LagTime, LeadTime, UseLocalClockAsRealTime, AllowSortsByArrival, " +
                        "LoadOrder, Enabled, IgnoreBadTimeStamps, TimeResolution, AllowPreemptivePublishing, DownSamplingMethod, DataFormat, CoordinateFormat, " +
                        "CurrentScalingValue, VoltageScalingValue, AnalogScalingValue, DigitalMaskValue, PerformTimeReasonabilityCheck, UpdatedBy, UpdatedOn, " +
                        "CreatedBy, CreatedOn) VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, " +
                        "{21}, {22}, {23}, {24}, {25}, {26}, {27}, {28}, {29}, {30}, {31}, {32})", "nodeID", "acronym", "name", "type", "connectionString", "idCode",
                        "commandChannel", "dataChannel", "autoPublishConfigFrame", "autoStartDataChannel", "nominalFrequency", "framesPerSecond", "lagTime", "leadTime",
                        "useLocalClockAsRealTime", "allowSortsByArrival", "loadOrder", "enabled", "ignoreBadTimeStamps", "timeResolution", "allowPreemptivePublishing",
                        "downSamplingMethod", "dataFormat", "coordinateFormat", "currentScalingValue", "voltageScalingValue", "analogScalingValue", "digitalMaskValue",
                        "performTimeReasonabilityCheck", "updatedBy", "updatedOn", "createdBy", "createdOn");

                    database.Connection.ExecuteNonQuery(query,
                        database.CurrentNodeID(), outputStream.Acronym.Replace(" ", "").ToUpper(), outputStream.Name.ToNotNull(), outputStream.Type - 1, outputStream.ConnectionString.ToNotNull(),
                        outputStream.IDCode, outputStream.CommandChannel.ToNotNull(), outputStream.DataChannel.ToNotNull(), database.Bool(outputStream.AutoPublishConfigFrame), database.Bool(outputStream.AutoStartDataChannel),
                        outputStream.NominalFrequency, outputStream.FramesPerSecond, outputStream.LagTime, outputStream.LeadTime, database.Bool(outputStream.UseLocalClockAsRealTime), database.Bool(outputStream.AllowSortsByArrival),
                        outputStream.LoadOrder, database.Bool(outputStream.Enabled), database.Bool(outputStream.IgnoreBadTimeStamps), outputStream.TimeResolution, database.Bool(outputStream.AllowPreemptivePublishing),
                        outputStream.DownSamplingMethod.ToNotNull(), outputStream.DataFormat.ToNotNull(), outputStream.CoordinateFormat.ToNotNull(), outputStream.CurrentScalingValue,
                        outputStream.VoltageScalingValue, outputStream.AnalogScalingValue, outputStream.DigitalMaskValue, database.Bool(outputStream.PerformTimestampReasonabilityCheck),
                        CommonFunctions.CurrentUser, database.UtcNow, CommonFunctions.CurrentUser, database.UtcNow);
                }
                else
                {
                    oldOutputStream = GetOutputStream(database, " WHERE ID = " + outputStream.ID);

                    query = database.ParameterizedQueryString("UPDATE OutputStream SET NodeID = {0}, Acronym = {1}, Name = {2}, Type = {3}, ConnectionString = {4}, " +
                        "IDCode = {5}, CommandChannel = {6}, DataChannel = {7}, AutoPublishConfigFrame = {8}, AutoStartDataChannel = {9}, NominalFrequency = {10}, " +
                        "FramesPerSecond = {11}, LagTime = {12}, LeadTime = {13}, UseLocalClockAsRealTime = {14}, AllowSortsByArrival = {15}, LoadOrder = {16}, " +
                        "Enabled = {17}, IgnoreBadTimeStamps = {18}, TimeResolution = {19}, AllowPreemptivePublishing = {20}, DownSamplingMethod = {21}, " +
                        "DataFormat = {22}, CoordinateFormat = {23}, CurrentScalingValue = {24}, VoltageScalingValue = {25}, AnalogScalingValue = {26}, " +
                        "DigitalMaskValue = {27}, PerformTimeReasonabilityCheck = {28}, UpdatedBy = {29}, UpdatedOn = {30} WHERE ID = {31}", "nodeID", "acronym", "name",
                        "type", "connectionString", "idCode", "commandChannel", "dataChannel", "autoPublishConfigFrame", "autoStartDataChannel", "nominalFrequency",
                        "framesPerSecond", "lagTime", "leadTime", "useLocalClockAsRealTime", "allowSortsByArrival", "loadOrder", "enabled", "ignoreBadTimeStamps",
                        "timeResolution", "allowPreemptivePublishing", "downsamplingMethod", "dataFormat", "coordinateFormat", "currentScalingValue", "voltageScalingValue",
                        "analogScalingValue", "digitalMaskValue", "performTimeReasonabilityCheck", "updatedBy", "updatedOn", "id");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout,
                        database.Guid(outputStream.NodeID), outputStream.Acronym.Replace(" ", "").ToUpper(), outputStream.Name.ToNotNull(), outputStream.Type - 1, outputStream.ConnectionString.ToNotNull(),
                        outputStream.IDCode, outputStream.CommandChannel.ToNotNull(), outputStream.DataChannel.ToNotNull(), database.Bool(outputStream.AutoPublishConfigFrame), database.Bool(outputStream.AutoStartDataChannel),
                        outputStream.NominalFrequency, outputStream.FramesPerSecond, outputStream.LagTime, outputStream.LeadTime, database.Bool(outputStream.UseLocalClockAsRealTime),
                        database.Bool(outputStream.AllowSortsByArrival), outputStream.LoadOrder, database.Bool(outputStream.Enabled), database.Bool(outputStream.IgnoreBadTimeStamps), outputStream.TimeResolution,
                        database.Bool(outputStream.AllowPreemptivePublishing), outputStream.DownSamplingMethod.ToNotNull(), outputStream.DataFormat.ToNotNull(), outputStream.CoordinateFormat.ToNotNull(),
                        outputStream.CurrentScalingValue, outputStream.VoltageScalingValue, outputStream.AnalogScalingValue, outputStream.DigitalMaskValue, database.Bool(outputStream.PerformTimestampReasonabilityCheck),
                        CommonFunctions.CurrentUser, database.UtcNow, outputStream.ID);

                    if (oldOutputStream != null && oldOutputStream.Acronym != outputStream.Acronym.Replace(" ", "").ToUpper())
                    {
                        ObservableCollection<Measurement> measurementList = Measurement.GetOutputStatisticMeasurements(database, oldOutputStream.Acronym);

                        foreach (Measurement measurement in measurementList)
                        {
                            measurement.SignalReference = measurement.SignalReference.Replace(oldOutputStream.Acronym, outputStream.Acronym.Replace(" ", "").ToUpper());
                            measurement.PointTag = measurement.PointTag.Replace(oldOutputStream.Acronym, outputStream.Acronym.Replace(" ", "").ToUpper());
                            measurement.Description = Regex.Replace(measurement.Description, oldOutputStream.Name, outputStream.Name ?? outputStream.Acronym.Replace(" ", "").ToUpper(), RegexOptions.IgnoreCase);
                            Measurement.Save(database, measurement);
                        }

                        SignalType qualityType = SignalType.Load(database).FirstOrDefault(type => type.Acronym == "QUAL");

                        if ((object)qualityType != null)
                        {
                            IList<int> keys = database.Connection.RetrieveData(database.AdapterType, string.Format("SELECT ID FROM OutputStreamMeasurement WHERE AdapterID = {0}", outputStream.ID))
                                .Select().Select(row => row.ConvertField<int>("ID")).ToList();

                            foreach (OutputStreamMeasurement measurement in OutputStreamMeasurement.Load(database, keys))
                            {
                                if (Regex.IsMatch(measurement.SignalReference, string.Format("{0}-{1}", oldOutputStream.Acronym, qualityType.Suffix)))
                                {
                                    measurement.SignalReference = measurement.SignalReference.Replace(oldOutputStream.Acronym, outputStream.Acronym.Replace(" ", "").ToUpper());
                                    OutputStreamMeasurement.Save(database, measurement);
                                }
                            }
                        }
                    }
                }

                if (mirrorMode)
                {
                    // Get ID of the output stream if a new one was inserted above.
                    if (outputStream.ID == 0)
                        outputStream.ID = GetOutputStream(database, " WHERE Acronym = '" + outputStream.Acronym.Replace(" ", "").ToUpper() + "'").ID;

                    IList<int> keys = OutputStreamDevice.LoadKeys(database, outputStream.ID);

                    // Get all existing devices associated with output stream and delete them.
                    ObservableCollection<OutputStreamDevice> outputStreamDevices = OutputStreamDevice.Load(database, keys);
                    foreach (OutputStreamDevice outputStreamDevice in outputStreamDevices)
                        OutputStreamDevice.Delete(database, outputStream.ID, outputStreamDevice.Acronym);

                    if (!string.IsNullOrEmpty(outputStream.MirroringSourceDevice))
                    {
                        // Get list of input devices, filter by original source = outputstream.MirrorSourceDevice.
                        ObservableCollection<Device> devices = Device.GetDevices(database, "WHERE OriginalSource = '" + outputStream.MirroringSourceDevice + "'");

                        // Add these above input devices as output stream devices.
                        OutputStreamDevice.AddDevices(database, outputStream.ID, devices, true, true);
                    }
                }

                return "Output Stream Information Saved Successfully";
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #34
0
ファイル: OutputStream.cs プロジェクト: avs009/gsf
        /// <summary>
        /// Gets output stream.
        /// </summary>
        /// <param name="database">Source database connection.</param>
        /// <param name="whereClause">Where filter clause.</param>
        /// <returns>Output stream.</returns>
        public static OutputStream GetOutputStream(AdoDataConnection database, string whereClause)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);
                DataTable outputStreamTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM OutputStreamDetail " + whereClause);

                if (outputStreamTable.Rows.Count == 0)
                    return null;

                DataRow row = outputStreamTable.Rows[0];
                int type = Convert.ToInt32(row.Field<object>("Type"));

                OutputStream outputStream = new OutputStream
                    {
                        NodeID = database.Guid(row, "NodeID"),
                        ID = Convert.ToInt32(row.Field<object>("ID")),
                        Acronym = row.Field<string>("Acronym"),
                        Name = row.Field<string>("Name"),
                        Type = type,
                        ConnectionString = row.Field<string>("ConnectionString"),
                        IDCode = Convert.ToInt32(row.Field<object>("IDCode")),
                        CommandChannel = row.Field<string>("CommandChannel"),
                        DataChannel = row.Field<string>("DataChannel"),
                        AutoPublishConfigFrame = Convert.ToBoolean(row.Field<object>("AutoPublishConfigFrame")),
                        AutoStartDataChannel = Convert.ToBoolean(row.Field<object>("AutoStartDataChannel")),
                        NominalFrequency = Convert.ToInt32(row.Field<object>("NominalFrequency")),
                        FramesPerSecond = Convert.ToInt32(row.Field<object>("FramesPerSecond") ?? 30),
                        LagTime = row.ConvertField<double>("LagTime"),
                        LeadTime = row.ConvertField<double>("LeadTime"),
                        UseLocalClockAsRealTime = Convert.ToBoolean(row.Field<object>("UseLocalClockAsRealTime")),
                        AllowSortsByArrival = Convert.ToBoolean(row.Field<object>("AllowSortsByArrival")),
                        LoadOrder = Convert.ToInt32(row.Field<object>("LoadOrder")),
                        Enabled = Convert.ToBoolean(row.Field<object>("Enabled")),
                        m_nodeName = row.Field<string>("NodeName"),
                        m_typeName = (type == 1) ? "IEEE C37.118" : (type == 2) ? "BPA" : "IEC 61850-90-5",
                        IgnoreBadTimeStamps = Convert.ToBoolean(row.Field<object>("IgnoreBadTimeStamps")),
                        TimeResolution = Convert.ToInt32(row.Field<object>("TimeResolution")),
                        AllowPreemptivePublishing = Convert.ToBoolean(row.Field<object>("AllowPreemptivePublishing")),
                        DownSamplingMethod = row.Field<string>("DownsamplingMethod"),
                        DataFormat = row.Field<string>("DataFormat"),
                        CoordinateFormat = row.Field<string>("CoordinateFormat"),
                        CurrentScalingValue = Convert.ToInt32(row.Field<object>("CurrentScalingValue")),
                        VoltageScalingValue = Convert.ToInt32(row.Field<object>("VoltageScalingValue")),
                        AnalogScalingValue = Convert.ToInt32(row.Field<object>("AnalogScalingValue")),
                        DigitalMaskValue = Convert.ToInt32(row.Field<object>("DigitalMaskValue")),
                        PerformTimestampReasonabilityCheck = Convert.ToBoolean(row.Field<object>("PerformTimeReasonabilityCheck"))
                    };

                return outputStream;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #35
0
ファイル: Device.cs プロジェクト: avs009/gsf
        /// <summary>
        /// Retrieves <see cref="ObservableCollection{T}"/> type list of <see cref="Device"/> information from the database based on query string filter.
        /// </summary>
        /// <param name="database"></param>
        /// <param name="whereClause"></param>
        /// <returns></returns>
        public static ObservableCollection<Device> GetDevices(AdoDataConnection database, string whereClause)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);
                DataTable deviceTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM DeviceDetail " + whereClause);

                if (deviceTable.Rows.Count == 0)
                    return null;

                ObservableCollection<Device> deviceList = new ObservableCollection<Device>();
                foreach (DataRow row in deviceTable.Rows)
                {
                    deviceList.Add(new Device
                    {
                        NodeID = database.Guid(row, "NodeID"),
                        ID = row.ConvertField<int>("ID"),
                        ParentID = row.ConvertNullableField<int>("ParentID"),
                        UniqueID = database.Guid(row, "UniqueID"),
                        Acronym = row.Field<string>("Acronym"),
                        Name = row.Field<string>("Name"),
                        IsConcentrator = Convert.ToBoolean(row.Field<object>("IsConcentrator")),
                        CompanyID = row.ConvertNullableField<int>("CompanyID"),
                        HistorianID = row.ConvertNullableField<int>("HistorianID"),
                        AccessID = row.ConvertField<int>("AccessID"),
                        VendorDeviceID = row.ConvertNullableField<int>("VendorDeviceID"),
                        ProtocolID = row.ConvertNullableField<int>("ProtocolID"),
                        Longitude = row.ConvertNullableField<decimal>("Longitude"),
                        Latitude = row.ConvertNullableField<decimal>("Latitude"),
                        InterconnectionID = row.ConvertNullableField<int>("InterconnectionID"),
                        ConnectionString = ParseConnectionString(row.Field<string>("ConnectionString").ToNonNullString()),
                        AlternateCommandChannel = ParseAlternateCommand(row.Field<string>("ConnectionString").ToNonNullString()),
                        TimeZone = row.Field<string>("TimeZone"),
                        FramesPerSecond = Convert.ToInt32(row.Field<object>("FramesPerSecond") ?? 30),
                        TimeAdjustmentTicks = Convert.ToInt64(row.Field<object>("TimeAdjustmentTicks")),
                        DataLossInterval = row.ConvertField<double>("DataLossInterval"),
                        ContactList = row.Field<string>("ContactList"),
                        MeasuredLines = row.ConvertNullableField<int>("MeasuredLines"),
                        LoadOrder = row.ConvertField<int>("LoadOrder"),
                        Enabled = Convert.ToBoolean(row.Field<object>("Enabled")),
                        CreatedOn = row.Field<DateTime>("CreatedOn"),
                        AllowedParsingExceptions = Convert.ToInt32(row.Field<object>("AllowedParsingExceptions")),
                        ParsingExceptionWindow = row.ConvertField<double>("ParsingExceptionWindow"),
                        DelayedConnectionInterval = row.ConvertField<double>("DelayedConnectionInterval"),
                        AllowUseOfCachedConfiguration = Convert.ToBoolean(row.Field<object>("AllowUseOfCachedConfiguration")),
                        AutoStartDataParsingSequence = Convert.ToBoolean(row.Field<object>("AutoStartDataParsingSequence")),
                        SkipDisableRealTimeData = Convert.ToBoolean(row.Field<object>("SkipDisableRealTimeData")),
                        MeasurementReportingInterval = Convert.ToInt32(row.Field<object>("MeasurementReportingInterval")),
                        ConnectOnDemand = Convert.ToBoolean(row.Field<object>("ConnectOnDemand")),
                        m_companyName = row.Field<string>("CompanyName"),
                        m_companyAcronym = row.Field<string>("CompanyAcronym"),
                        m_historianAcronym = row.Field<string>("HistorianAcronym"),
                        m_vendorDeviceName = row.Field<string>("VendorDeviceName"),
                        m_vendorAcronym = row.Field<string>("VendorAcronym"),
                        m_protocolName = row.Field<string>("ProtocolName"),
                        m_protocolCategory = row.Field<string>("Category"),
                        m_interconnectionName = row.Field<string>("InterconnectionName"),
                        m_nodeName = row.Field<string>("NodeName"),
                        m_parentAcronym = row.Field<string>("ParentAcronym"),
                        m_originalSource = row.Field<string>("OriginalSource")
                    });
                }

                return deviceList;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #36
0
ファイル: Subscriber.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Saves <see cref="Subscriber"/> information to database.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="subscriber">Information about <see cref="Subscriber"/>.</param>        
        /// <returns>String, for display use, indicating success.</returns>
        public static string Save(AdoDataConnection database, Subscriber subscriber)
        {
            bool createdConnection = false;
            SslPolicyErrors validPolicyErrors;
            X509ChainStatusFlags validChainFlags;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);
                validPolicyErrors = (subscriber.ValidPolicyErrors ?? SslPolicyErrors.None) | (subscriber.RemoteCertificateIsSelfSigned ? SslPolicyErrors.RemoteCertificateChainErrors : SslPolicyErrors.None);
                validChainFlags = (subscriber.ValidChainFlags ?? X509ChainStatusFlags.NoError) | (subscriber.RemoteCertificateIsSelfSigned ? X509ChainStatusFlags.UntrustedRoot : X509ChainStatusFlags.NoError);

                if (subscriber.ID == Guid.Empty)
                {
                    query = database.ParameterizedQueryString("INSERT INTO Subscriber (NodeID, Acronym, Name, SharedSecret, AuthKey, ValidIPAddresses, RemoteCertificateFile, ValidPolicyErrors, ValidChainFlags, " +
                                                              "AccessControlFilter, Enabled, UpdatedBy, UpdatedOn, CreatedBy, CreatedOn) VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, " +
                                                              "{13}, {14})", "nodeID", "acronym", "name", "sharedSecret", "authKey", "validIPAddresses", "remoteCertificateFile", "validPolicyErrors", "validChainFlags",
                                                              "accessControlFilter", "enabled", "updatedBy", "updatedOn", "createdBy", "createdOn");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.CurrentNodeID(), subscriber.Acronym, subscriber.Name.ToNotNull(), subscriber.SharedSecret.ToNotNull(),
                                                        subscriber.AuthKey.ToNotNull(), subscriber.ValidIPAddresses.ToNotNull(), subscriber.RemoteCertificateFile.ToNotNull(), validPolicyErrors.ToString(),
                                                        validChainFlags.ToString(), subscriber.AccessControlFilter.ToNotNull(), database.Bool(subscriber.Enabled), CommonFunctions.CurrentUser, database.UtcNow,
                                                        CommonFunctions.CurrentUser, database.UtcNow);
                }
                else
                {
                    query = database.ParameterizedQueryString("UPDATE Subscriber SET NodeID = {0}, Acronym = {1}, Name = {2}, SharedSecret = {3}, AuthKey = {4}, ValidIPAddresses = {5}, RemoteCertificateFile = {6}, " +
                                                              "ValidPolicyErrors = {7}, ValidChainFlags = {8}, AccessControlFilter = {9}, Enabled = {10}, UpdatedBy = {11}, UpdatedOn = {12} WHERE ID = {13}", "nodeID",
                                                              "acronym", "name", "sharedSecret", "authKey", "validIPAddresses", "remoteCertificateFile", "validPolicyErrors", "validChainFlags", "accessControlFilter",
                                                              "enabled", "updatedBy", "updatedOn", "id");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(subscriber.NodeID), subscriber.Acronym, subscriber.Name.ToNotNull(), subscriber.SharedSecret.ToNotNull(),
                                                        subscriber.AuthKey.ToNotNull(), subscriber.ValidIPAddresses.ToNotNull(), subscriber.RemoteCertificateFile.ToNotNull(), validPolicyErrors.ToString(),
                                                        validChainFlags.ToString(), subscriber.AccessControlFilter.ToNotNull(), database.Bool(subscriber.Enabled), CommonFunctions.CurrentUser, database.UtcNow,
                                                        database.Guid(subscriber.ID));
                }

                try
                {
                    CommonFunctions.SendCommandToService("ReloadConfig");
                }
                catch (Exception ex)
                {
                    return "Subscriber information saved successfully. Failed to send ReloadConfig command to backend service." + Environment.NewLine + ex.Message;
                }

                return "Subscriber information saved successfully";
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #37
0
ファイル: UserAccount.cs プロジェクト: rmc00/gsf
        // Static Methods

        /// <summary>
        /// Loads <see cref="UserAccount"/> information as an OberservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <returns>Collection of <see cref="UserAccount"/></returns>
        public static ObservableCollection<UserAccount> Load(AdoDataConnection database)
        {
            bool createdConnection = false;
            try
            {
                createdConnection = CreateConnection(ref database);

                ObservableCollection<UserAccount> userAccountList = new ObservableCollection<UserAccount>();
                DataTable userAccountTable = database.Connection.RetrieveData(database.AdapterType, "SELECT * From UserAccount WHERE DefaultNodeID = '" + database.CurrentNodeID() + "'  ORDER BY Name");

                foreach (DataRow row in userAccountTable.Rows)
                {
                    userAccountList.Add(new UserAccount()
                    {
                        ID = database.Guid(row, "ID"),
                        Name = UserInfo.SIDToAccountName(row.Field<string>("Name")),
                        Password = row.Field<object>("Password") == null ? string.Empty : row.Field<string>("Password"),
                        FirstName = row.Field<object>("FirstName") == null ? string.Empty : row.Field<string>("FirstName"),
                        LastName = row.Field<object>("LastName") == null ? string.Empty : row.Field<string>("LastName"),
                        DefaultNodeID = database.Guid(row, "DefaultNodeID"),
                        Phone = row.Field<object>("Phone") == null ? string.Empty : row.Field<string>("Phone"),
                        Email = row.Field<object>("Email") == null ? string.Empty : row.Field<string>("Email"),
                        LockedOut = Convert.ToBoolean(row.Field<object>("LockedOut")),
                        UseADAuthentication = Convert.ToBoolean(row.Field<object>("UseADAuthentication")),
                        ChangePasswordOn = row.Field<object>("ChangePasswordOn") == null ? DateTime.MinValue : Convert.ToDateTime(row.Field<object>("ChangePasswordOn")),
                        CreatedOn = Convert.ToDateTime(row["CreatedOn"]),
                        CreatedBy = row.Field<string>("CreatedBy"),
                        UpdatedOn = Convert.ToDateTime(row.Field<object>("UpdatedOn")),
                        UpdatedBy = row.Field<string>("UpdatedBy")
                    });
                }

                userAccountList.Insert(0, new UserAccount
                {
                    ID = Guid.Empty,
                    ChangePasswordOn = DateTime.Now.AddDays(90)
                });

                return userAccountList;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #38
0
ファイル: UserAccount.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Gets a <see cref="Dictionary{T1,T2}"/> style list of <see cref="UserAccount"/> information.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="isOptional">Indicates if selection on UI is optional for this collection.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> containing ID and Name of user accounts defined in the database.</returns>
        public static Dictionary<Guid, string> GetLookupList(AdoDataConnection database, bool isOptional = false)
        {
            bool createdConnection = false;
            try
            {
                createdConnection = CreateConnection(ref database);

                Dictionary<Guid, string> userAccountList = new Dictionary<Guid, string>();
                if (isOptional)
                    userAccountList.Add(Guid.Empty, "Select UserAccount");

                DataTable userAccountTable = database.Connection.RetrieveData(database.AdapterType, "SELECT ID, Name FROM UserAccount ORDER BY Name");

                foreach (DataRow row in userAccountTable.Rows)
                    userAccountList[database.Guid(row, "ID")] = UserInfo.SIDToAccountName(row.Field<string>("Name"));

                return userAccountList;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #39
0
ファイル: Device.cs プロジェクト: avs009/gsf
        /// <summary>
        /// Loads <see cref="Device"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="keys">Keys of the measurement to be loaded from the database</param>
        /// <returns>Collection of <see cref="Device"/>.</returns>
        public static ObservableCollection<Device> Load(AdoDataConnection database, IList<int> keys)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string query;
                string commaSeparatedKeys;

                Device[] deviceList = null;
                DataTable deviceTable;
                int id;

                if ((object)keys != null && keys.Count > 0)
                {
                    commaSeparatedKeys = keys.Select(key => key.ToString()).Aggregate((str1, str2) => str1 + "," + str2);
                    query = string.Format("SELECT * FROM DeviceDetail WHERE ID IN ({0})", commaSeparatedKeys);
                    deviceTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout);
                    deviceList = new Device[deviceTable.Rows.Count];

                    foreach (DataRow row in deviceTable.Rows)
                    {
                        id = row.ConvertField<int>("ID");

                        deviceList[keys.IndexOf(id)] = new Device()
                        {
                            NodeID = database.Guid(row, "NodeID"),
                            ID = id,
                            ParentID = row.ConvertNullableField<int>("ParentID"),
                            UniqueID = database.Guid(row, "UniqueID"),
                            Acronym = row.Field<string>("Acronym"),
                            Name = row.Field<string>("Name"),
                            IsConcentrator = Convert.ToBoolean(row.Field<object>("IsConcentrator")),
                            CompanyID = row.ConvertNullableField<int>("CompanyID"),
                            HistorianID = row.ConvertNullableField<int>("HistorianID"),
                            AccessID = row.ConvertField<int>("AccessID"),
                            VendorDeviceID = row.ConvertNullableField<int>("VendorDeviceID"),
                            ProtocolID = row.ConvertNullableField<int>("ProtocolID"),
                            Longitude = row.ConvertNullableField<decimal>("Longitude"),
                            Latitude = row.ConvertNullableField<decimal>("Latitude"),
                            InterconnectionID = row.ConvertNullableField<int>("InterconnectionID"),
                            ConnectionString = ParseConnectionString(row.Field<string>("ConnectionString").ToNonNullString()),
                            AlternateCommandChannel = ParseAlternateCommand(row.Field<string>("ConnectionString").ToNonNullString()),
                            TimeZone = row.Field<string>("TimeZone"),
                            FramesPerSecond = Convert.ToInt32(row.Field<object>("FramesPerSecond") ?? 30),
                            TimeAdjustmentTicks = Convert.ToInt64(row.Field<object>("TimeAdjustmentTicks")),
                            DataLossInterval = row.ConvertField<double>("DataLossInterval"),
                            ContactList = row.Field<string>("ContactList"),
                            MeasuredLines = row.ConvertNullableField<int>("MeasuredLines"),
                            LoadOrder = row.ConvertField<int>("LoadOrder"),
                            Enabled = Convert.ToBoolean(row.Field<object>("Enabled")),
                            CreatedOn = row.Field<DateTime>("CreatedOn"),
                            AllowedParsingExceptions = Convert.ToInt32(row.Field<object>("AllowedParsingExceptions")),
                            ParsingExceptionWindow = row.ConvertField<double>("ParsingExceptionWindow"),
                            DelayedConnectionInterval = row.ConvertField<double>("DelayedConnectionInterval"),
                            AllowUseOfCachedConfiguration = Convert.ToBoolean(row.Field<object>("AllowUseOfCachedConfiguration")),
                            AutoStartDataParsingSequence = Convert.ToBoolean(row.Field<object>("AutoStartDataParsingSequence")),
                            SkipDisableRealTimeData = Convert.ToBoolean(row.Field<object>("SkipDisableRealTimeData")),
                            MeasurementReportingInterval = Convert.ToInt32(row.Field<object>("MeasurementReportingInterval")),
                            ConnectOnDemand = Convert.ToBoolean(row.Field<object>("ConnectOnDemand")),
                            m_companyName = row.Field<string>("CompanyName"),
                            m_companyAcronym = row.Field<string>("CompanyAcronym"),
                            m_historianAcronym = row.Field<string>("HistorianAcronym"),
                            m_vendorDeviceName = row.Field<string>("VendorDeviceName"),
                            m_vendorAcronym = row.Field<string>("VendorAcronym"),
                            m_protocolName = row.Field<string>("ProtocolName"),
                            m_protocolCategory = row.Field<string>("Category"),
                            m_interconnectionName = row.Field<string>("InterconnectionName"),
                            m_nodeName = row.Field<string>("NodeName"),
                            m_parentAcronym = row.Field<string>("ParentAcronym"),
                            m_originalSource = row.Field<string>("OriginalSource")
                        };
                    }
                }

                return new ObservableCollection<Device>(deviceList ?? new Device[0]);
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #40
0
ファイル: MeasurementGroup.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Retrieves a <see cref="Dictionary{T1,T2}"/> style list of <see cref="Measurement"/> assigned to <see cref="MeasurementGroup"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="measurementGroupId">ID of the <see cref="MeasurementGroup"/> to filter data.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> containing SignalID and PointTag of <see cref="Measurement"/>s assigned to <see cref="MeasurementGroup"/>.</returns>
        public static Dictionary<Guid, string> GetCurrentMeasurements(AdoDataConnection database, int measurementGroupId)
        {
            Dictionary<Guid, string> currentMeasurements;
            DataTable currentMeasurementTable;
            bool createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);
                currentMeasurements = new Dictionary<Guid, string>();
                query = database.ParameterizedQueryString("SELECT * FROM MeasurementGroupMeasDetail WHERE MeasurementGroupID = {0} ORDER BY PointID", "measurementGroupID");
                currentMeasurementTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, measurementGroupId);

                foreach (DataRow row in currentMeasurementTable.Rows)
                    currentMeasurements[database.Guid(row, "SignalID")] = row.Field<string>("PointTag");

                return currentMeasurements;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #41
0
ファイル: Device.cs プロジェクト: avs009/gsf
        /// <summary>
        /// Saves <see cref="Device"/> information to database along with analogs and digital measurements if requested..
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="device">Information about <see cref="Device"/>.</param>
        /// <param name="notifyService">Boolean value to notify service if needed.</param>
        /// <param name="digitalCount">Number of digital measurements to add.</param>
        /// <param name="analogCount">Number of analog measurements to add.</param>
        /// <param name="digitalLabels">Collection of digital labels associated with a device in configuration frame.</param>
        /// <param name="analogLabels">Collection of analog labels associated with a device in configuration frame.</param>
        /// <returns>String, for display use, indicating success.</returns>
        public static string SaveWithAnalogsDigitals(AdoDataConnection database, Device device, bool notifyService, int digitalCount, int analogCount, List<string> digitalLabels = null, List<string> analogLabels = null)
        {
            bool createdConnection = false;
            string query;

            try
            {
                Device oldDevice = null;

                createdConnection = CreateConnection(ref database);

                object nodeID;

                if (device.NodeID == Guid.Empty)
                    nodeID = database.CurrentNodeID();
                else
                    nodeID = database.Guid(device.NodeID);

                if (device.ID == 0)
                {
                    query = database.ParameterizedQueryString("INSERT INTO Device (NodeID, ParentID, UniqueID, Acronym, Name, IsConcentrator, CompanyID, HistorianID, AccessID, VendorDeviceID, " +
                        "ProtocolID, Longitude, Latitude, InterconnectionID, ConnectionString, TimeZone, FramesPerSecond, TimeAdjustmentTicks, DataLossInterval, ContactList, " +
                        "MeasuredLines, LoadOrder, Enabled, AllowedParsingExceptions, ParsingExceptionWindow, DelayedConnectionInterval, AllowUseOfCachedConfiguration, " +
                        "AutoStartDataParsingSequence, SkipDisableRealTimeData, MeasurementReportingInterval, ConnectOndemand, UpdatedBy, UpdatedOn, CreatedBy, CreatedOn) Values " +
                        "({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, {12}, {13}, {14}, {15}, {16}, {17}, {18}, {19}, {20}, {21}, {22}, {23}, {24}, {25}, " +
                        "{26}, {27}, {28}, {29}, {30}, {31}, {32}, {33}, {34})", "nodeID", "parentID", "uniqueID", "acronym", "name", "isConcentrator", "companyID",
                        "historianID", "accessID", "vendorDeviceID", "protocolID", "longitude", "latitude", "interconnectionID", "connectionString", "timezone",
                        "framesPerSecond", "timeAdjustmentTicks", "dataLossInterval", "contactList", "measuredLines", "loadOrder", "enabled", "allowedParsingExceptions",
                        "parsingExceptionWindow", "delayedConnectionInterval", "allowUseOfCachedConfiguration", "autoStartDataParsingSequence", "skipDisableRealTimeData",
                        "measurementReportingInterval", "connectOndemand", "updatedBy", "updatedOn", "createdBy", "createdOn");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, nodeID,
                        device.ParentID.ToNotNull(), database.Guid(Guid.NewGuid()), device.Acronym.Replace(" ", "").ToUpper(), device.Name.ToNotNull(), database.Bool(device.IsConcentrator), device.CompanyID.ToNotNull(),
                        device.HistorianID.ToNotNull(), device.AccessID, device.VendorDeviceID.ToNotNull(),
                        device.ProtocolID.ToNotNull(), device.Longitude.ToNotNull(), device.Latitude.ToNotNull(), device.InterconnectionID.ToNotNull(),
                        BuildConnectionString(device), device.TimeZone.ToNotNull(), device.FramesPerSecond ?? 30, device.TimeAdjustmentTicks, device.DataLossInterval, device.ContactList.ToNotNull(), device.MeasuredLines.ToNotNull(),
                        device.LoadOrder, database.Bool(device.Enabled), device.AllowedParsingExceptions, device.ParsingExceptionWindow, device.DelayedConnectionInterval, database.Bool(device.AllowUseOfCachedConfiguration),
                        database.Bool(device.AutoStartDataParsingSequence), database.Bool(device.SkipDisableRealTimeData), device.MeasurementReportingInterval, database.Bool(device.ConnectOnDemand), CommonFunctions.CurrentUser,
                        database.UtcNow, CommonFunctions.CurrentUser, database.UtcNow);
                }
                else
                {
                    oldDevice = GetDevice(database, " WHERE ID = " + device.ID);

                    query = database.ParameterizedQueryString("UPDATE Device SET NodeID = {0}, ParentID = {1}, UniqueID = {2}, Acronym = {3}, Name = {4}, " +
                        "IsConcentrator = {5}, CompanyID = {6}, HistorianID = {7}, AccessID = {8}, VendorDeviceID = {9}, ProtocolID = {10}, Longitude = {11}, " +
                        "Latitude = {12}, InterconnectionID = {13}, ConnectionString = {14}, TimeZone = {15}, FramesPerSecond = {16}, TimeAdjustmentTicks = {17}, " +
                        "DataLossInterval = {18}, ContactList = {19}, MeasuredLines = {20}, LoadOrder = {21}, Enabled = {22}, AllowedParsingExceptions = {23}, " +
                        "ParsingExceptionWindow = {24}, DelayedConnectionInterval = {25}, AllowUseOfCachedConfiguration = {26}, AutoStartDataParsingSequence = {27}, " +
                        "SkipDisableRealTimeData = {28}, MeasurementReportingInterval = {29}, ConnectOnDemand = {30}, UpdatedBy = {31}, UpdatedOn = {32} WHERE ID = {33}",
                        "nodeID", "parentID", "uniqueID", "acronym", "name", "isConcentrator", "companyID", "historianID", "accessID", "vendorDeviceID", "protocolID",
                        "longitude", "latitude", "interconnectionID", "connectionString", "timezone", "framesPerSecond", "timeAdjustmentTicks", "dataLossInterval",
                        "contactList", "measuredLines", "loadOrder", "enabled", "allowedParsingExceptions", "parsingExceptionWindow", "delayedConnectionInterval",
                        "allowUseOfCachedConfiguration", "autoStartDataParsingSequence", "skipDisableRealTimeData", "measurementReportingInterval", "connectOnDemand",
                        "updatedBy", "updatedOn", "id");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, nodeID,
                        device.ParentID.ToNotNull(), database.Guid(device.UniqueID), device.Acronym.Replace(" ", "").ToUpper(), device.Name.ToNotNull(), database.Bool(device.IsConcentrator), device.CompanyID.ToNotNull(),
                        device.HistorianID.ToNotNull(), device.AccessID, device.VendorDeviceID.ToNotNull(),
                        device.ProtocolID.ToNotNull(), device.Longitude.ToNotNull(), device.Latitude.ToNotNull(), device.InterconnectionID.ToNotNull(),
                        BuildConnectionString(device), device.TimeZone.ToNotNull(), device.FramesPerSecond ?? 30, device.TimeAdjustmentTicks, device.DataLossInterval, device.ContactList.ToNotNull(), device.MeasuredLines.ToNotNull(),
                        device.LoadOrder, database.Bool(device.Enabled), device.AllowedParsingExceptions, device.ParsingExceptionWindow, device.DelayedConnectionInterval, database.Bool(device.AllowUseOfCachedConfiguration),
                        database.Bool(device.AutoStartDataParsingSequence), database.Bool(device.SkipDisableRealTimeData), device.MeasurementReportingInterval, database.Bool(device.ConnectOnDemand), CommonFunctions.CurrentUser,
                        database.UtcNow, device.ID);
                }


                Device savedDevice = GetDevice(database, "WHERE Acronym = '" + device.Acronym.Replace(" ", "").ToUpper() + "'");

                if ((object)savedDevice == null)
                    return "Device information saved successfully but failed to create measurements";

                // Determine if device is using a phasor protocol
                bool deviceIsUsingPhasorProtocol = (string.Compare(savedDevice.ProtocolCategory, "Phasor", StringComparison.OrdinalIgnoreCase) == 0);

                // Add default measurements for non-concentrator devices when device protocol category is Phasor 
                if (!savedDevice.IsConcentrator && deviceIsUsingPhasorProtocol)
                {
                    // Setup and/or validate default signals associated with non-concentrator devices (e.g., directly connected PMUs or PMUs in a concentrator)
                    foreach (TimeSeries.UI.DataModels.SignalType signal in TimeSeries.UI.DataModels.SignalType.GetPmuSignalTypes())
                    {
                        Measurement measurement;

                        if (signal.Suffix == "AV" && analogCount > 0)
                        {
                            for (int i = 1; i <= analogCount; i++)
                            {
                                measurement = Measurement.GetMeasurement(database, "WHERE DeviceID = " + savedDevice.ID + " AND SignalReference = '" + savedDevice.Acronym + "-AV" + i + "'");

                                if ((object)measurement == null)
                                {
                                    measurement = new Measurement();

                                    measurement.DeviceID = savedDevice.ID;
                                    measurement.HistorianID = savedDevice.HistorianID;
                                    measurement.PointTag = CommonPhasorServices.CreatePointTag(savedDevice.CompanyAcronym, savedDevice.Acronym, savedDevice.VendorAcronym, "ALOG", i);
                                    measurement.SignalReference = savedDevice.Acronym + "-AV" + i;
                                    measurement.Description = savedDevice.Name + (string.IsNullOrWhiteSpace(savedDevice.VendorDeviceName) ? "" : " " + savedDevice.VendorDeviceName) + " Analog Value " + i;
                                    measurement.SignalTypeID = signal.ID;
                                    measurement.PhasorSourceIndex = (int?)null;
                                    measurement.Enabled = true;

                                    if ((object)analogLabels != null && (object)analogLabels[i - 1] != null)
                                        measurement.AlternateTag = analogLabels[i - 1];

                                    Measurement.Save(database, measurement);
                                }
                                else if (measurement.SignalTypeID != signal.ID)
                                {
                                    // Correct signal type if it has been changed
                                    measurement.SignalTypeID = signal.ID;
                                    Measurement.Save(database, measurement);
                                }
                            }
                        }
                        else if (signal.Suffix == "DV" && digitalCount > 0)
                        {
                            for (int i = 1; i <= digitalCount; i++)
                            {
                                measurement = Measurement.GetMeasurement(database, "WHERE DeviceID = " + savedDevice.ID + " AND SignalReference = '" + savedDevice.Acronym + "-DV" + i + "'");

                                if ((object)measurement == null)
                                {
                                    measurement = new Measurement();

                                    measurement.DeviceID = savedDevice.ID;
                                    measurement.HistorianID = savedDevice.HistorianID;
                                    measurement.PointTag = CommonPhasorServices.CreatePointTag(savedDevice.CompanyAcronym, savedDevice.Acronym, savedDevice.VendorAcronym, "DIGI", i);
                                    measurement.SignalReference = savedDevice.Acronym + "-DV" + i;
                                    measurement.SignalTypeID = signal.ID;
                                    measurement.Description = savedDevice.Name + (string.IsNullOrWhiteSpace(savedDevice.VendorDeviceName) ? "" : " " + savedDevice.VendorDeviceName) + " Digital Value " + i;
                                    measurement.PhasorSourceIndex = (int?)null;
                                    measurement.Enabled = true;

                                    if ((object)digitalLabels != null && (object)digitalLabels[i - 1] != null)
                                        measurement.AlternateTag = digitalLabels[i - 1];

                                    Measurement.Save(database, measurement);
                                }
                                else if (measurement.SignalTypeID != signal.ID)
                                {
                                    // Correct signal type if it has been changed
                                    measurement.SignalTypeID = signal.ID;
                                    Measurement.Save(database, measurement);
                                }
                            }
                        }
                        else if (signal.Suffix == "FQ" || signal.Suffix == "DF" || signal.Suffix == "SF")
                        {
                            measurement = Measurement.GetMeasurement(database, "WHERE DeviceID = " + savedDevice.ID + " AND SignalTypeSuffix = '" + signal.Suffix + "'");

                            if ((object)measurement == null)
                            {
                                measurement = new Measurement();

                                measurement.DeviceID = savedDevice.ID;
                                measurement.HistorianID = savedDevice.HistorianID;
                                measurement.PointTag = CommonPhasorServices.CreatePointTag(savedDevice.CompanyAcronym, savedDevice.Acronym, savedDevice.VendorAcronym, signal.Acronym);
                                measurement.SignalReference = savedDevice.Acronym + "-" + signal.Suffix;
                                measurement.SignalTypeID = signal.ID;
                                measurement.Description = savedDevice.Name + (string.IsNullOrWhiteSpace(savedDevice.VendorDeviceName) ? "" : " " + savedDevice.VendorDeviceName) + " " + signal.Name;
                                measurement.PhasorSourceIndex = (int?)null;
                                measurement.Enabled = true;

                                Measurement.Save(database, measurement);
                            }

                            // Based on query filter of SignalTypeSuffix, the following will never be true
                            //else if (measurement.SignalTypeID != signal.ID)
                            //{
                            //    // Correct signal type if it has been changed
                            //    measurement.SignalTypeID = signal.ID;
                            //    Measurement.Save(database, measurement);
                            //}
                        }
                    }
                }

                if (device.ID > 0)
                {
                    if (!device.IsConcentrator)
                    {
                        // For existing non-concentrator devices, call Save on each phasor so that measurements related to those phasors will reflect possible device changes.
                        IList<int> keys = Phasor.LoadKeys(database, device.ID);

                        foreach (Phasor phasor in Phasor.Load(database, keys))
                        {
                            Phasor.SaveWithoutMeasurementUpdate(database, phasor);
                        }
                    }

                    // Update existing device measurements to reflect possible device changes
                    if ((object)oldDevice != null)
                    {
                        bool companyUpdated = (deviceIsUsingPhasorProtocol && savedDevice.CompanyID != oldDevice.CompanyID);
                        bool deviceRenamed = (deviceIsUsingPhasorProtocol && (string.CompareOrdinal(savedDevice.Acronym, oldDevice.Acronym) != 0 || string.CompareOrdinal(savedDevice.Name, oldDevice.Name) != 0));
                        bool historianUpdated = (savedDevice.HistorianID != oldDevice.HistorianID);

                        if (companyUpdated || deviceRenamed || historianUpdated)
                        {
                            string companyAcronym = "";
                            int underScoreIndex;

                            if (companyUpdated)
                            {
                                if (savedDevice.CompanyID.HasValue && !string.IsNullOrWhiteSpace(savedDevice.CompanyAcronym))
                                    companyAcronym = savedDevice.CompanyAcronym;
                            }

                            foreach (Measurement measurement in Measurement.GetMeasurements(database, "WHERE DeviceID = " + oldDevice.ID))
                            {
                                if (companyUpdated)
                                {
                                    // WARNING: This assumes company name is followed by an underscore - this may not be a valid assumption for custom point tag naming conventions
                                    underScoreIndex = measurement.PointTag.ToNonNullString().IndexOf('_');

                                    if (underScoreIndex > -1)
                                        measurement.PointTag = companyAcronym + measurement.PointTag.Substring(underScoreIndex);
                                }

                                if (deviceRenamed)
                                {
                                    measurement.PointTag = measurement.PointTag.Replace(oldDevice.Acronym, savedDevice.Acronym);
                                    measurement.SignalReference = measurement.SignalReference.Replace(oldDevice.Acronym, savedDevice.Acronym);
                                    measurement.Description = Regex.Replace(measurement.Description.ToNonNullString(), oldDevice.Name, savedDevice.Name, RegexOptions.IgnoreCase);
                                }

                                if (historianUpdated && string.Compare(measurement.HistorianAcronym, "STAT", StringComparison.OrdinalIgnoreCase) != 0)
                                    measurement.HistorianID = savedDevice.HistorianID;

                                Measurement.Save(database, measurement);
                            }
                        }

                        // If changing the historian for a concentrator style device - must assume desire to change historian for all children devices
                        if (historianUpdated && device.IsConcentrator)
                        {
                            foreach (Device childDevice in GetDevices(database, "WHERE ParentID = " + device.ID))
                            {
                                // Recursively call this function for each child device with updated historian which will also fix measurement's historian
                                childDevice.HistorianID = savedDevice.HistorianID;
                                SaveWithAnalogsDigitals(database, childDevice, false, 0, 0);
                            }
                        }
                    }
                }

                try
                {
                    // Notify service about configuration changes made here.              
                    if (notifyService)
                        NotifyService(savedDevice);
                }
                catch (Exception ex)
                {
                    return "Device information saved successfully. Failed to send Initialize command to backend service." + Environment.NewLine + ex.Message;
                }

                return "Device information saved successfully";
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #42
0
ファイル: Subscriber.cs プロジェクト: avs009/gsf
        /// <summary>
        /// Removes measurements from <see cref="Subscriber"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="subscriberID">ID of the <see cref="Subscriber"/> from which measurements to be removed.</param>
        /// <param name="measurementsToBeRemoved">List of <see cref="Measurement"/> IDs to be removed.</param>
        /// <returns>string, indicating success for UI display.</returns>
        public static string RemoveMeasurements(AdoDataConnection database, Guid subscriberID, List<Guid> measurementsToBeRemoved)
        {
            bool createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);

                foreach (Guid id in measurementsToBeRemoved)
                {
                    query = database.ParameterizedQueryString("DELETE FROM SubscriberMeasurement WHERE SubscriberID = {0} AND SignalID = {1}", "subscriberID", "signalID");
                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(subscriberID), database.Guid(id));
                }

                return "Selected measurements removed successfully";
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #43
0
ファイル: Device.cs プロジェクト: avs009/gsf
        /// <summary>
        /// Retrieves devices for output stream.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="outputStreamID">ID of the output stream to filter out devices that already exist.</param>
        /// <returns>Collection of <see cref="Device"/>.</returns>
        public static ObservableCollection<Device> GetNewDevicesForOutputStream(AdoDataConnection database, int outputStreamID)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                ObservableCollection<Device> deviceList = new ObservableCollection<Device>();
                DataTable deviceTable;
                string query;

                // Note that OleDB does not support parameterized sub-query.
                if (database.DatabaseType == DatabaseType.Access)
                {
                    query = database.ParameterizedQueryString("SELECT * FROM DeviceDetail WHERE NodeID = {0} AND IsConcentrator = {1} AND Acronym NOT IN "
                        + "(SELECT Acronym FROM OutputStreamDevice WHERE AdapterID = " + outputStreamID + ") ORDER BY Acronym", "nodeID", "isConcentrator");

                    deviceTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID(), database.Bool(false));
                }
                else
                {
                    query = database.ParameterizedQueryString("SELECT * FROM DeviceDetail WHERE NodeID = {0} AND IsConcentrator = {1} AND Acronym NOT IN "
                        + "(SELECT Acronym FROM OutputStreamDevice WHERE AdapterID = {2}) ORDER BY Acronym", "nodeID", "isConcentrator", "adapterID");

                    deviceTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID(), database.Bool(false), outputStreamID);
                }

                foreach (DataRow row in deviceTable.Rows)
                {
                    deviceList.Add(new Device
                    {
                        NodeID = database.Guid(row, "NodeID"),
                        ID = row.ConvertField<int>("ID"),
                        ParentID = row.ConvertNullableField<int>("ParentID"),
                        UniqueID = database.Guid(row, "UniqueID"),
                        Acronym = row.Field<string>("Acronym"),
                        Name = row.Field<string>("Name"),
                        IsConcentrator = Convert.ToBoolean(row.Field<object>("IsConcentrator")),
                        CompanyID = row.ConvertNullableField<int>("CompanyID"),
                        HistorianID = row.ConvertNullableField<int>("HistorianID"),
                        AccessID = row.ConvertField<int>("AccessID"),
                        VendorDeviceID = row.ConvertNullableField<int>("VendorDeviceID"),
                        ProtocolID = row.ConvertNullableField<int>("ProtocolID"),
                        Longitude = row.ConvertNullableField<decimal>("Longitude"),
                        Latitude = row.ConvertNullableField<decimal>("Latitude"),
                        InterconnectionID = row.ConvertNullableField<int>("InterconnectionID"),
                        ConnectionString = ParseConnectionString(row.Field<string>("ConnectionString").ToNonNullString()),
                        AlternateCommandChannel = ParseAlternateCommand(row.Field<string>("ConnectionString").ToNonNullString()),
                        TimeZone = row.Field<string>("TimeZone"),
                        FramesPerSecond = Convert.ToInt32(row.Field<object>("FramesPerSecond") ?? 30),
                        TimeAdjustmentTicks = Convert.ToInt64(row.Field<object>("TimeAdjustmentTicks")),
                        DataLossInterval = row.ConvertField<double>("DataLossInterval"),
                        ContactList = row.Field<string>("ContactList"),
                        MeasuredLines = row.ConvertNullableField<int>("MeasuredLines"),
                        LoadOrder = row.ConvertField<int>("LoadOrder"),
                        Enabled = false, // We will use enable flag for check boxes on output stream device wizard so that we do not need to add selected flag.
                        CreatedOn = row.Field<DateTime>("CreatedOn"),
                        AllowedParsingExceptions = Convert.ToInt32(row.Field<object>("AllowedParsingExceptions")),
                        ParsingExceptionWindow = row.ConvertField<double>("ParsingExceptionWindow"),
                        DelayedConnectionInterval = row.ConvertField<double>("DelayedConnectionInterval"),
                        AllowUseOfCachedConfiguration = Convert.ToBoolean(row.Field<object>("AllowUseOfCachedConfiguration")),
                        AutoStartDataParsingSequence = Convert.ToBoolean(row.Field<object>("AutoStartDataParsingSequence")),
                        SkipDisableRealTimeData = Convert.ToBoolean(row.Field<object>("SkipDisableRealTimeData")),
                        MeasurementReportingInterval = Convert.ToInt32(row.Field<object>("MeasurementReportingInterval")),
                        ConnectOnDemand = Convert.ToBoolean(row.Field<object>("ConnectOnDemand")),
                        m_companyName = row.Field<string>("CompanyName"),
                        m_companyAcronym = row.Field<string>("CompanyAcronym"),
                        m_historianAcronym = row.Field<string>("HistorianAcronym"),
                        m_vendorDeviceName = row.Field<string>("VendorDeviceName"),
                        m_vendorAcronym = row.Field<string>("VendorAcronym"),
                        m_protocolName = row.Field<string>("ProtocolName"),
                        m_protocolCategory = row.Field<string>("Category"),
                        m_interconnectionName = row.Field<string>("InterconnectionName"),
                        m_nodeName = row.Field<string>("NodeName"),
                        m_parentAcronym = row.Field<string>("ParentAcronym"),
                        m_originalSource = row.Field<string>("OriginalSource")
                    });
                }

                return deviceList;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #44
0
ファイル: Subscriber.cs プロジェクト: avs009/gsf
        /// <summary>
        /// Adds measurement groups to <see cref="Subscriber"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="subscriberID">ID of the <see cref="Subscriber"/> to which measurements to be added.</param>
        /// <param name="measurementGroupsToBeAdded">List of <see cref="MeasurementGroup"/> IDs to be added.</param>
        /// <param name="allowed">boolean flag to indicate if measurement groups are allowed or denied.</param>
        /// <returns>string, indicating success for UI display.</returns>
        public static string AddMeasurementGroups(AdoDataConnection database, Guid subscriberID, List<int> measurementGroupsToBeAdded, bool allowed)
        {
            bool createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);

                foreach (int id in measurementGroupsToBeAdded)
                {
                    query = database.ParameterizedQueryString("INSERT INTO SubscriberMeasurementGroup (NodeID, SubscriberID, MeasurementGroupID, Allowed, UpdatedOn, " +
                        "UpdatedBy, CreatedOn, CreatedBy) VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7})", "nodeID", "subscriberID", "measurementGroupID",
                        "allowed", "updatedOn", "updatedBy", "createdOn", "createdBy");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.CurrentNodeID(), database.Guid(subscriberID), id, database.Bool(allowed),
                        database.UtcNow, CommonFunctions.CurrentUser, database.UtcNow, CommonFunctions.CurrentUser);
                }

                if (allowed)
                    return "Measurement groups added to allowed measurement groups list for subscriber successfully";
                else
                    return "Measurement groups added to denied measurement groups list for subscriber successfully";
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #45
0
ファイル: CommonPhasorServices.cs プロジェクト: avs009/gsf
        private static void PhasorDataSourceValidation(AdoDataConnection database, string nodeIDQueryString, ulong trackingVersion, string arguments, Action<string> statusMessage, Action<Exception> processException)
        {
            // Make sure setting exists to allow user to by-pass phasor data source validation at startup
            ConfigurationFile configFile = ConfigurationFile.Current;
            CategorizedSettingsElementCollection settings = configFile.Settings["systemSettings"];
            settings.Add("ProcessPhasorDataSourceValidation", true, "Determines if the phasor data source validation should be processed at startup");

            // See if this node should process phasor source validation
            if (!settings["ProcessPhasorDataSourceValidation"].ValueAsBoolean())
                return;

            Dictionary<string, string> args = new Dictionary<string, string>();
            bool skipOptimization = false, renameAllPointTags = false;
            string arg, acronym;

            if (!string.IsNullOrEmpty(arguments))
                args = arguments.ParseKeyValuePairs();

            if (args.TryGetValue("skipOptimization", out arg))
                skipOptimization = arg.ParseBoolean();

            if (args.TryGetValue("renameAllPointTags", out arg))
                renameAllPointTags = arg.ParseBoolean();

            CreateDefaultNode(database, nodeIDQueryString, statusMessage, processException);
            LoadDefaultConfigurationEntity(database, statusMessage, processException);
            LoadDefaultInterconnection(database, statusMessage, processException);
            LoadDefaultProtocol(database, statusMessage, processException);
            LoadDefaultSignalType(database, statusMessage, processException);
            LoadDefaultStatistic(database, statusMessage, processException);
            EstablishDefaultMeasurementKeyCache(database, statusMessage, processException);

            statusMessage("Validating signal types...");

            // Validate that the acronym for status flags is FLAG (it was STAT in prior versions)
            if (database.Connection.ExecuteScalar("SELECT Acronym FROM SignalType WHERE Suffix='SF'").ToNonNullString().ToUpper() == "STAT")
                database.Connection.ExecuteNonQuery("UPDATE SignalType SET Acronym='FLAG' WHERE Suffix='SF'");

            // Validate that the calculation and statistic signal types are defined (they did not in initial release)
            if (Convert.ToInt32(database.Connection.ExecuteScalar("SELECT COUNT(*) FROM SignalType WHERE Acronym='CALC'")) == 0)
                database.Connection.ExecuteNonQuery("INSERT INTO SignalType(Name, Acronym, Suffix, Abbreviation, LongAcronym, Source, EngineeringUnits) VALUES('Calculated Value', 'CALC', 'CV', 'CV', 'Calculated', 'PMU', '')");

            if (Convert.ToInt32(database.Connection.ExecuteScalar("SELECT COUNT(*) FROM SignalType WHERE Acronym='STAT'")) == 0)
                database.Connection.ExecuteNonQuery("INSERT INTO SignalType(Name, Acronym, Suffix, Abbreviation, LongAcronym, Source, EngineeringUnits) VALUES('Statistic', 'STAT', 'ST', 'ST', 'Statistic', 'Any', '')");

            if (Convert.ToInt32(database.Connection.ExecuteScalar("SELECT COUNT(*) FROM SignalType WHERE Acronym='QUAL'")) == 0)
                database.Connection.ExecuteNonQuery("INSERT INTO SignalType(Name, Acronym, Suffix, Abbreviation, LongAcronym, Source, EngineeringUnits) VALUES('Quality Flags', 'QUAL', 'QF', 'QF', 'QualityFlags', 'Frame', '')");

            // Make sure values are defined for long acronyms (did not exist in prior versions)
            if (Convert.ToInt32(database.Connection.ExecuteScalar("SELECT COUNT(*) FROM SignalType WHERE LongAcronym='Undefined'")) > 0)
            {
                // Update abbreviations to better values for consistent custom point tag naming convention
                if (database.Connection.ExecuteScalar("SELECT Abbreviation FROM SignalType WHERE Acronym='ALOG'").ToNonNullString().ToUpper() == "A")
                    database.Connection.ExecuteNonQuery("UPDATE SignalType SET Abbreviation='AV' WHERE Acronym='ALOG'");

                if (database.Connection.ExecuteScalar("SELECT Abbreviation FROM SignalType WHERE Acronym='DIGI'").ToNonNullString().ToUpper() == "D")
                    database.Connection.ExecuteNonQuery("UPDATE SignalType SET Abbreviation='DV' WHERE Acronym='DIGI'");

                if (database.Connection.ExecuteScalar("SELECT Abbreviation FROM SignalType WHERE Acronym='CALC'").ToNonNullString().ToUpper() == "C")
                    database.Connection.ExecuteNonQuery("UPDATE SignalType SET Abbreviation='CV' WHERE Acronym='CALC'");

                if (database.Connection.ExecuteScalar("SELECT Abbreviation FROM SignalType WHERE Acronym='STAT'").ToNonNullString().ToUpper() == "P")
                    database.Connection.ExecuteNonQuery("UPDATE SignalType SET Abbreviation='ST' WHERE Acronym='STAT'");

                if (database.Connection.ExecuteScalar("SELECT Abbreviation FROM SignalType WHERE Acronym='QUAL'").ToNonNullString().ToUpper() == "Q")
                    database.Connection.ExecuteNonQuery("UPDATE SignalType SET Abbreviation='QF' WHERE Acronym='QUAL'");

                IEnumerable<DataRow> signalTypes = database.Connection.RetrieveData(database.AdapterType, "SELECT Name, Acronym FROM SignalType WHERE LongAcronym='Undefined'").AsEnumerable();
                string longAcronym;

                foreach (DataRow row in signalTypes)
                {
                    acronym = row.Field<string>("Acronym").ToUpperInvariant().Trim();

                    switch (acronym)
                    {
                        case "IPHM":
                            longAcronym = "CurrentMagnitude";
                            break;
                        case "IPHA":
                            longAcronym = "CurrentAngle";
                            break;
                        case "VPHM":
                            longAcronym = "VoltageMagnitude";
                            break;
                        case "VPHA":
                            longAcronym = "VoltageAngle";
                            break;
                        case "FREQ":
                            longAcronym = "Frequency";
                            break;
                        case "DFDT":
                            longAcronym = "DfDt";
                            break;
                        case "ALOG":
                            longAcronym = "Analog";
                            break;
                        case "FLAG":
                            longAcronym = "StatusFlags";
                            break;
                        case "DIGI":
                            longAcronym = "Digital";
                            break;
                        case "CALC":
                            longAcronym = "Calculated";
                            break;
                        case "STAT":
                            longAcronym = "Statistic";
                            break;
                        case "ALRM":
                            longAcronym = "Alarm";
                            break;
                        case "QUAL":
                            longAcronym = "QualityFlags";
                            break;
                        default:
                            longAcronym = row.Field<string>("Name").Trim().RemoveWhiteSpace();

                            if (string.IsNullOrEmpty(longAcronym))
                                longAcronym = acronym.ToNonNullString("?");

                            break;
                    }

                    database.Connection.ExecuteNonQuery(string.Format("UPDATE SignalType SET LongAcronym='{0}' WHERE Acronym='{1}'", longAcronym, acronym));
                }
            }

            statusMessage("Validating output stream device ID codes...");

            // Validate all ID codes for output stream devices are not set their default value
            database.Connection.ExecuteNonQuery("UPDATE OutputStreamDevice SET IDCode = ID WHERE IDCode = 0");

            statusMessage("Verifying statistics archive exists...");

            // Validate that the statistics historian exists
            if (Convert.ToInt32(database.Connection.ExecuteScalar(string.Format("SELECT COUNT(*) FROM Historian WHERE Acronym='STAT' AND NodeID={0}", nodeIDQueryString))) == 0)
                database.Connection.ExecuteNonQuery(string.Format("INSERT INTO Historian(NodeID, Acronym, Name, AssemblyName, TypeName, ConnectionString, IsLocal, Description, LoadOrder, Enabled) VALUES({0}, 'STAT', 'Statistics Archive', 'HistorianAdapters.dll', 'HistorianAdapters.LocalOutputAdapter', '', 1, 'Local historian used to archive system statistics', 9999, 1)", nodeIDQueryString));

            // Make sure statistics path exists to hold historian files
            string statisticsPath = FilePath.GetAbsolutePath(FilePath.AddPathSuffix("Statistics"));

            if (!Directory.Exists(statisticsPath))
                Directory.CreateDirectory(statisticsPath);

            // Make sure needed statistic historian configuration settings are properly defined
            settings = configFile.Settings["statMetadataFile"];
            settings.Add("FileName", string.Format("Statistics{0}stat_dbase.dat", Path.DirectorySeparatorChar), "Name of the statistics meta-data file including its path.");
            settings.Add("LoadOnOpen", true, "True if file records are to be loaded in memory when opened; otherwise False - this defaults to True for the statistics meta-data file.");
            settings.Add("ReloadOnModify", false, "True if file records loaded in memory are to be re-loaded when file is modified on disk; otherwise False - this defaults to False for the statistics meta-data file.");
            settings["LoadOnOpen"].Update(true);
            settings["ReloadOnModify"].Update(false);

            settings = configFile.Settings["statStateFile"];
            settings.Add("FileName", string.Format("Statistics{0}stat_startup.dat", Path.DirectorySeparatorChar), "Name of the statistics state file including its path.");
            settings.Add("AutoSaveInterval", 10000, "Interval in milliseconds at which the file records loaded in memory are to be saved automatically to disk. Use -1 to disable automatic saving - this defaults to 10,000 for the statistics state file.");
            settings.Add("LoadOnOpen", true, "True if file records are to be loaded in memory when opened; otherwise False - this defaults to True for the statistics state file.");
            settings.Add("SaveOnClose", true, "True if file records loaded in memory are to be saved to disk when file is closed; otherwise False - this defaults to True for the statistics state file.");
            settings.Add("ReloadOnModify", false, "True if file records loaded in memory are to be re-loaded when file is modified on disk; otherwise False - this defaults to False for the statistics state file.");
            settings["AutoSaveInterval"].Update(10000);
            settings["LoadOnOpen"].Update(true);
            settings["SaveOnClose"].Update(true);
            settings["ReloadOnModify"].Update(false);

            settings = configFile.Settings["statIntercomFile"];
            settings.Add("FileName", string.Format("Statistics{0}scratch.dat", Path.DirectorySeparatorChar), "Name of the statistics intercom file including its path.");
            settings.Add("AutoSaveInterval", 10000, "Interval in milliseconds at which the file records loaded in memory are to be saved automatically to disk. Use -1 to disable automatic saving - this defaults to 10,000 for the statistics intercom file.");
            settings.Add("LoadOnOpen", true, "True if file records are to be loaded in memory when opened; otherwise False - this defaults to True for the statistics intercom file.");
            settings.Add("SaveOnClose", true, "True if file records loaded in memory are to be saved to disk when file is closed; otherwise False - this defaults to True for the statistics intercom file.");
            settings.Add("ReloadOnModify", false, "True if file records loaded in memory are to be re-loaded when file is modified on disk; otherwise False - this defaults to False for the statistics intercom file.");
            settings["AutoSaveInterval"].Update(1000);
            settings["LoadOnOpen"].Update(true);
            settings["SaveOnClose"].Update(true);
            settings["ReloadOnModify"].Update(false);

            settings = configFile.Settings["statArchiveFile"];
            settings.Add("FileName", string.Format("Statistics{0}stat_archive.d", Path.DirectorySeparatorChar), "Name of the statistics working archive file including its path.");
            settings.Add("CacheWrites", true, "True if writes are to be cached for performance; otherwise False - this defaults to True for the statistics working archive file.");
            settings.Add("ConserveMemory", false, "True if attempts are to be made to conserve memory; otherwise False - this defaults to False for the statistics working archive file.");
            settings["CacheWrites"].Update(true);
            settings["ConserveMemory"].Update(false);

            settings = configFile.Settings["statMetadataService"];
            settings.Add("Endpoints", "http.rest://localhost:6051/historian", "Semicolon delimited list of URIs where the web service can be accessed - this defaults to http.rest://localhost:6051/historian for the statistics meta-data service.");

            settings = configFile.Settings["statTimeSeriesDataService"];
            settings.Add("Endpoints", "http.rest://localhost:6052/historian", "Semicolon delimited list of URIs where the web service can be accessed - this defaults to http.rest://localhost:6052/historian for the statistics time-series data service.");

            configFile.Save();

            // Get the needed statistic related IDs
            int statHistorianID = Convert.ToInt32(database.Connection.ExecuteScalar(string.Format("SELECT ID FROM Historian WHERE Acronym='STAT' AND NodeID={0}", nodeIDQueryString)));

            // Load the defined system statistics
            IEnumerable<DataRow> statistics = database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM Statistic ORDER BY Source, SignalIndex").AsEnumerable();

            // Filter statistics to device, input stream and output stream types            
            IEnumerable<DataRow> deviceStatistics = statistics.Where(row => string.Compare(row.Field<string>("Source"), "Device", true) == 0).ToList();
            IEnumerable<DataRow> inputStreamStatistics = statistics.Where(row => string.Compare(row.Field<string>("Source"), "InputStream", true) == 0).ToList();

            // Define kinds of output signal that will designate a location in an output stream protocol frame - other non-mappable measurements will be removed from output stream measurements
            SignalKind[] validOutputSignalKinds = { SignalKind.Angle, SignalKind.Magnitude, SignalKind.Frequency, SignalKind.DfDt, SignalKind.Status, SignalKind.Analog, SignalKind.Digital, SignalKind.Quality };

            HashSet<int> measurementIDsToDelete = new HashSet<int>();
            SignalReference deviceSignalReference;
            string query, signalReference, pointTag, company, description, protocolIDs;
            int adapterID, deviceID, signalIndex;
            bool firstStatisticExisted;
            int? historianID;

            string[] trackedTables;
            ulong changes;

            try
            {
                // Determine the tables for which changes are tracked
                if (trackingVersion != ulong.MinValue)
                {
                    trackedTables = database.Connection.RetrieveData(database.AdapterType, "SELECT Name FROM TrackedTable").Select()
                        .Select(row => row["Name"].ToNonNullString())
                        .ToArray();
                }
                else
                {
                    trackedTables = new string[0];
                }
            }
            catch
            {
                trackedTables = new string[0];
            }

            statusMessage("Validating device protocols...");

            // Extract IDs for phasor protocols
            StringBuilder protocolIDList = new StringBuilder();
            DataTable protocols = database.Connection.RetrieveData(database.AdapterType, "SELECT * FROM Protocol");

            if (protocols.Columns.Contains("Category"))
            {
                // Make sure new protocol types exist
                if (Convert.ToInt32(database.Connection.ExecuteScalar(string.Format("SELECT COUNT(*) FROM Protocol WHERE Acronym='GatewayTransport'"))) == 0)
                {
                    database.Connection.ExecuteNonQuery("INSERT INTO Protocol(Acronym, Name, Type, Category, AssemblyName, TypeName, LoadOrder) VALUES('GatewayTransport', 'Gateway Transport', 'Measurement', 'Gateway', 'GSF.TimeSeries.dll', 'GSF.TimeSeries.Transport.DataSubscriber', " + (protocols.Rows.Count + 1) + ")");

                    if (Convert.ToInt32(database.Connection.ExecuteScalar(string.Format("SELECT COUNT(*) FROM Protocol WHERE Acronym='WAV'"))) == 0)
                        database.Connection.ExecuteNonQuery("INSERT INTO Protocol(Acronym, Name, Type, Category, AssemblyName, TypeName, LoadOrder) VALUES('WAV', 'Wave Form Input Adapter', 'Frame', 'Audio', 'WavInputAdapter.dll', 'WavInputAdapter.WavInputAdapter', " + (protocols.Rows.Count + 2) + ")");

                    if (Convert.ToInt32(database.Connection.ExecuteScalar(string.Format("SELECT COUNT(*) FROM Protocol WHERE Acronym='IeeeC37_118V2'"))) == 0)
                        database.Connection.ExecuteNonQuery("INSERT INTO Protocol(Acronym, Name, Type, Category, AssemblyName, TypeName, LoadOrder) VALUES('IeeeC37_118V2', 'IEEE C37.118.2-2011', 'Frame', 'Phasor', 'PhasorProtocolAdapters.dll', 'PhasorProtocolAdapters.PhasorMeasurementMapper', 2)");

                    if (Convert.ToInt32(database.Connection.ExecuteScalar(string.Format("SELECT COUNT(*) FROM Protocol WHERE Acronym='VirtualInput'"))) == 0)
                        database.Connection.ExecuteNonQuery("INSERT INTO Protocol(Acronym, Name, Type, Category, AssemblyName, TypeName, LoadOrder) VALUES('VirtualInput', 'Virtual Device', 'Frame', 'Virtual', 'TestingAdapters.dll', 'TestingAdapters.VirtualInputAdapter', " + (protocols.Rows.Count + 4) + ")");
                }

                if (Convert.ToInt32(database.Connection.ExecuteScalar(string.Format("SELECT COUNT(*) FROM Protocol WHERE Acronym='Iec61850_90_5'"))) == 0)
                    database.Connection.ExecuteNonQuery("INSERT INTO Protocol(Acronym, Name, Type, Category, AssemblyName, TypeName, LoadOrder) VALUES('Iec61850_90_5', 'IEC 61850-90-5', 'Frame', 'Phasor', 'PhasorProtocolAdapters.dll', 'PhasorProtocolAdapters.PhasorMeasurementMapper', 12)");

                foreach (DataRow protocol in protocols.Rows)
                {
                    if (string.Compare(protocol.Field<string>("Category"), "Phasor", true) == 0)
                    {
                        if (protocolIDList.Length > 0)
                            protocolIDList.Append(", ");

                        protocolIDList.Append(protocol.ConvertField<int>("ID"));
                    }
                }
            }
            else
            {
                // Older schemas do not include protocol categories and assembly info
                foreach (DataRow protocol in protocols.Rows)
                {
                    if (protocolIDList.Length > 0)
                        protocolIDList.Append(", ");

                    protocolIDList.Append(protocol.ConvertField<int>("ID"));
                }
            }

            protocolIDs = protocolIDList.ToString();

            try
            {
                // Determine how many changes were made to devices and measurements -
                // if no changes were made, we can skip the next few steps
                if (trackedTables.Contains("Device") && trackedTables.Contains("Measurement"))
                    changes = Convert.ToUInt64(database.Connection.ExecuteScalar(string.Format("SELECT COUNT(*) FROM TrackedChange WHERE (TableName = 'Device' OR TableName = 'Measurement') AND ID > {0}", trackingVersion)));
                else
                    changes = ulong.MaxValue;
            }
            catch
            {
                changes = ulong.MaxValue;
            }

            if (skipOptimization || changes != 0L)
            {
                statusMessage("Validating device measurements...");

                // Get protocol ID list for those protocols that support time quality flags
                DataTable timeQualityProtocols = database.Connection.RetrieveData(database.AdapterType, "SELECT ID FROM Protocol WHERE Acronym = 'IeeeC37_118V1' OR Acronym = 'IeeeC37_118V2' OR Acronym = 'IeeeC37_118D6' OR Acronym = 'Iec61850_90_5'");
                StringBuilder timeQualityProtocolIDList = new StringBuilder();
                string timeQualityProtocolIDs;

                foreach (DataRow timeQualityProtocol in timeQualityProtocols.Rows)
                {
                    if (timeQualityProtocolIDList.Length > 0)
                        timeQualityProtocolIDList.Append(", ");

                    timeQualityProtocolIDList.Append(timeQualityProtocol.ConvertField<int>("ID"));
                }

                timeQualityProtocolIDs = timeQualityProtocolIDList.ToString();

                int qualityFlagsSignalTypeID = Convert.ToInt32(database.Connection.ExecuteScalar("SELECT ID FROM SignalType WHERE Acronym='QUAL'"));

                // Make sure one device quality flags measurement exists for each "connection" for devices that support time quality flags
                foreach (DataRow device in database.Connection.RetrieveData(database.AdapterType, string.Format("SELECT * FROM Device WHERE ((IsConcentrator = 0 AND ParentID IS NULL) OR IsConcentrator = 1) AND NodeID = {0} AND ProtocolID IN ({1})", nodeIDQueryString, timeQualityProtocolIDs)).Rows)
                {
                    deviceID = device.ConvertField<int>("ID");
                    acronym = device.Field<string>("Acronym");
                    signalReference = SignalReference.ToString(acronym, SignalKind.Quality);

                    // See if quality flags measurement exists for device
                    if (Convert.ToInt32(database.Connection.ExecuteScalar(string.Format("SELECT COUNT(*) FROM Measurement WHERE SignalReference = '{0}' AND DeviceID = {1}", signalReference, deviceID))) == 0)
                    {
                        historianID = device.ConvertNullableField<int>("HistorianID");

                        company = (string)database.Connection.ExecuteScalar(string.Format("SELECT MapAcronym FROM Company WHERE ID = {0}", device.ConvertNullableField<int>("CompanyID") ?? 0));

                        if (string.IsNullOrEmpty(company))
                            company = configFile.Settings["systemSettings"]["CompanyAcronym"].Value.TruncateRight(3);

                        pointTag = CreatePointTag(company, acronym, null, "QUAL");
                        description = string.Format("{0} Time Quality Flags", device.Field<string>("Name"));

                        query = database.ParameterizedQueryString("INSERT INTO Measurement(HistorianID, DeviceID, PointTag, SignalTypeID, PhasorSourceIndex, " +
                                                                  "SignalReference, Description, Enabled) VALUES({0}, {1}, {2}, {3}, NULL, {4}, {5}, 1)", "historianID", "deviceID", "pointTag",
                            "signalTypeID", "signalReference", "description");

                        database.Connection.ExecuteNonQuery(query, DataExtensions.DefaultTimeoutDuration, historianID.HasValue ? (object)historianID.Value : (object)DBNull.Value, deviceID, pointTag, qualityFlagsSignalTypeID, signalReference, description);
                    }
                }

                // Make sure needed device statistic measurements exist, currently statistics are only associated with phasor devices so we filter based on protocol
                foreach (DataRow device in database.Connection.RetrieveData(database.AdapterType, string.Format("SELECT * FROM Device WHERE IsConcentrator = 0 AND NodeID = {0} AND ProtocolID IN ({1})", nodeIDQueryString, protocolIDs)).Rows)
                {
                    foreach (DataRow statistic in deviceStatistics)
                    {
                        string oldAcronym;
                        string oldSignalReference;

                        signalIndex = statistic.ConvertField<int>("SignalIndex");
                        oldAcronym = device.Field<string>("Acronym");
                        acronym = oldAcronym + "!PMU";
                        oldSignalReference = SignalReference.ToString(oldAcronym, SignalKind.Statistic, signalIndex);
                        signalReference = SignalReference.ToString(acronym, SignalKind.Statistic, signalIndex);

                        // If the original format for device statistics is found in the database, update to new format
                        if (Convert.ToInt32(database.Connection.ExecuteScalar(string.Format("SELECT COUNT(*) FROM Measurement WHERE SignalReference='{0}' AND HistorianID={1}", oldSignalReference, statHistorianID))) > 0)
                            database.Connection.ExecuteNonQuery(string.Format("UPDATE Measurement SET SignalReference='{0}' WHERE SignalReference='{1}' AND HistorianID={2}", signalReference, oldSignalReference, statHistorianID));
                        else if (!skipOptimization)
                            break;
                    }
                }

                statusMessage("Validating input stream measurements...");

                // Make sure devices associated with a concentrator do not have any extraneous input stream statistic measurements - this can happen
                // when a device was once a direct connect device but now is part of a concentrator...
                foreach (DataRow inputStream in database.Connection.RetrieveData(database.AdapterType, string.Format("SELECT * FROM Device WHERE (IsConcentrator = 0 AND ParentID IS NOT NULL) AND NodeID = {0} AND ProtocolID IN ({1})", nodeIDQueryString, protocolIDs)).Rows)
                {
                    firstStatisticExisted = false;

                    foreach (DataRow statistic in inputStreamStatistics)
                    {
                        acronym = inputStream.Field<string>("Acronym") + "!IS";
                        signalIndex = statistic.ConvertField<int>("SignalIndex");
                        signalReference = SignalReference.ToString(acronym, SignalKind.Statistic, signalIndex);

                        // To reduce time required to execute these steps, only first statistic is verified to exist
                        if (!skipOptimization && !firstStatisticExisted)
                        {
                            firstStatisticExisted = (Convert.ToInt32(database.Connection.ExecuteScalar(string.Format("SELECT COUNT(*) FROM Measurement WHERE SignalReference='{0}'", signalReference))) > 0);

                            // If the first extraneous input statistic doesn't exist, we assume no others do as well
                            if (!firstStatisticExisted)
                                break;
                        }

                        // Remove extraneous input statistics
                        database.Connection.ExecuteNonQuery(string.Format("DELETE FROM Measurement WHERE SignalReference = '{0}'", signalReference));
                    }
                }
            }

            try
            {
                // Determine how many changes were made to output streams, devices, and measurements -
                // if no changes were made, we can skip the next few steps
                if (trackedTables.Contains("OutputStream") && trackedTables.Contains("OutputStreamDevice") && trackedTables.Contains("OutputStreamMeasurement") && trackedTables.Contains("Measurement"))
                    changes = Convert.ToUInt64(database.Connection.ExecuteScalar(string.Format("SELECT COUNT(*) FROM TrackedChange WHERE (TableName = 'OutputStream' OR TableName = 'OutputStreamDevice' OR TableName = 'OutputStreamMeasurement' OR TableName = 'Measurement') AND ID > {0}", trackingVersion)));
                else
                    changes = ulong.MaxValue;
            }
            catch
            {
                changes = ulong.MaxValue;
            }

            if (skipOptimization || changes != 0L)
            {
                statusMessage("Validating output stream measurements...");

                // Make sure needed output stream statistic measurements exist
                foreach (DataRow outputStream in database.Connection.RetrieveData(database.AdapterType, string.Format("SELECT * FROM OutputStream WHERE NodeID = {0}", nodeIDQueryString)).Rows)
                {
                    adapterID = outputStream.ConvertField<int>("ID");

                    // Load devices acronyms associated with this output stream
                    List<string> deviceAcronyms =
                        database.Connection.RetrieveData(database.AdapterType,
                            string.Format("SELECT Acronym FROM OutputStreamDevice WHERE AdapterID = {0} AND NodeID = {1}", adapterID, nodeIDQueryString))
                            .AsEnumerable()
                            .Select(row => row.Field<string>("Acronym"))
                            .ToList();

                    // Since measurements can be added to the output stream device itself (e.g., quality flags) - we add it as a valid mapping destination as well
                    deviceAcronyms.Add(outputStream.Field<string>("Acronym"));

                    // Sort list so binary search can be used to speed lookups
                    deviceAcronyms.Sort(StringComparer.OrdinalIgnoreCase);

                    // Validate measurements associated with this output stream
                    foreach (DataRow outputStreamMeasurement in database.Connection.RetrieveData(database.AdapterType, string.Format("SELECT * FROM OutputStreamMeasurement WHERE AdapterID = {0} AND NodeID = {1}", adapterID, nodeIDQueryString)).Rows)
                    {
                        // Parse output stream measurement signal reference
                        deviceSignalReference = new SignalReference(outputStreamMeasurement.Field<string>("SignalReference"));

                        // Validate that the signal reference is associated with one of the output stream's devices
                        if (deviceAcronyms.BinarySearch(deviceSignalReference.Acronym, StringComparer.OrdinalIgnoreCase) < 0)
                        {
                            // This measurement has a signal reference for a device that is not part of the associated output stream, so we mark it for deletion
                            measurementIDsToDelete.Add(outputStreamMeasurement.ConvertField<int>("ID"));
                        }

                        // Validate that the signal reference type is valid for an output stream
                        if (!validOutputSignalKinds.Any(validSignalKind => deviceSignalReference.Kind == validSignalKind))
                        {
                            // This measurement has a signal reference type that is not valid for an output stream, so we mark it for deletion
                            measurementIDsToDelete.Add(outputStreamMeasurement.ConvertField<int>("ID"));
                        }
                    }
                }
            }

            if (measurementIDsToDelete.Count > 0)
            {
                statusMessage(string.Format("Removing {0} unused output stream device measurements...", measurementIDsToDelete.Count));

                foreach (int measurementID in measurementIDsToDelete)
                {
                    database.Connection.ExecuteNonQuery(string.Format("DELETE FROM OutputStreamMeasurement WHERE ID = {0} AND NodeID = {1}", measurementID, nodeIDQueryString));
                }
            }

            if (renameAllPointTags)
            {
                statusMessage("Renaming all point tags...");

                string device, vendor, signalAcronym;
                char? phase;
                int? vendorDeviceID;
                SignalReference signal;

                foreach (DataRow measurement in database.Connection.RetrieveData(database.AdapterType, "SELECT SignalID, CompanyAcronym, DeviceAcronym, VendorDeviceID, SignalReference, SignalAcronym, Phase FROM MeasurementDetail WHERE SignalAcronym <> 'STAT' AND Internal <> 0 AND Subscribed = 0").Rows)
                {
                    company = measurement.ConvertField<string>("CompanyAcronym");

                    if (string.IsNullOrEmpty(company))
                        company = configFile.Settings["systemSettings"]["CompanyAcronym"].Value.TruncateRight(3);

                    device = measurement.ConvertField<string>("DeviceAcronym");

                    if ((object)device != null)
                    {
                        vendorDeviceID = measurement.ConvertNullableField<int>("VendorDeviceID");

                        if (vendorDeviceID.HasValue)
                            vendor = (string)database.Connection.ExecuteScalar("SELECT Acronym FROM Vendor WHERE ID = " + vendorDeviceID.Value);
                        else
                            vendor = null;

                        signalAcronym = measurement.ConvertField<string>("SignalAcronym");

                        try
                        {
                            signal = new SignalReference(measurement.ConvertField<string>("SignalReference"));
                            signalIndex = signal.Index;

                            if (signalIndex <= 0)
                                signalIndex = -1;
                        }
                        catch
                        {
                            signalIndex = -1;
                        }

                        phase = measurement.ConvertNullableField<char>("Phase");

                        database.Connection.ExecuteNonQuery(string.Format("UPDATE Measurement SET PointTag = '{0}' WHERE SignalID = '{1}'", CreatePointTag(company, device, vendor, signalAcronym, signalIndex, phase ?? '_'), database.Guid(measurement, "SignalID")));
                    }
                }
            }

            if (skipOptimization || renameAllPointTags)
            {
                // If skipOptimization is set to true, automatically set it back to false
                const string clearParametersQuery =
                    "UPDATE DataOperation SET Arguments = '' " +
                    "WHERE AssemblyName = 'PhasorProtocolAdapters.dll' " +
                    "AND TypeName = 'PhasorProtocolAdapters.CommonPhasorServices' " +
                    "AND MethodName = 'PhasorDataSourceValidation'";

                database.Connection.ExecuteNonQuery(clearParametersQuery);
            }
        }
コード例 #46
0
ファイル: Subscriber.cs プロジェクト: avs009/gsf
        /// <summary>
        /// Removed measurement groups from <see cref="Subscriber"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="subscriberID">ID of the <see cref="Subscriber"/> to which measurement groups to be removed.</param>
        /// <param name="measurementGroupsToBeRemoved">List of <see cref="MeasurementGroup"/> IDs to be removed.</param>
        /// <returns>string, indicating success for UI display.</returns>
        public static string RemoveMeasurementGroups(AdoDataConnection database, Guid subscriberID, List<int> measurementGroupsToBeRemoved)
        {
            bool createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);

                foreach (int id in measurementGroupsToBeRemoved)
                {
                    query = database.ParameterizedQueryString("DELETE FROM SubscriberMeasurementGroup WHERE SubscriberID = {0} AND MeasurementGroupID = {1}", "subscriberID", "measurementGroupID");
                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(subscriberID), id);
                }

                return "Measurement groups removed from allowed measurement groups list for subscriber successfully";
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #47
0
ファイル: OutputStream.cs プロジェクト: avs009/gsf
        /// <summary>
        /// Loads <see cref="OutputStream"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="keys">Keys of the measuremnets to be loaded from the database</param>
        /// <returns>Collection of <see cref="OutputStream"/>.</returns>
        public static ObservableCollection<OutputStream> Load(AdoDataConnection database, IList<int> keys)
        {
            bool createdConnection = false;
            try
            {
                createdConnection = CreateConnection(ref database);

                ObservableCollection<OutputStream> outputStreamList = new ObservableCollection<OutputStream>();
                DataTable outputStreamTable;
                string query;
                string commaSeparatedKeys;

                if ((object)keys != null && keys.Count > 0)
                {
                    commaSeparatedKeys = keys.Select(key => "" + key.ToString() + "").Aggregate((str1, str2) => str1 + "," + str2);
                    query = string.Format("SELECT * FROM OutputStreamDetail WHERE ID IN ({0})", commaSeparatedKeys);
                    outputStreamTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout);

                    outputStreamList = new ObservableCollection<OutputStream>(from item in outputStreamTable.AsEnumerable()
                                                                              let id = item.ConvertField<int>("ID")
                                                                              let type = item.ConvertField<int>("Type") + 1
                                                                              orderby keys.IndexOf(id)
                                                                              select new OutputStream
                                                                              {
                                                                                  NodeID = database.Guid(item, "NodeID"),
                                                                                  ID = id,
                                                                                  Acronym = item.Field<string>("Acronym"),
                                                                                  Name = item.Field<string>("Name"),
                                                                                  Type = type,
                                                                                  ConnectionString = item.Field<string>("ConnectionString"),
                                                                                  IDCode = item.ConvertField<int>("IDCode"),
                                                                                  CommandChannel = item.Field<string>("CommandChannel"),
                                                                                  DataChannel = item.Field<string>("DataChannel"),
                                                                                  AutoPublishConfigFrame = Convert.ToBoolean(item.Field<object>("AutoPublishConfigFrame")),
                                                                                  AutoStartDataChannel = Convert.ToBoolean(item.Field<object>("AutoStartDataChannel")),
                                                                                  NominalFrequency = item.ConvertField<int>("NominalFrequency"),
                                                                                  FramesPerSecond = item.ConvertNullableField<int>("FramesPerSecond") ?? 30,
                                                                                  LagTime = item.ConvertField<double>("LagTime"),
                                                                                  LeadTime = item.ConvertField<double>("LeadTime"),
                                                                                  UseLocalClockAsRealTime = Convert.ToBoolean(item.Field<object>("UseLocalClockAsRealTime")),
                                                                                  AllowSortsByArrival = Convert.ToBoolean(item.Field<object>("AllowSortsByArrival")),
                                                                                  LoadOrder = item.ConvertField<int>("LoadOrder"),
                                                                                  Enabled = Convert.ToBoolean(item.Field<object>("Enabled")),
                                                                                  m_nodeName = item.Field<string>("NodeName"),
                                                                                  m_typeName = (type == 1) ? "IEEE C37.118" : (type == 2) ? "BPA" : "IEC 61850-90-5",
                                                                                  IgnoreBadTimeStamps = Convert.ToBoolean(item.Field<object>("IgnoreBadTimeStamps")),
                                                                                  TimeResolution = item.ConvertField<int>("TimeResolution"),
                                                                                  AllowPreemptivePublishing = Convert.ToBoolean(item.Field<object>("AllowPreemptivePublishing")),
                                                                                  DownSamplingMethod = item.Field<string>("DownsamplingMethod"),
                                                                                  DataFormat = item.Field<string>("DataFormat"),
                                                                                  CoordinateFormat = item.Field<string>("CoordinateFormat"),
                                                                                  CurrentScalingValue = item.ConvertField<int>("CurrentScalingValue"),
                                                                                  VoltageScalingValue = item.ConvertField<int>("VoltageScalingValue"),
                                                                                  AnalogScalingValue = item.ConvertField<int>("AnalogScalingValue"),
                                                                                  DigitalMaskValue = item.ConvertField<int>("DigitalMaskValue"),
                                                                                  PerformTimestampReasonabilityCheck = Convert.ToBoolean(item.Field<object>("PerformTimeReasonabilityCheck")),
                                                                                  m_mirroringSourceDevice = GetMirroringSource(database, id)
                                                                              });
                    return outputStreamList;

                }
                return outputStreamList;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #48
0
ファイル: DataSubscriber.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Handles meta-data synchronization to local system.
        /// </summary>
        /// <remarks>
        /// This function should only be initiated from call to <see cref="SynchronizeMetadata(DataSet)"/> to make
        /// sure only one meta-data synchronization happens at once. Users can override this method to customize
        /// process of meta-data synchronization.
        /// </remarks>
        protected virtual void SynchronizeMetadata()
        {
            bool dataMonitoringEnabled = false;

            // TODO: This function is complex and very closely tied to the current time-series data schema - perhaps it should be moved outside this class and referenced
            // TODO: as a delegate that can be assigned and called to allow other schemas as well. DataPublisher is already very flexible in what data it can deliver.
            try
            {
                DataSet metadata = m_receivedMetadata;

                // Only perform database synchronization if meta-data has changed since last update
                if (!SynchronizedMetadataChanged(metadata))
                    return;

                if ((object)metadata == null)
                {
                    OnStatusMessage("WARNING: Meta-data synchronization was not performed, deserialized dataset was empty.");
                    return;
                }

                // Reset data stream monitor while meta-data synchronization is in progress
                if ((object)m_dataStreamMonitor != null && m_dataStreamMonitor.Enabled)
                {
                    m_dataStreamMonitor.Enabled = false;
                    dataMonitoringEnabled = true;
                }

                // Track total meta-data synchronization process time
                Ticks startTime = DateTime.UtcNow.Ticks;
                DateTime updateTime;
                DateTime latestUpdateTime = DateTime.MinValue;

                // Open the configuration database using settings found in the config file
                using (AdoDataConnection database = new AdoDataConnection("systemSettings"))
                using (IDbCommand command = database.Connection.CreateCommand())
                {
                    IDbTransaction transaction = null;

                    if (m_useTransactionForMetadata)
                        transaction = database.Connection.BeginTransaction(database.DefaultIsloationLevel);

                    try
                    {
                        if ((object)transaction != null)
                            command.Transaction = transaction;

                        // Query the actual record ID based on the known run-time ID for this subscriber device
                        int parentID = Convert.ToInt32(command.ExecuteScalar($"SELECT SourceID FROM Runtime WHERE ID = {ID} AND SourceTable='Device'", m_metadataSynchronizationTimeout));

                        // Validate that the subscriber device is marked as a concentrator (we are about to associate children devices with it)
                        if (!command.ExecuteScalar($"SELECT IsConcentrator FROM Device WHERE ID = {parentID}", m_metadataSynchronizationTimeout).ToString().ParseBoolean())
                            command.ExecuteNonQuery($"UPDATE Device SET IsConcentrator = 1 WHERE ID = {parentID}", m_metadataSynchronizationTimeout);

                        // Get any historian associated with the subscriber device
                        object historianID = command.ExecuteScalar($"SELECT HistorianID FROM Device WHERE ID = {parentID}", m_metadataSynchronizationTimeout);

                        // Determine the active node ID - we cache this since this value won't change for the lifetime of this class
                        if (m_nodeID == Guid.Empty)
                            m_nodeID = Guid.Parse(command.ExecuteScalar($"SELECT NodeID FROM IaonInputAdapter WHERE ID = {(int)ID}", m_metadataSynchronizationTimeout).ToString());

                        // Determine the protocol record auto-inc ID value for the gateway transport protocol (GEP) - this value is also cached since it shouldn't change for the lifetime of this class
                        if (m_gatewayProtocolID == 0)
                            m_gatewayProtocolID = int.Parse(command.ExecuteScalar("SELECT ID FROM Protocol WHERE Acronym='GatewayTransport'", m_metadataSynchronizationTimeout).ToString());

                        // Ascertain total number of actions required for all meta-data synchronization so some level feed back can be provided on progress
                        InitSyncProgress(metadata.Tables.Cast<DataTable>().Select(dataTable => (long)dataTable.Rows.Count).Sum() + 3);

                        // Prefix all children devices with the name of the parent since the same device names could appear in different connections (helps keep device names unique)
                        string sourcePrefix = Name + "!";
                        Dictionary<string, int> deviceIDs = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
                        string deviceAcronym, signalTypeAcronym;
                        decimal longitude, latitude;
                        decimal? location;
                        object originalSource;
                        int deviceID;

                        // Check to see if data for the "DeviceDetail" table was included in the meta-data
                        if (metadata.Tables.Contains("DeviceDetail"))
                        {
                            DataTable deviceDetail = metadata.Tables["DeviceDetail"];
                            List<Guid> uniqueIDs = new List<Guid>();
                            DataRow[] deviceRows;

                            // Define SQL statement to query if this device is already defined (this should always be based on the unique guid-based device ID)
                            string deviceExistsSql = database.ParameterizedQueryString("SELECT COUNT(*) FROM Device WHERE UniqueID = {0}", "uniqueID");

                            // Define SQL statement to insert new device record
                            string insertDeviceSql = database.ParameterizedQueryString("INSERT INTO Device(NodeID, ParentID, HistorianID, Acronym, Name, ProtocolID, FramesPerSecond, OriginalSource, AccessID, Longitude, Latitude, ContactList, IsConcentrator, Enabled) " +
                                                                                       "VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}, {11}, 0, 1)", "nodeID", "parentID", "historianID", "acronym", "name", "protocolID", "framesPerSecond", "originalSource", "accessID", "longitude", "latitude", "contactList");

                            // Define SQL statement to update device's guid-based unique ID after insert
                            string updateDeviceUniqueIDSql = database.ParameterizedQueryString("UPDATE Device SET UniqueID = {0} WHERE Acronym = {1}", "uniqueID", "acronym");

                            // Define SQL statement to query if a device can be safely updated
                            string deviceIsUpdatableSql = database.ParameterizedQueryString("SELECT COUNT(*) FROM Device WHERE UniqueID = {0} AND (ParentID <> {1} OR ParentID IS NULL)", "uniqueID", "parentID");

                            // Define SQL statement to update existing device record
                            string updateDeviceSql = database.ParameterizedQueryString("UPDATE Device SET Acronym = {0}, Name = {1}, OriginalSource = {2}, ProtocolID = {3}, FramesPerSecond = {4}, HistorianID = {5}, AccessID = {6}, Longitude = {7}, Latitude = {8}, ContactList = {9} WHERE UniqueID = {10}",
                                                                                       "acronym", "name", "originalSource", "protocolID", "framesPerSecond", "historianID", "accessID", "longitude", "latitude", "contactList", "uniqueID");

                            // Define SQL statement to retrieve device's auto-inc ID based on its unique guid-based ID
                            string queryDeviceIDSql = database.ParameterizedQueryString("SELECT ID FROM Device WHERE UniqueID = {0}", "uniqueID");

                            // Define SQL statement to retrieve all unique device ID's for the current parent to check for mismatches
                            string queryUniqueDeviceIDsSql = database.ParameterizedQueryString("SELECT UniqueID FROM Device WHERE ParentID = {0}", "parentID");

                            // Define SQL statement to remove device records that no longer exist in the meta-data
                            string deleteDeviceSql = database.ParameterizedQueryString("DELETE FROM Device WHERE UniqueID = {0}", "uniqueID");

                            // Determine which device rows should be synchronized based on operational mode flags
                            if (ReceiveInternalMetadata && ReceiveExternalMetadata)
                                deviceRows = deviceDetail.Select();
                            else if (ReceiveInternalMetadata)
                                deviceRows = deviceDetail.Select("OriginalSource IS NULL");
                            else if (ReceiveExternalMetadata)
                                deviceRows = deviceDetail.Select("OriginalSource IS NOT NULL");
                            else
                                deviceRows = new DataRow[0];

                            // Check existence of optional meta-data fields
                            DataColumnCollection deviceDetailColumns = deviceDetail.Columns;
                            bool accessIDFieldExists = deviceDetailColumns.Contains("AccessID");
                            bool longitudeFieldExists = deviceDetailColumns.Contains("Longitude");
                            bool latitudeFieldExists = deviceDetailColumns.Contains("Latitude");
                            bool companyAcronymFieldExists = deviceDetailColumns.Contains("CompanyAcronym");
                            bool protocolNameFieldExists = deviceDetailColumns.Contains("ProtocolName");
                            bool vendorAcronymFieldExists = deviceDetailColumns.Contains("VendorAcronym");
                            bool vendorDeviceNameFieldExists = deviceDetailColumns.Contains("VendorDeviceName");
                            bool interconnectionNameFieldExists = deviceDetailColumns.Contains("InterconnectionName");
                            bool updatedOnFieldExists = deviceDetailColumns.Contains("UpdatedOn");

                            // Older versions of GEP did not include the AccessID field, so this is treated as optional
                            int accessID = 0;

                            foreach (DataRow row in deviceRows)
                            {
                                Guid uniqueID = Guid.Parse(row.Field<object>("UniqueID").ToString());
                                bool recordNeedsUpdating;

                                // Track unique device Guids in this meta-data session, we'll need to remove any old associated devices that no longer exist
                                uniqueIDs.Add(uniqueID);

                                // Determine if record has changed since last synchronization
                                if (updatedOnFieldExists)
                                {
                                    try
                                    {
                                        updateTime = Convert.ToDateTime(row["UpdatedOn"]);
                                        recordNeedsUpdating = updateTime > m_lastMetaDataRefreshTime;

                                        if (updateTime > latestUpdateTime)
                                            latestUpdateTime = updateTime;
                                    }
                                    catch
                                    {
                                        recordNeedsUpdating = true;
                                    }
                                }
                                else
                                {
                                    recordNeedsUpdating = true;
                                }

                                // We will synchronize meta-data only if the source owns this device and it's not defined as a concentrator (these should normally be filtered by publisher - but we check just in case).
                                if (!row["IsConcentrator"].ToNonNullString("0").ParseBoolean())
                                {
                                    if (accessIDFieldExists)
                                        accessID = row.ConvertField<int>("AccessID");

                                    // Get longitude and latitude values if they are defined
                                    longitude = 0M;
                                    latitude = 0M;

                                    if (longitudeFieldExists)
                                    {
                                        location = row.ConvertNullableField<decimal>("Longitude");

                                        if (location.HasValue)
                                            longitude = location.Value;
                                    }

                                    if (latitudeFieldExists)
                                    {
                                        location = row.ConvertNullableField<decimal>("Latitude");

                                        if (location.HasValue)
                                            latitude = location.Value;
                                    }

                                    // Save any reported extraneous values from device meta-data in connection string formatted contact list - all fields are considered optional
                                    Dictionary<string, string> contactList = new Dictionary<string, string>();

                                    if (companyAcronymFieldExists)
                                        contactList["companyAcronym"] = row.Field<string>("CompanyAcronym") ?? string.Empty;

                                    if (protocolNameFieldExists)
                                        contactList["protocolName"] = row.Field<string>("ProtocolName") ?? string.Empty;

                                    if (vendorAcronymFieldExists)
                                        contactList["vendorAcronym"] = row.Field<string>("VendorAcronym") ?? string.Empty;

                                    if (vendorDeviceNameFieldExists)
                                        contactList["vendorDeviceName"] = row.Field<string>("VendorDeviceName") ?? string.Empty;

                                    if (interconnectionNameFieldExists)
                                        contactList["interconnectionName"] = row.Field<string>("InterconnectionName") ?? string.Empty;

                                    // Determine if device record already exists
                                    if (Convert.ToInt32(command.ExecuteScalar(deviceExistsSql, m_metadataSynchronizationTimeout, database.Guid(uniqueID))) == 0)
                                    {
                                        // Insert new device record
                                        command.ExecuteNonQuery(insertDeviceSql, m_metadataSynchronizationTimeout, database.Guid(m_nodeID), parentID, historianID, sourcePrefix + row.Field<string>("Acronym"), row.Field<string>("Name"), m_gatewayProtocolID, row.ConvertField<int>("FramesPerSecond"),
                                                                m_internal ? (object)DBNull.Value : string.IsNullOrEmpty(row.Field<string>("ParentAcronym")) ? sourcePrefix + row.Field<string>("Acronym") : sourcePrefix + row.Field<string>("ParentAcronym"), accessID, longitude, latitude, contactList.JoinKeyValuePairs());

                                        // Guids are normally auto-generated during insert - after insertion update the Guid so that it matches the source data. Most of the database
                                        // scripts have triggers that support properly assigning the Guid during an insert, but this code ensures the Guid will always get assigned.
                                        command.ExecuteNonQuery(updateDeviceUniqueIDSql, m_metadataSynchronizationTimeout, database.Guid(uniqueID), sourcePrefix + row.Field<string>("Acronym"));
                                    }
                                    else if (recordNeedsUpdating)
                                    {
                                        // Perform safety check to preserve device records which are not safe to overwrite
                                        if (Convert.ToInt32(command.ExecuteScalar(deviceIsUpdatableSql, m_metadataSynchronizationTimeout, database.Guid(uniqueID), parentID)) > 0)
                                            continue;

                                        // Gateway is assuming ownership of the device records when the "internal" flag is true - this means the device's measurements can be forwarded to another party. From a device record perspective,
                                        // ownership is inferred by setting 'OriginalSource' to null. When gateway doesn't own device records (i.e., the "internal" flag is false), this means the device's measurements can only be consumed
                                        // locally - from a device record perspective this means the 'OriginalSource' field is set to the acronym of the PDC or PMU that generated the source measurements. This field allows a mirrored source
                                        // restriction to be implemented later to ensure all devices in an output protocol came from the same original source connection, if desired.
                                        originalSource = m_internal ? (object)DBNull.Value : string.IsNullOrEmpty(row.Field<string>("ParentAcronym")) ? sourcePrefix + row.Field<string>("Acronym") : sourcePrefix + row.Field<string>("ParentAcronym");

                                        // Update existing device record
                                        command.ExecuteNonQuery(updateDeviceSql, m_metadataSynchronizationTimeout, sourcePrefix + row.Field<string>("Acronym"), row.Field<string>("Name"), originalSource, m_gatewayProtocolID, row.ConvertField<int>("FramesPerSecond"), historianID, accessID, longitude, latitude, contactList.JoinKeyValuePairs(), database.Guid(uniqueID));
                                    }
                                }

                                // Capture local device ID auto-inc value for measurement association
                                deviceIDs[row.Field<string>("Acronym")] = Convert.ToInt32(command.ExecuteScalar(queryDeviceIDSql, m_metadataSynchronizationTimeout, database.Guid(uniqueID)));

                                // Periodically notify user about synchronization progress
                                UpdateSyncProgress();
                            }

                            // Remove any device records associated with this subscriber that no longer exist in the meta-data
                            if (uniqueIDs.Count > 0)
                            {
                                // Sort unique ID list so that binary search can be used for quick lookups
                                uniqueIDs.Sort();

                                DataTable deviceUniqueIDs = command.RetrieveData(database.AdapterType, queryUniqueDeviceIDsSql, m_metadataSynchronizationTimeout, parentID);
                                Guid uniqueID;

                                foreach (DataRow deviceRow in deviceUniqueIDs.Rows)
                                {
                                    uniqueID = database.Guid(deviceRow, "UniqueID");

                                    // Remove any devices in the database that are associated with the parent device and do not exist in the meta-data
                                    if (uniqueIDs.BinarySearch(uniqueID) < 0)
                                        command.ExecuteNonQuery(deleteDeviceSql, m_metadataSynchronizationTimeout, database.Guid(uniqueID));
                                }
                                UpdateSyncProgress();
                            }
                        }

                        // Check to see if data for the "MeasurementDetail" table was included in the meta-data
                        if (metadata.Tables.Contains("MeasurementDetail"))
                        {
                            DataTable measurementDetail = metadata.Tables["MeasurementDetail"];
                            List<Guid> signalIDs = new List<Guid>();
                            DataRow[] measurementRows;

                            // Define SQL statement to query if this measurement is already defined (this should always be based on the unique signal ID Guid)
                            string measurementExistsSql = database.ParameterizedQueryString("SELECT COUNT(*) FROM Measurement WHERE SignalID = {0}", "signalID");

                            // Define SQL statement to insert new measurement record
                            string insertMeasurementSql = database.ParameterizedQueryString("INSERT INTO Measurement(DeviceID, HistorianID, PointTag, AlternateTag, SignalTypeID, PhasorSourceIndex, SignalReference, Description, Internal, Subscribed, Enabled) " +
                                                                                            "VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, 0, 1)", "deviceID", "historianID", "pointTag", "alternateTag", "signalTypeID", "phasorSourceIndex", "signalReference", "description", "internal");

                            // Define SQL statement to update measurement's signal ID after insert
                            string updateMeasurementSignalIDSql = database.ParameterizedQueryString("UPDATE Measurement SET SignalID = {0}, AlternateTag = NULL WHERE AlternateTag = {1}", "signalID", "alternateTag");

                            // Define SQL statement to update existing measurement record
                            string updateMeasurementSql = database.ParameterizedQueryString("UPDATE Measurement SET HistorianID = {0}, PointTag = {1}, SignalTypeID = {2}, PhasorSourceIndex = {3}, SignalReference = {4}, Description = {5}, Internal = {6} WHERE SignalID = {7}",
                                                                                            "historianID", "pointTag", "signalTypeID", "phasorSourceIndex", "signalReference", "description", "internal", "signalID");

                            // Define SQL statement to retrieve all measurement signal ID's for the current parent to check for mismatches - note that we use the ActiveMeasurements view
                            // since it associates measurements with their top-most parent runtime device ID, this allows us to easily query all measurements for the parent device
                            string queryMeasurementSignalIDsSql = database.ParameterizedQueryString("SELECT SignalID FROM ActiveMeasurement WHERE DeviceID = {0}", "deviceID");

                            // Define SQL statement to retrieve measurement's associated device ID, i.e., actual record ID, based on measurement's signal ID
                            string queryMeasurementDeviceIDSql = database.ParameterizedQueryString("SELECT DeviceID FROM Measurement WHERE SignalID = {0}", "signalID");

                            // Define SQL statement to remove device records that no longer exist in the meta-data
                            string deleteMeasurementSql = database.ParameterizedQueryString("DELETE FROM Measurement WHERE SignalID = {0}", "signalID");

                            // Load signal type ID's from local database associated with their acronym for proper signal type translation
                            Dictionary<string, int> signalTypeIDs = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

                            foreach (DataRow row in command.RetrieveData(database.AdapterType, "SELECT ID, Acronym FROM SignalType").Rows)
                            {
                                signalTypeAcronym = row.Field<string>("Acronym");

                                if (!string.IsNullOrWhiteSpace(signalTypeAcronym))
                                    signalTypeIDs[signalTypeAcronym] = row.ConvertField<int>("ID");
                            }

                            // Determine which measurement rows should be synchronized based on operational mode flags
                            if (ReceiveInternalMetadata && ReceiveExternalMetadata)
                                measurementRows = measurementDetail.Select();
                            else if (ReceiveInternalMetadata)
                                measurementRows = measurementDetail.Select("Internal <> 0");
                            else if (ReceiveExternalMetadata)
                                measurementRows = measurementDetail.Select("Internal = 0");
                            else
                                measurementRows = new DataRow[0];

                            // Check existence of optional meta-data fields
                            DataColumnCollection measurementDetailColumns = measurementDetail.Columns;
                            bool phasorSourceIndexFieldExists = measurementDetailColumns.Contains("PhasorSourceIndex");
                            bool updatedOnFieldExists = measurementDetailColumns.Contains("UpdatedOn");

                            object phasorSourceIndex = DBNull.Value;

                            foreach (DataRow row in measurementRows)
                            {
                                bool recordNeedsUpdating;

                                // Determine if record has changed since last synchronization
                                if (updatedOnFieldExists)
                                {
                                    try
                                    {
                                        updateTime = Convert.ToDateTime(row["UpdatedOn"]);
                                        recordNeedsUpdating = updateTime > m_lastMetaDataRefreshTime;

                                        if (updateTime > latestUpdateTime)
                                            latestUpdateTime = updateTime;
                                    }
                                    catch
                                    {
                                        recordNeedsUpdating = true;
                                    }
                                }
                                else
                                {
                                    recordNeedsUpdating = true;
                                }

                                // Get device and signal type acronyms
                                deviceAcronym = row.Field<string>("DeviceAcronym") ?? string.Empty;
                                signalTypeAcronym = row.Field<string>("SignalAcronym") ?? string.Empty;

                                // Get phasor source index if field is defined
                                if (phasorSourceIndexFieldExists)
                                {
                                    // Using ConvertNullableField extension since publisher could use SQLite database in which case
                                    // all integers would arrive in data set as longs and need to be converted back to integers
                                    int? index = row.ConvertNullableField<int>("PhasorSourceIndex");
                                    phasorSourceIndex = index.HasValue ? (object)index.Value : (object)DBNull.Value;
                                }

                                // Make sure we have an associated device and signal type already defined for the measurement
                                if (!string.IsNullOrWhiteSpace(deviceAcronym) && deviceIDs.ContainsKey(deviceAcronym) && !string.IsNullOrWhiteSpace(signalTypeAcronym) && signalTypeIDs.ContainsKey(signalTypeAcronym))
                                {
                                    Guid signalID = Guid.Parse(row.Field<object>("SignalID").ToString());

                                    // Track unique measurement signal Guids in this meta-data session, we'll need to remove any old associated measurements that no longer exist
                                    signalIDs.Add(signalID);


                                    // Prefix the tag name with the "updated" device name
                                    string pointTag = sourcePrefix + row.Field<string>("PointTag");

                                    // Look up associated device ID (local DB auto-inc)
                                    deviceID = deviceIDs[deviceAcronym];

                                    // Determine if measurement record already exists
                                    if (Convert.ToInt32(command.ExecuteScalar(measurementExistsSql, m_metadataSynchronizationTimeout, database.Guid(signalID))) == 0)
                                    {
                                        string alternateTag = Guid.NewGuid().ToString();

                                        // Insert new measurement record
                                        command.ExecuteNonQuery(insertMeasurementSql, m_metadataSynchronizationTimeout, deviceID, historianID, pointTag, alternateTag, signalTypeIDs[signalTypeAcronym], phasorSourceIndex, sourcePrefix + row.Field<string>("SignalReference"), row.Field<string>("Description") ?? string.Empty, database.Bool(m_internal));

                                        // Guids are normally auto-generated during insert - after insertion update the Guid so that it matches the source data. Most of the database
                                        // scripts have triggers that support properly assigning the Guid during an insert, but this code ensures the Guid will always get assigned.
                                        command.ExecuteNonQuery(updateMeasurementSignalIDSql, m_metadataSynchronizationTimeout, database.Guid(signalID), alternateTag);
                                    }
                                    else if (recordNeedsUpdating)
                                    {
                                        // Update existing measurement record. Note that this update assumes that measurements will remain associated with a static source device.
                                        command.ExecuteNonQuery(updateMeasurementSql, m_metadataSynchronizationTimeout, historianID, pointTag, signalTypeIDs[signalTypeAcronym], phasorSourceIndex, sourcePrefix + row.Field<string>("SignalReference"), row.Field<string>("Description") ?? string.Empty, database.Bool(m_internal), database.Guid(signalID));
                                    }
                                }

                                // Periodically notify user about synchronization progress
                                UpdateSyncProgress();
                            }

                            // Remove any measurement records associated with existing devices in this session but no longer exist in the meta-data
                            if (signalIDs.Count > 0)
                            {
                                // Sort signal ID list so that binary search can be used for quick lookups
                                signalIDs.Sort();

                                // Query all the guid-based signal ID's for all measurement records associated with the parent device using run-time ID
                                DataTable measurementSignalIDs = command.RetrieveData(database.AdapterType, queryMeasurementSignalIDsSql, m_metadataSynchronizationTimeout, (int)ID);
                                Guid signalID;

                                // Walk through each database record and see if the measurement exists in the provided meta-data
                                foreach (DataRow measurementRow in measurementSignalIDs.Rows)
                                {
                                    signalID = database.Guid(measurementRow, "SignalID");

                                    // Remove any measurements in the database that are associated with received devices and do not exist in the meta-data
                                    if (signalIDs.BinarySearch(signalID) < 0)
                                    {
                                        // Measurement was not in the meta-data, get the measurement's actual record based ID for its associated device
                                        object measurementDeviceID = command.ExecuteScalar(queryMeasurementDeviceIDSql, m_metadataSynchronizationTimeout, database.Guid(signalID));

                                        // If the unknown measurement is directly associated with a device that exists in the meta-data it is assumed that this measurement
                                        // was removed from the publishing system and no longer exists therefore we remove it from the local measurement cache. If the user
                                        // needs custom local measurements associated with a remote device, they should be associated with the parent device only.
                                        if (measurementDeviceID != null && !(measurementDeviceID is DBNull) && deviceIDs.ContainsValue(Convert.ToInt32(measurementDeviceID)))
                                            command.ExecuteNonQuery(deleteMeasurementSql, m_metadataSynchronizationTimeout, database.Guid(signalID));
                                    }
                                }

                                UpdateSyncProgress();
                            }
                        }

                        // Check to see if data for the "PhasorDetail" table was included in the meta-data
                        if (metadata.Tables.Contains("PhasorDetail"))
                        {
                            Dictionary<int, int> maxSourceIndicies = new Dictionary<int, int>();
                            int sourceIndex;

                            // Phasor data is normally only needed so that the user can properly generate a mirrored IEEE C37.118 output stream from the source data.
                            // This is necessary since, in this protocol, the phasors are described (i.e., labeled) as a unit (i.e., as a complex number) instead of
                            // as two distinct angle and magnitude measurements.

                            // Define SQL statement to query if phasor record is already defined (no Guid is defined for these simple label records)
                            string phasorExistsSql = database.ParameterizedQueryString("SELECT COUNT(*) FROM Phasor WHERE DeviceID = {0} AND SourceIndex = {1}", "deviceID", "sourceIndex");

                            // Define SQL statement to insert new phasor record
                            string insertPhasorSql = database.ParameterizedQueryString("INSERT INTO Phasor(DeviceID, Label, Type, Phase, SourceIndex) VALUES ({0}, {1}, {2}, {3}, {4})", "deviceID", "label", "type", "phase", "sourceIndex");

                            // Define SQL statement to update existing phasor record
                            string updatePhasorSql = database.ParameterizedQueryString("UPDATE Phasor SET Label = {0}, Type = {1}, Phase = {2} WHERE DeviceID = {3} AND SourceIndex = {4}", "label", "type", "phase", "deviceID", "sourceIndex");

                            // Define SQL statement to delete a phasor record
                            string deletePhasorSql = database.ParameterizedQueryString("DELETE FROM Phasor WHERE DeviceID = {0} AND SourceIndex > {1}", "deviceID", "sourceIndex");

                            foreach (DataRow row in metadata.Tables["PhasorDetail"].Rows)
                            {
                                // Get device acronym
                                deviceAcronym = row.Field<string>("DeviceAcronym") ?? string.Empty;

                                // Make sure we have an associated device already defined for the phasor record
                                if (!string.IsNullOrWhiteSpace(deviceAcronym) && deviceIDs.ContainsKey(deviceAcronym))
                                {
                                    bool recordNeedsUpdating;

                                    // Determine if record has changed since last synchronization
                                    try
                                    {
                                        updateTime = Convert.ToDateTime(row["UpdatedOn"]);
                                        recordNeedsUpdating = updateTime > m_lastMetaDataRefreshTime;

                                        if (updateTime > latestUpdateTime)
                                            latestUpdateTime = updateTime;
                                    }
                                    catch
                                    {
                                        recordNeedsUpdating = true;
                                    }

                                    deviceID = deviceIDs[deviceAcronym];

                                    // Determine if phasor record already exists
                                    if (Convert.ToInt32(command.ExecuteScalar(phasorExistsSql, m_metadataSynchronizationTimeout, deviceID, row.ConvertField<int>("SourceIndex"))) == 0)
                                    {
                                        // Insert new phasor record
                                        command.ExecuteNonQuery(insertPhasorSql, m_metadataSynchronizationTimeout, deviceID, row.Field<string>("Label") ?? "undefined", (row.Field<string>("Type") ?? "V").TruncateLeft(1), (row.Field<string>("Phase") ?? "+").TruncateLeft(1), row.ConvertField<int>("SourceIndex"));
                                    }
                                    else if (recordNeedsUpdating)
                                    {
                                        // Update existing phasor record
                                        command.ExecuteNonQuery(updatePhasorSql, m_metadataSynchronizationTimeout, row.Field<string>("Label") ?? "undefined", (row.Field<string>("Type") ?? "V").TruncateLeft(1), (row.Field<string>("Phase") ?? "+").TruncateLeft(1), deviceID, row.ConvertField<int>("SourceIndex"));
                                    }

                                    // Track largest source index for each device
                                    maxSourceIndicies.TryGetValue(deviceID, out sourceIndex);

                                    if (row.ConvertField<int>("SourceIndex") > sourceIndex)
                                        maxSourceIndicies[deviceID] = row.ConvertField<int>("SourceIndex");
                                }

                                // Periodically notify user about synchronization progress
                                UpdateSyncProgress();
                            }

                            // Remove any phasor records associated with existing devices in this session but no longer exist in the meta-data
                            if (maxSourceIndicies.Count > 0)
                            {
                                foreach (KeyValuePair<int, int> deviceIndexPair in maxSourceIndicies)
                                {
                                    command.ExecuteNonQuery(deletePhasorSql, m_metadataSynchronizationTimeout, deviceIndexPair.Key, deviceIndexPair.Value);
                                }
                            }
                        }

                        if ((object)transaction != null)
                            transaction.Commit();

                        // Update local in-memory synchronized meta-data cache
                        m_synchronizedMetadata = metadata;
                    }
                    catch (Exception ex)
                    {
                        OnProcessException(new InvalidOperationException("Failed to synchronize meta-data to local cache: " + ex.Message, ex));

                        if ((object)transaction != null)
                        {
                            try
                            {
                                transaction.Rollback();
                            }
                            catch (Exception rollbackException)
                            {
                                OnProcessException(new InvalidOperationException("Failed to roll back database transaction due to exception: " + rollbackException.Message, rollbackException));
                            }
                        }

                        return;
                    }
                    finally
                    {
                        if ((object)transaction != null)
                            transaction.Dispose();
                    }
                }

                // New signals may have been defined, take original remote signal index cache and apply changes
                if (m_remoteSignalIndexCache != null)
                    m_signalIndexCache = new SignalIndexCache(DataSource, m_remoteSignalIndexCache);

                m_lastMetaDataRefreshTime = latestUpdateTime > DateTime.MinValue ? latestUpdateTime : DateTime.UtcNow;

                OnStatusMessage("Meta-data synchronization completed successfully in {0}", (DateTime.UtcNow.Ticks - startTime).ToElapsedTimeString(2));

                // Send notification that system configuration has changed
                OnConfigurationChanged();
            }
            catch (Exception ex)
            {
                OnProcessException(new InvalidOperationException("Failed to synchronize meta-data to local cache: " + ex.Message, ex));
            }
            finally
            {
                // Restart data stream monitor after meta-data synchronization if it was originally enabled
                if (dataMonitoringEnabled && (object)m_dataStreamMonitor != null)
                    m_dataStreamMonitor.Enabled = true;
            }
        }
コード例 #49
0
ファイル: OutputStreamDevicePhasor.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Loads <see cref="OutputStreamDevicePhasor"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="keys">Keys of the measuremnets to be loaded from the database</param>
        /// <returns>Collection of <see cref="OutputStreamDevicePhasor"/>.</returns>
        public static ObservableCollection<OutputStreamDevicePhasor> Load(AdoDataConnection database, IList<int> keys)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                string query;
                string commaSeparatedKeys;

                OutputStreamDevicePhasor[] outputStreamDevicePhasorList = null;
                DataTable outputStreamDevicePhasorTable;
                int id;

                if ((object)keys != null && keys.Count > 0)
                {
                    commaSeparatedKeys = keys.Select(key => "" + key.ToString() + "").Aggregate((str1, str2) => str1 + "," + str2);
                    query = database.ParameterizedQueryString(string.Format("SELECT NodeID, OutputStreamDeviceID, ID, Label, Type, Phase, ScalingValue, LoadOrder " +
                          "FROM OutputStreamDevicePhasor WHERE ID IN ({0})", commaSeparatedKeys));

                    outputStreamDevicePhasorTable = database.Connection.RetrieveData(database.AdapterType, query);
                    outputStreamDevicePhasorList = new OutputStreamDevicePhasor[outputStreamDevicePhasorTable.Rows.Count];

                    foreach (DataRow row in outputStreamDevicePhasorTable.Rows)
                    {
                        id = row.ConvertField<int>("ID");

                        outputStreamDevicePhasorList[keys.IndexOf(id)] = new OutputStreamDevicePhasor()
                        {
                            NodeID = database.Guid(row, "NodeID"),
                            OutputStreamDeviceID = row.ConvertField<int>("OutputStreamDeviceID"),
                            ID = id,
                            Label = row.Field<string>("Label"),
                            Type = row.Field<string>("Type"),
                            Phase = row.Field<string>("Phase"),
                            ScalingValue = row.ConvertField<int>("ScalingValue"),
                            LoadOrder = row.ConvertField<int>("LoadOrder"),
                            m_phaseType = row.Field<string>("Phase") == "+" ? "Positive Sequence" : row.Field<string>("Phase") == "-" ? "Negative Sequence" :
                                                                    row.Field<string>("Phase") == "0" ? "Zero Sequence" : row.Field<string>("Phase") == "A" ? "Phase A" :
                                                                    row.Field<string>("Phase") == "B" ? "Phase B" : "Phase C",
                            m_phasorType = row.Field<string>("Type") == "V" ? "Voltage" : "Current"
                        };
                    }
                }

                return new ObservableCollection<OutputStreamDevicePhasor>(outputStreamDevicePhasorList ?? new OutputStreamDevicePhasor[0]);
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #50
0
ファイル: OutputStreamMeasurement.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Saves <see cref="OutputStreamMeasurement"/> information to database.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="outputStreamMeasurement">Information about <see cref="OutputStreamMeasurement"/>.</param>        
        /// <returns>String, for display use, indicating success.</returns>
        public static string Save(AdoDataConnection database, OutputStreamMeasurement outputStreamMeasurement)
        {
            bool createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);

                if (outputStreamMeasurement.ID == 0)
                {
                    query = database.ParameterizedQueryString("INSERT INTO OutputStreamMeasurement (NodeID, AdapterID, HistorianID, PointID, SignalReference, " +
                        " UpdatedBy, UpdatedOn, CreatedBy, CreatedOn) VALUES ({0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8})",
                        "nodeID", "adapterID", "historianID", "pointID", "signalReference", "updatedBy", "updatedOn", "createdBy",
                        "createdOn");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, outputStreamMeasurement.NodeID == Guid.Empty ? database.CurrentNodeID() : database.Guid(outputStreamMeasurement.NodeID),
                        outputStreamMeasurement.AdapterID, outputStreamMeasurement.HistorianID.ToNotNull(), outputStreamMeasurement.PointID, outputStreamMeasurement.SignalReference,
                        CommonFunctions.CurrentUser, database.UtcNow, CommonFunctions.CurrentUser, database.UtcNow);
                }
                else
                {
                    query = database.ParameterizedQueryString("UPDATE OutputStreamMeasurement SET NodeID = {0}, AdapterID = {1}, HistorianID = {2}, PointID = {3}, " +
                        "SignalReference = {4}, UpdatedBy = {5}, UpdatedOn = {6} WHERE ID = {7}", "nodeID", "adapterID",
                        "historianID", "pointID", "signalReference", "updatedBy", "updatedOn", "id");

                    database.Connection.ExecuteNonQuery(query, DefaultTimeout, database.Guid(outputStreamMeasurement.NodeID), outputStreamMeasurement.AdapterID,
                        outputStreamMeasurement.HistorianID.ToNotNull(), outputStreamMeasurement.PointID, outputStreamMeasurement.SignalReference,
                        CommonFunctions.CurrentUser, database.UtcNow, outputStreamMeasurement.ID);
                }

                return "OutputStreamMeasurement information saved successfully";
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #51
0
ファイル: Subscriber.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Loads <see cref="Node"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>        
        /// <returns>Collection of <see cref="Subscriber"/>.</returns>
        public static ObservableCollection<Subscriber> Load(AdoDataConnection database)
        {
            ObservableCollection<Subscriber> subscriberList;
            DataTable subscriberTable;
            bool createdConnection = false;
            string query;

            SslPolicyErrors validPolicyErrors;
            X509ChainStatusFlags validChainFlags;

            try
            {
                createdConnection = CreateConnection(ref database);
                subscriberList = new ObservableCollection<Subscriber>();

                query = database.ParameterizedQueryString("SELECT ID, NodeID, Acronym, Name, SharedSecret, AuthKey, ValidIPAddresses, RemoteCertificateFile," +
                    " ValidPolicyErrors, ValidChainFlags, AccessControlFilter, Enabled FROM Subscriber WHERE NodeID = {0} ORDER BY Name", "nodeID");

                subscriberTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID());

                foreach (DataRow row in subscriberTable.Rows)
                {
                    subscriberList.Add(new Subscriber()
                    {
                        ID = database.Guid(row, "ID"),
                        NodeID = database.Guid(row, "NodeID"),
                        Acronym = row.Field<string>("Acronym"),
                        Name = row.Field<string>("Name"),
                        SharedSecret = row.Field<string>("SharedSecret"),
                        AuthKey = row.Field<string>("AuthKey"),
                        ValidIPAddresses = row.Field<string>("ValidIPAddresses"),
                        RemoteCertificateFile = row.Field<string>("RemoteCertificateFile"),
                        ValidPolicyErrors = Enum.TryParse(row.Field<string>("ValidPolicyErrors"), out validPolicyErrors) ? validPolicyErrors : (SslPolicyErrors?)null,
                        ValidChainFlags = Enum.TryParse(row.Field<string>("ValidChainFlags"), out validChainFlags) ? validChainFlags : (X509ChainStatusFlags?)null,
                        AccessControlFilter = row.Field<string>("AccessControlFilter"),
                        Enabled = Convert.ToBoolean(row.Field<object>("Enabled")),
                        AllowedMeasurementGroups = GetAllowedMeasurementGroups(database, database.Guid(row, "ID")),
                        DeniedMeasurementGroups = GetDeniedMeasurementGroups(database, database.Guid(row, "ID")),
                        AvailableMeasurementGroups = GetAvailableMeasurementGroups(database, database.Guid(row, "ID")),
                        StatusColor = "gray",
                        Version = ""
                    });
                }

                return subscriberList;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #52
0
ファイル: UserAccount.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Deletes specified <see cref="UserAccount"/> record from database.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="userAccountID">ID of the record to be deleted.</param>
        /// <returns>String, for display use, indicating success.</returns>
        public static string Delete(AdoDataConnection database, Guid userAccountID)
        {
            bool createdConnection = false;
            string userName;

            try
            {
                createdConnection = CreateConnection(ref database);

                // Get the name of the user to be deleted
                userName = database.Connection.ExecuteScalar(database.ParameterizedQueryString("SELECT Name FROM UserAccount WHERE ID = {0}", "userAccountID"), DefaultTimeout, database.Guid(userAccountID)).ToNonNullString();

                // Setup current user context for any delete triggers
                CommonFunctions.SetCurrentUserContext(database);

                // Delete the user from the database
                database.Connection.ExecuteNonQuery(database.ParameterizedQueryString("DELETE FROM UserAccount WHERE ID = {0}", "userAccountID"), DefaultTimeout, database.Guid(userAccountID));

                // Write to the event log
                CommonFunctions.LogEvent(string.Format("User \"{0}\" deleted successfully by user \"{1}\".", UserInfo.SIDToAccountName(userName), CommonFunctions.CurrentUser), 12);

                return "User account deleted successfully";
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #53
0
ファイル: Subscriber.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Retrieves <see cref="Dictionary{T1,T2}"/> type collection of <see cref="MeasurementGroup"/> neither allowed nor denied for <see cref="Subscriber"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="subscriberID">ID of the <see cref="Subscriber"/> to filter data.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> type collection of ID and Name of <see cref="MeasurementGroup"/>.</returns>
        public static Dictionary<int, string> GetAvailableMeasurementGroups(AdoDataConnection database, Guid subscriberID)
        {
            Dictionary<int, string> availableMeasurementGroups;
            DataTable availableMeasurementGroupTable;
            bool createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);
                availableMeasurementGroups = new Dictionary<int, string>();
                query = database.ParameterizedQueryString("SELECT ID, Name FROM MeasurementGroup WHERE ID NOT IN (SELECT MeasurementGroupID FROM SubscriberMeasurementGroup WHERE SubscriberID = {0}) ORDER BY Name", "subscriberID");
                availableMeasurementGroupTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.Guid(subscriberID));

                foreach (DataRow row in availableMeasurementGroupTable.Rows)
                    availableMeasurementGroups[row.ConvertField<int>("ID")] = row.Field<string>("Name");

                return availableMeasurementGroups;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #54
0
ファイル: MeasurementGroup.cs プロジェクト: rmc00/gsf
        // Static Methods

        /// <summary>
        /// Loads <see cref="MeasurementGroup"/> information as an <see cref="ObservableCollection{T}"/> style list.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <returns>Collection of <see cref="MeasurementGroup"/>.</returns>
        public static ObservableCollection<MeasurementGroup> Load(AdoDataConnection database)
        {
            ObservableCollection<MeasurementGroup> measurementGroupList;
            DataTable measurementGroupTable;
            bool createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);
                measurementGroupList = new ObservableCollection<MeasurementGroup>();
                query = database.ParameterizedQueryString("SELECT NodeID, ID, Name, Description, FilterExpression FROM MeasurementGroup WHERE NodeID = {0} ORDER BY Name", "nodeID");
                measurementGroupTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.CurrentNodeID());

                foreach (DataRow row in measurementGroupTable.Rows)
                {
                    measurementGroupList.Add(new MeasurementGroup()
                    {
                        NodeID = database.Guid(row, "NodeID"),
                        ID = row.ConvertField<int>("ID"),
                        Name = row.Field<string>("Name"),
                        Description = row.Field<object>("Description").ToNonNullString(),
                        FilterExpression = row.Field<object>("FilterExpression").ToNonNullString(),
                    });
                }

                measurementGroupList.Insert(0, new MeasurementGroup());

                return measurementGroupList;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #55
0
ファイル: Subscriber.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Retrieves <see cref="Dictionary{T1,T2}"/> type collection of <see cref="MeasurementGroup"/> denied for <see cref="Subscriber"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="subscriberID">ID of the <see cref="Subscriber"/> to filter data.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> type collection of ID and Name of <see cref="MeasurementGroup"/>.</returns>
        public static Dictionary<int, string> GetDeniedMeasurementGroups(AdoDataConnection database, Guid subscriberID)
        {
            Dictionary<int, string> deniedMeasurementGroups;
            DataTable deniedMeasurementGroupTable;
            bool createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);
                deniedMeasurementGroups = new Dictionary<int, string>();
                query = database.ParameterizedQueryString("SELECT MeasurementGroupID, MeasurementGroupName FROM SubscriberMeasGroupDetail WHERE SubscriberID = {0} AND Allowed = {1} ORDER BY MeasurementGroupName", "subscriberID", "allowed");
                deniedMeasurementGroupTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.Guid(subscriberID), database.Bool(false));

                foreach (DataRow row in deniedMeasurementGroupTable.Rows)
                    deniedMeasurementGroups[row.ConvertField<int>("MeasurementGroupID")] = row.Field<string>("MeasurementGroupName");

                return deniedMeasurementGroups;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #56
0
ファイル: Phasor.cs プロジェクト: rmc00/gsf
		/// <summary>
		/// Loads <see cref="PowerCalculation"/> information as an <see cref="ObservableCollection{T}"/> style list.
		/// </summary>
		/// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
		/// <param name="keys">Keys of the measurement to be loaded from the database</param>
		/// <returns>Collection of <see cref="PowerCalculation"/>.</returns>
		public static ObservableCollection<Phasor> Load(AdoDataConnection database, IList<int> keys)
		{
			var createdConnection = false;

			try
			{
				createdConnection = CreateConnection(ref database);

				Phasor[] phasorList = null;

				if (keys != null && keys.Count > 0)
				{
					var commaSeparatedKeys = keys.Select(key => key.ToString()).Aggregate((str1, str2) => str1 + "," + str2);
					var query = string.Format("select p.id, p.deviceid, d.acronym as DeviceAcronym, p.label, p.type, p.phase, p.sourceindex, mags.signalid as mag_signalid, angles.signalid as angle_signalid " +
											  "from phasor p left join measurement mags " +
											  "on mags.deviceid = p.deviceid and mags.phasorsourceindex = p.sourceindex and mags.signaltypeid in (1,3) " +
											  "left join measurement angles " +
											  "on angles.deviceid = p.deviceid and angles.phasorsourceindex = p.sourceindex and angles.signaltypeid in (2,4) " +
                                              "left join device d " +
                                              "on p.deviceid = d.id " +
											  "where p.id in ({0})", commaSeparatedKeys);
					var phasorTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout);
					phasorList = new Phasor[phasorTable.Rows.Count];

					foreach (DataRow row in phasorTable.Rows)
					{
						var id = row.ConvertField<int>("Id");
						var deviceId = row.ConvertField<int>("DeviceId");
                        var deviceName = row.ConvertField<string>("DeviceAcronym");
						var label = row.ConvertField<string>("Label");
						var type = row.ConvertField<string>("Type");
						var phase = row.ConvertField<string>("Phase");
						var sourceIndex = row.ConvertField<int>("SourceIndex");
						var magnitudeSignalId = database.Guid(row, "mag_signalId");
						var angleSignalId = database.Guid(row, "angle_signalId");

						var measurements = Measurement.LoadFromKeys(database, (new[] {magnitudeSignalId, angleSignalId}).ToList());

                        phasorList[keys.IndexOf(id)] = new Phasor
                        {
                            ID = id,
                            DeviceID = deviceId,
                            DeviceName = deviceName,
							Label = label,
							Type = type,
							Phase = phase,
							SourceIndex = sourceIndex,
							MagnitudeMeasurement = measurements.FirstOrDefault(m => m.SignalID == magnitudeSignalId),
							AngleMeasurement = measurements.FirstOrDefault(m => m.SignalID == angleSignalId)
						};
					}
				}

				return new ObservableCollection<Phasor>(phasorList ?? new Phasor[0]);
			}
			finally
			{
				if (createdConnection && database != null)
					database.Dispose();
			}
		}
コード例 #57
0
ファイル: Subscriber.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Gets a <see cref="Dictionary{T1,T2}"/> style list of <see cref="Subscriber"/> information.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="isOptional">Indicates if selection on UI is optional for this collection.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> containing ID and Name of subscribers defined in the database.</returns>
        public static Dictionary<Guid, string> GetLookupList(AdoDataConnection database, bool isOptional = false)
        {
            Dictionary<Guid, string> subscriberList;
            DataTable subscriberTable;
            bool createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);
                subscriberList = new Dictionary<Guid, string>();

                if (isOptional)
                    subscriberList.Add(Guid.Empty, "Select Subscriber");

                query = database.ParameterizedQueryString("SELECT ID, Acronym FROM Subscriber WHERE Enabled = {0} AND NodeID = {1} ORDER BY Name", "enabled", "nodeID");
                subscriberTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.Bool(true), database.CurrentNodeID());

                foreach (DataRow row in subscriberTable.Rows)
                {
                    subscriberList[database.Guid(row, "ID")] = row.Field<string>("Acronym");
                }

                return subscriberList;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #58
0
ファイル: Subscriber.cs プロジェクト: avs009/gsf
        /// <summary>
        /// Retrieves <see cref="Dictionary{T1,T2}"/> type collection of <see cref="Measurement"/> allowed for <see cref="Subscriber"/>.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="subscriberID">ID of the <see cref="Subscriber"/> to filter data.</param>
        /// <returns><see cref="Dictionary{T1,T2}"/> type collection of SignalID and PointTag of <see cref="Measurement"/>.</returns>
        public static Dictionary<Guid, string> GetAllowedMeasurements(AdoDataConnection database, Guid subscriberID)
        {
            Dictionary<Guid, string> allowedMeasurements;
            DataTable allowedMeasurementTable;
            bool createdConnection = false;
            string query;

            try
            {
                createdConnection = CreateConnection(ref database);
                allowedMeasurements = new Dictionary<Guid, string>();
                query = database.ParameterizedQueryString("SELECT SignalID, PointTag FROM SubscriberMeasurementDetail WHERE SubscriberID = {0} AND Allowed = {1} ORDER BY PointTag", "subscriberID", "allowed");
                allowedMeasurementTable = database.Connection.RetrieveData(database.AdapterType, query, DefaultTimeout, database.Guid(subscriberID), database.Bool(true));

                foreach (DataRow row in allowedMeasurementTable.Rows)
                    allowedMeasurements[database.Guid(row, "SignalID")] = row.Field<string>("PointTag");

                return allowedMeasurements;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #59
0
ファイル: Subscriber.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Deletes specified <see cref="Subscriber"/> record from database.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="id">ID of the record to be deleted.</param>
        /// <returns>String, for display use, indicating success.</returns>
        public static string Delete(AdoDataConnection database, Guid id)
        {
            bool createdConnection = false;

            try
            {
                createdConnection = CreateConnection(ref database);

                // Setup current user context for any delete triggers
                CommonFunctions.SetCurrentUserContext(database);

                database.Connection.ExecuteNonQuery(database.ParameterizedQueryString("DELETE FROM Subscriber WHERE ID = {0}", "id"), DefaultTimeout, database.Guid(id));

                try
                {
                    CommonFunctions.SendCommandToService("ReloadConfig");
                }
                catch (Exception ex)
                {
                    return "Subscriber deleted successfully. Failed to send ReloadConfig command to backend service." + Environment.NewLine + ex.Message;
                }

                return "Subscriber deleted successfully";
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }
コード例 #60
0
ファイル: MeasurementGroup.cs プロジェクト: rmc00/gsf
        /// <summary>
        /// Retrieves <see cref="MeasurementGroup"/> information for the group with the given ID.
        /// </summary>
        /// <param name="database"><see cref="AdoDataConnection"/> to connection to database.</param>
        /// <param name="groupID">The ID of the measurement group to be retrieved.</param>
        /// <returns>Measurement group with the given ID.</returns>
        public static MeasurementGroup GetMeasurementGroup(AdoDataConnection database, int groupID)
        {
            DataTable measurementGroupTable;
            bool createdConnection = false;
            DataRow row;

            try
            {
                createdConnection = CreateConnection(ref database);
                measurementGroupTable = database.RetrieveData(DefaultTimeout, "SELECT * FROM MeasurementGroup WHERE ID = {0}", groupID);

                if (measurementGroupTable.Rows.Count == 0)
                    return null;

                row = measurementGroupTable.Rows[0];

                MeasurementGroup measurementGroup = new MeasurementGroup()
                {
                    NodeID = database.Guid(row, "NodeID"),
                    ID = row.ConvertField<int>("ID"),
                    Name = row.Field<string>("Name"),
                    Description = row.Field<object>("Description").ToNonNullString(),
                    FilterExpression = row.Field<object>("FilterExpression").ToNonNullString(),
                };

                return measurementGroup;
            }
            finally
            {
                if (createdConnection && database != null)
                    database.Dispose();
            }
        }