Example #1
0
        public void ValueConflictThrows()
        {
            var entity = new TestEntity
            {
                Property = "prop"
            };

            using (var context = InMemoryContextBuilder.Build <TestDataContext>())
            {
                context.Add(entity);
                context.SaveChanges();
            }

            using (var context = InMemoryContextBuilder.Build <TestDataContext>())
            {
                var update = new TestEntity
                {
                    Id        = entity.Id,
                    Property  = "Something new",
                    Timestamp = RowVersion.New()
                };
                context.Attach(update);
                context.Entry(update).Property("Property").IsModified = true;
                var exception = Assert.Throws <DbUpdateConcurrencyException>(() => context.SaveChanges());
                Approvals.Verify(exception.Message);
            }
        }
Example #2
0
        private int IncrementNextRecordVersion <TModel>(IDbConnection connection, TKey identity)
        {
            var table      = _integrator.GetTableInfo(typeof(TModel));
            var versionTbl = GetVersionTableInfo(table, changesSchema);

            var    param     = new { id = identity };
            string tableName = versionTbl.ToString();

            int result = connection.QuerySingleOrDefault <int?>(SqlSelectNextVersion(tableName), param) ?? 0;

            if (result == 0)
            {
                RowVersion <TKey> initialVersion = new RowVersion <TKey>()
                {
                    RecordId    = identity,
                    NextVersion = 1
                };
                PlainInsert(connection, initialVersion, tableName: tableName);
                result = 1;
            }

            connection.Execute(SqlUpdateNextVersion(tableName), param);

            return(result);
        }
        /// <inheritdoc />
        protected override string FieldToString(FieldId field, RowVersion version)
        {
            return(field switch
            {
                FieldId.ProvinceState when version == RowVersion.JHopkinsV1 || version == RowVersion.JHopkinsV2 => "Province/State",
                FieldId.ProvinceState => "Province_State",

                FieldId.CountryRegion when version == RowVersion.JHopkinsV1 || version == RowVersion.JHopkinsV2 => "Country/Region",
                FieldId.CountryRegion => "Country_Region",

                FieldId.LastUpdate when version == RowVersion.JHopkinsV1 || version == RowVersion.JHopkinsV2 => "Last Update",
                FieldId.LastUpdate => "Last_Update",

                FieldId.Latitude when version == RowVersion.JHopkinsV1 || version == RowVersion.JHopkinsV2 => field.ToString(),
                FieldId.Latitude => "Lat",

                FieldId.Longitude when version == RowVersion.JHopkinsV1 || version == RowVersion.JHopkinsV2 => field.ToString(),
                FieldId.Longitude => "Long_",

                FieldId.CombinedKey => "Combined_Key",

                FieldId.IncidenceRate when version == RowVersion.JHopkinsV4 => "Incidence_Rate",
                FieldId.IncidenceRate when version == RowVersion.JHopkinsV5 => "Incident_Rate",

                FieldId.CaseFatalityRatio when version == RowVersion.JHopkinsV4 => "Case-Fatality_Ratio",
                FieldId.CaseFatalityRatio when version == RowVersion.JHopkinsV5 => "Case_Fatality_Ratio",


                _ => field.ToString()
            });
        /// <inheritdoc />
        protected override string FieldToString(FieldId field, RowVersion version)
        {
            return(field switch
            {
                FieldId.Iso2 when version == RowVersion.StatsBase => "iso2",
                FieldId.Iso3 when version == RowVersion.StatsBase => "iso3",
                FieldId.Code3 when version == RowVersion.StatsBase => "code3",
                FieldId.CountryRegion when version == RowVersion.StatsBase => "Country_Region",

                FieldId.Iso2 when version == RowVersion.StatsEx => "Two_Letter_Country_Code",
                FieldId.Iso3 when version == RowVersion.StatsEx => "Three_Letter_Country_Code",
                FieldId.Code3 when version == RowVersion.StatsEx => "Country_Number",
                FieldId.CountryRegion when version == RowVersion.StatsEx => "Country_Name",

                FieldId.ProvinceState => "Province_State",
                FieldId.Latitude => "Lat",
                FieldId.Longitude => "Long_",
                FieldId.CombinedKey => "Combined_Key",

                FieldId.ContinentName => "Continent_Name",
                FieldId.ContinentCode => "Continent_Code",

                FieldId.English => "English_JHopkins",
                FieldId.Russian => "Russian_Yandex",

                _ => field.ToString()
            });
 /// <summary>
 /// Escreve os dados para XML.
 /// </summary>
 /// <param name="writer"></param>
 void System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
 {
     writer.WriteAttributeString("xmlns", "i", null, Namespaces.SchemaInstance);
     writer.WriteAttributeString("xmlns", "q", null, Namespaces.Query);
     writer.WriteAttributeString("ActionId", ActionId.ToString());
     writer.WriteAttributeString("Type", Type.ToString());
     writer.WriteAttributeString("EntityFullName", EntityFullName);
     writer.WriteAttributeString("ProviderName", ProviderName ?? "");
     writer.WriteAttributeString("RowVersion", (RowVersion.HasValue) ? RowVersion.ToString() : "");
     writer.WriteAttributeString("CommandTimeout", CommandTimeout.ToString());
     writer.WriteStartElement("Parameters", Namespaces.Data);
     if (Parameters != null)
     {
         foreach (System.Xml.Serialization.IXmlSerializable parameter in Parameters)
         {
             writer.WriteStartElement("Parameter", Namespaces.Data);
             parameter.WriteXml(writer);
             writer.WriteEndElement();
         }
     }
     writer.WriteEndElement();
     writer.WriteStartElement("Conditional");
     if (Conditional != null)
     {
         ((System.Xml.Serialization.IXmlSerializable)Conditional).WriteXml(writer);
     }
     writer.WriteEndElement();
     writer.WriteStartElement("AlternativeActions");
     foreach (System.Xml.Serialization.IXmlSerializable action in AlternativeActions)
     {
         writer.WriteStartElement("PersistenceAction", Namespaces.Data);
         action.WriteXml(writer);
         writer.WriteEndElement();
     }
     writer.WriteEndElement();
     writer.WriteStartElement("BeforeActions");
     foreach (System.Xml.Serialization.IXmlSerializable action in BeforeActions)
     {
         writer.WriteStartElement("PersistenceAction", Namespaces.Data);
         action.WriteXml(writer);
         writer.WriteEndElement();
     }
     writer.WriteEndElement();
     writer.WriteStartElement("AfterActions");
     foreach (System.Xml.Serialization.IXmlSerializable action in AfterActions)
     {
         writer.WriteStartElement("PersistenceAction", Namespaces.Data);
         action.WriteXml(writer);
         writer.WriteEndElement();
     }
     writer.WriteEndElement();
     WriteItem <Colosoft.Query.StoredProcedureName>(writer, "StoredProcedureName", _storedProcedureName ?? Colosoft.Query.StoredProcedureName.Empty);
     writer.WriteStartElement("Query");
     if (Query != null)
     {
         ((System.Xml.Serialization.IXmlSerializable)Query).WriteXml(writer);
     }
     writer.WriteEndElement();
 }
 /// <inheritdoc />
 protected override string FieldToString(FieldId field, RowVersion version)
 {
     return(field switch
     {
         FieldId.LastUpdate => "Day",
         FieldId.CountryRegion => "Country",
         FieldId.ProvinceState => "Province",
         FieldId.Admin2 => "County",
         FieldId.ContinentName => "Continent",
         FieldId.Population => "Population",
         FieldId.CombinedKey => "StatsName",
         _ => field.ToString()
     });
Example #7
0
        private bool ValidateColumnsOrder(RowVersion version, IEnumerable <string> headerColumns)
        {
            using var headerEnumerator = headerColumns.GetEnumerator();
            using var fieldsEnumerator = VersionFieldsDictionary[version].GetEnumerator();

            while (headerEnumerator.MoveNext() && fieldsEnumerator.MoveNext())
            {
                if (headerEnumerator.Current != FieldToString(fieldsEnumerator.Current, version))
                {
                    return(false);
                }
            }

            return(true);
        }
Example #8
0
        /// <inheritdoc />
        protected override string FieldToString(FieldId field, RowVersion version)
        {
            return(field switch
            {
                FieldId.Confirmed => "Заражений",
                FieldId.LastUpdate => "Дата",
                FieldId.ProvinceState => "Регион",
                FieldId.Recovered => "Выздоровлений",
                FieldId.Deaths => "Смертей",
                FieldId.DeathsByDay => "Смертей за день",
                FieldId.ConfirmedByDay => "Заражений за день",
                FieldId.RecoveredByDay => "Выздоровлений за день",

                _ => field.ToString()
            });
Example #9
0
    void Validate(Func <object, byte[]> getter, Action <object, byte[]> setter, IProperty primaryKey, object primaryKeyValue, List <object> objects)
    {
        byte[] rowVersion;
        var    first = objects.First();

        var exceptionSuffix = $" Type: {first.GetType().FullName}. {primaryKey.Name}: {primaryKeyValue}.";
        //If seen
        var version = getter(first);

        if (seen.Any(x => ReferenceEquals(x, first)))
        {
            rowVersion = version;
            if (rowVersion == null)
            {
                throw new Exception($"Row version has been incorrectly set to null. {exceptionSuffix}");
            }
        }
        //If not seen
        else
        {
            if (version != null)
            {
                throw new Exception($"The first save must have a null RowVersion. {exceptionSuffix}");
            }

            rowVersion = RowVersion.New();
            setter(first, rowVersion);
            seen.Add(first);
        }

        foreach (var o in objects.Skip(1))
        {
            var bytes = getter(o);

            if (bytes != null && bytes.SequenceEqual(rowVersion))
            {
                rowVersion = RowVersion.New();
                setter(o, rowVersion);
            }
        }
    }
Example #10
0
    void Validate(Func <object, byte[]> getter, Action <object, byte[]> setter, List <object> objects)
    {
        byte[] rowVersion;
        var    first = objects.First();

        var version = getter(first);

        if (seen.Any(x => ReferenceEquals(x, first)))
        {
            rowVersion = version;
            if (rowVersion == null)
            {
                throw new Exception("Row version has been incorrectly set to null");
            }
        }
        //If not seen
        else
        {
            if (version != null)
            {
                throw new Exception("The first save must have a null RowVersion");
            }

            rowVersion = RowVersion.New();
            setter(first, rowVersion);
            seen.Add(first);
        }

        foreach (var o in objects.Skip(1))
        {
            var bytes = getter(o);

            if (bytes != null && bytes.SequenceEqual(rowVersion))
            {
                rowVersion = RowVersion.New();
                setter(o, rowVersion);
            }
        }
    }
Example #11
0
        /// <summary>
        /// Initializes the Globa Data Model.
        /// </summary>
        static ServerDataModel()
        {
            // IMPORTANT CONCEPT: The RowVersion object keeps track of the 'age' of the server dataset.  When rows are added,
            // updated and deleted, the row version is incremented.  There is a single, monotonically incrementing value used for
            // the entire DataSet.  We initialize the database with a value of 1, that allows the client to use a value of zero
            // when initializing.  A requested row version of zero will guarantee that all the contents of the database are
            // returned to the client.
            ServerDataModel.rowVersion = new RowVersion();

            // The persistent storage device used by this server is specified in this custom configuration section.
            PersistentStoreSection persistentStoreSection =
                (PersistentStoreSection)ConfigurationManager.GetSection("persistentStoreSection");
            PersistentStoreInfo persistentStoreInfo = persistentStoreSection[PersistentStore];

            if (persistentStoreInfo == null)
            {
                throw new Exception("There is no persistent storage device defined for this server.");
            }
            SqlConnection sqlConnection = new SqlConnection(persistentStoreInfo.ConnectionString);

            try
            {
                // Make sure all the tables are locked before populating them.
                foreach (TableLock tableLock in ServerDataModel.TableLocks)
                {
                    tableLock.AcquireWriterLock(CommonTimeout.LockWait);
                }

                // IMPORTANT CONCEPT: These filters are used for security and performance.  They remove elements that a user has
                // no right to view on the local client.  They must also guarantee referential integrity if a record is removed.
                // That is, if you have a filter to remove an element, there must be another filter to guarantee the children of
                // that element are not returned to the client.
                ServerDataModel.Object.UserFilter   = new RowFilterDelegate(FilterObject);
                ServerDataModel.Security.UserFilter = new RowFilterDelegate(FilterSecurity);
                ServerDataModel.Price.UserFilter    = new RowFilterDelegate(FilterPrice);
                ServerDataModel.Currency.UserFilter = new RowFilterDelegate(FilterCurrency);
                ServerDataModel.Debt.UserFilter     = new RowFilterDelegate(FilterDebt);
                ServerDataModel.Equity.UserFilter   = new RowFilterDelegate(FilterEquity);

                // A view is needed for all the tables so we can search the records according to 'age'.  The 'RowVersion' is an
                // indication of the relative age of an record.  When a client requests a refresh of it's data model, we will
                // return any records that are younger than the oldest record on the client.  To find these records efficiently, we
                // need this view on the table.
                foreach (Table table in ServerDataModel.Tables)
                {
                    table.DefaultView.Sort           = "RowVersion DESC";
                    table.DefaultView.RowStateFilter = DataViewRowState.OriginalRows;
                }

                // Open a connection to the server and read all the tables into the data model.
                sqlConnection.Open();

                // Constraints are disabled so the data can be loaded in table-by-table from the persistent store.
                ServerDataModel.EnforceConstraints = false;

                // This will keep track of the largest row number in the persistent data store.  This maximum row version will
                // become the seed value for the system-wide row version that is assigned to every row that is added, updated or
                // deleted.
                long maxRowVersion = 0;

                // Read each of the persistent tables from the relational database store.
                foreach (Table table in ServerDataModel.Tables)
                {
                    if (table.IsPersistent)
                    {
                        // Every record has an 'Archived' bit which indicates whether the record has been deleted from the active
                        // database.  This bit is used here to discard records that shouldn't be included in the active database.
                        // While it would be possible to simply select all the records where the 'Archived' bit is clear, they are
                        // added to the table and then deleted in order to keep the identity columns of the ADO tables synchronized
                        // with the indices of the persistent SQL tables.  This section of code will construct a statement that
                        // will select all the persistent columns from the relational database.
                        string columnList = "IsArchived, IsDeleted";
                        foreach (Column column in table.Columns)
                        {
                            if (column.IsPersistent)
                            {
                                columnList += (columnList == string.Empty ? string.Empty : ", ") + "\"" + column.ColumnName + "\"";
                            }
                        }
                        string selectCommand = String.Format("select {0} from \"{1}\"", columnList, table.TableName);

                        // Execute the command to read the table.
                        SqlCommand sqlCommand = new SqlCommand(selectCommand);
                        sqlCommand.Connection = sqlConnection;
                        SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();

                        // IMPORTANT CONCEPT:  The persistent database can store many deleted and archived rows.  To minimize the
                        // amount of memory needed to read these tables, the rows are reused as they are read when the row has been
                        // deleted or archived.  Active rows will be added to the data model and a new row will be created the next
                        // time a row from that table is read.
                        Row row = null;

                        // Read each record from the table into the ADO database.
                        while (sqlDataReader.Read())
                        {
                            // Create a new record (unless the row is being reused because it was deleted or archived).
                            if (row == null)
                            {
                                row = (Row)table.NewRow();
                            }

                            // Read all records from the database, throw away the ones that are archived.  This will keep the
                            // identity columns in the ADO database from repeating any of the key elements in the SQL database.
                            bool isArchived = false;
                            bool isDeleted  = false;
                            for (int column = 0; column < sqlDataReader.FieldCount; column++)
                            {
                                string columnName = sqlDataReader.GetName(column);

                                if (columnName == "IsArchived")
                                {
                                    isArchived = (bool)sqlDataReader.GetValue(column);
                                }
                                if (columnName == "IsDeleted")
                                {
                                    isDeleted = (bool)sqlDataReader.GetValue(column);
                                }

                                DataColumn destinationColumn = table.Columns[columnName];
                                if (destinationColumn != null)
                                {
                                    row[destinationColumn] = sqlDataReader.GetValue(column);
                                }
                            }

                            // IMPORTANT CONCEPT: The initial system-wide row version used by the in-memory data model to keep
                            // track of the age of a record will be the maximum row version read from the persistent store
                            // (including deleted and archived rows).
                            maxRowVersion = row.RowVersion > maxRowVersion ? row.RowVersion : maxRowVersion;

                            // Add active rows to the ADO table, reuse deleted and archived rows for the next record read.
                            if (!isArchived && !isDeleted)
                            {
                                table.Rows.Add(row);
                                row = null;
                            }
                        }

                        // This is the end of reading a table.  Close out the reader, accept the changes and move on to the next
                        // table in the DataSet.
                        sqlDataReader.Close();
                        table.AcceptChanges();
                    }
                }

                // This is the row version that will be used for all inserted, modified and deleted records.
                rowVersion.Set(maxRowVersion);

                // Once all the tables have been read, the constraints can be enforced again.  This is where any Relational
                // Integrity problems will kick out.
                ServerDataModel.EnforceConstraints = true;

                // These masks are used to dynamically filter the data that is returned to the client.
                ServerDataModel.masks     = new Hashtable();
                ServerDataModel.maskLocks = new Hashtable();
                ServerDataModel.maskLock  = new TableLock("Mask.Master");

                // Run through each of the users and create a mask for their pricing data.
                foreach (ServerDataModel.UserRow userRow in ServerDataModel.User.Rows)
                {
                    // UserRow.UserName must match MarkThree.Quasar.Server.Environment.UserName which is always lower case.
                    string  maskName = string.Format("Mask.{0}", userRow.UserName.ToLower());
                    DataSet maskSet  = new DataSet(maskName);
                    ServerDataModel.masks[userRow.UserName.ToLower()]     = maskSet;
                    ServerDataModel.maskLocks[userRow.UserName.ToLower()] = new TableLock(maskName);

                    // The mask has a single table with the security identifier in it.  Any price that matches the security
                    // identifier is returned to the client.
                    DataTable  priceTable       = maskSet.Tables.Add("Price");
                    DataColumn securityIdColumn = priceTable.Columns.Add("SecurityId", typeof(int));
                    priceTable.PrimaryKey = new DataColumn[] { securityIdColumn };
                }
            }
            catch (ConstraintException constraintException)
            {
                // Write out the exact location of the error.
                foreach (DataTable dataTable in ServerDataModel.Tables)
                {
                    foreach (DataRow dataRow in dataTable.Rows)
                    {
                        if (dataRow.HasErrors)
                        {
                            EventLog.Error("Error in '{0}': {1}", dataRow.Table.TableName, dataRow.RowError);
                        }
                    }
                }

                // Rethrow the exception.
                throw constraintException;
            }
            catch (SqlException sqlException)
            {
                // Write out the exact location of the error.
                foreach (SqlError sqlError in sqlException.Errors)
                {
                    EventLog.Error(sqlError.Message);
                }

                // Rethrow the exception.
                throw sqlException;
            }
            finally
            {
                // Release all of the write locks.
                foreach (TableLock tableLock in ServerDataModel.TableLocks)
                {
                    if (tableLock.IsWriterLockHeld)
                    {
                        tableLock.ReleaseWriterLock();
                    }
                }

                // Make sure the sqlConnection is closed, even when an exception happens.
                sqlConnection.Close();
            }
        }
Example #12
0
 /// <summary>
 /// Serializa o objeto.
 /// </summary>
 /// <param name="writer"></param>
 public void Serialize(Serialization.IO.CompactWriter writer)
 {
     writer.Write(ActionId);
     writer.Write((int)Type);
     writer.Write(EntityFullName);
     writer.Write(ProviderName);
     writer.Write((RowVersion.HasValue) ? RowVersion.ToString() : "");
     if (Parameters != null)
     {
         writer.Write(Parameters.Count);
         foreach (ICompactSerializable parameter in Parameters)
         {
             parameter.Serialize(writer);
         }
     }
     else
     {
         writer.Write(0);
     }
     if (Conditional != null)
     {
         writer.Write(true);
         ((ICompactSerializable)Conditional).Serialize(writer);
     }
     else
     {
         writer.Write(false);
     }
     writer.Write(AlternativeActions.Count);
     foreach (ICompactSerializable action in AlternativeActions)
     {
         action.Serialize(writer);
     }
     writer.Write(BeforeActions.Count);
     foreach (ICompactSerializable action in BeforeActions)
     {
         action.Serialize(writer);
     }
     writer.Write(AfterActions.Count);
     foreach (ICompactSerializable action in AfterActions)
     {
         action.Serialize(writer);
     }
     if (_storedProcedureName != null)
     {
         writer.Write(true);
         ((ICompactSerializable)_storedProcedureName).Serialize(writer);
     }
     else
     {
         writer.Write(false);
     }
     if (Query != null)
     {
         writer.Write(true);
         ((ICompactSerializable)Query).Serialize(writer);
     }
     else
     {
         writer.Write(false);
     }
 }
Example #13
0
        public void ValidateJHopkinsVersionStrings(string header, RowVersion version)
        {
            var provider = new JHopkinsDataProvider();

            Assert.That(provider.GetVersion(header.SplitCsvRowString().ToArray()), Is.EqualTo(version));
        }
Example #14
0
 /// <inheritdoc />
 public IEnumerable <FieldId> GetFields(RowVersion version)
 {
     return(VersionFieldsDictionary.ContainsKey(version) ? VersionFieldsDictionary[version] : Enumerable.Empty <FieldId>());
 }
        public static EventStreamRow FromRaw(string rawDataString)
        {
            var parsed = JsonConvert.DeserializeObject <List <dynamic> >(rawDataString);

            // Synapse 0.99.4+ sends ["ev", [...]] - the 'ev' represents the kind of event.
            RowKind kind = RowKind.Unknown;

            if (parsed[0] == "ev")
            {
                kind = RowKind.Event;
            }
            if (parsed[0] == "state")
            {
                kind = RowKind.State;
            }

            var        secondArgType = (parsed[1] as object).GetType().FullName;
            RowVersion version       = secondArgType == typeof(JArray).FullName ? RowVersion.Post0994 : RowVersion.Pre0994;

            // We have to convert the JArray to something useful
            var rowData = version == RowVersion.Post0994 ? ((JArray)parsed[1]).ToObject <List <dynamic> >() : new List <dynamic>();

            string relatesToEventId = null;

            if (rowData.Count >= 6)
            {
                version          = RowVersion.Post0995;
                relatesToEventId = rowData[5];
            }

            switch (kind)
            {
            case RowKind.Event:
                return(new EventStreamRow
                {
                    Kind = kind,
                    SynapseVersion = version,
                    EventId = rowData[0],
                    RoomId = rowData[1],
                    EventType = rowData[2],
                    StateKey = rowData[3],
                    RedactsEventId = rowData[4],
                    RelatesToEventId = relatesToEventId,
                });

            case RowKind.State:
                return(new EventStreamRow
                {
                    Kind = kind,
                    SynapseVersion = version,
                    RoomId = rowData[0],
                    EventType = rowData[1],
                    StateKey = rowData[2],
                    EventId = rowData[3],
                });

            default:
                if (version == RowVersion.Pre0994)
                {
                    return(new EventStreamRow
                    {
                        Kind = kind,
                        SynapseVersion = version,
                        EventId = parsed[0],
                        RoomId = parsed[1],
                        EventType = parsed[2],
                        StateKey = parsed[3],
                        RedactsEventId = parsed[4],
                        RelatesToEventId = relatesToEventId,
                    });
                }
                else
                {
                    return(new EventStreamRow {
                        Kind = kind, SynapseVersion = version
                    });
                }
            }
        }
Example #16
0
 /// <summary>
 /// Helper function that returns a <see cref="string"/> representation of given <see cref="FieldId"/> in the particular <see cref="RowVersion"/>.
 /// </summary>
 /// <param name="field">Field to convert to string.</param>
 /// <param name="version"><see cref="RowVersion"/> to where this field come from.</param>
 /// <returns>A <see cref="string"/> representation of given <see cref="FieldId"/>.</returns>
 protected abstract string FieldToString(FieldId field, RowVersion version);
Example #17
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Row"/> class.
 /// </summary>
 /// <param name="fields"><see cref="Field"/> collection to store in row.</param>
 /// <param name="version">Row version.</param>
 public Row(IEnumerable <Field> fields, RowVersion version)
 {
     Version = version;
     _data   = fields.ToDictionary(_ => _.Id, _ => _.Value);
 }
Example #18
0
        public void JHopkinsDataProviderDoesntFailOnGetFields([Values] RowVersion version)
        {
            var provider = new JHopkinsDataProvider();

            Assert.DoesNotThrow(() => { provider.GetFields(version); });
        }
Example #19
0
 internal static string SetParameterValue(this RowVersion value) => $"{((ulong)value).GetBytes().ToHexString()}";
        public void Hook(IPipelines p)
        {
            // Use Pipeline Hook so that we can get information about the requests before performing action
            // with the data

            p.AfterRequest.AddItemToStartOfPipeline((ctx) =>
            {
                if (_Events == null)
                {
                    return;
                }

                var siteconfig = ctx.Items["CurrentSite"] as JObject;
                var user       = ctx.CurrentUser as NcbUser;
                // this will not work when more than one person updating the site at the same time

                var events = _Events.ToList();
                _Events    = null;

                if (siteconfig.Property("watcher") == null)
                {
                    return; // not configured
                }

                var watcher = siteconfig.Property("watcher").Value as JObject;
                var userIP  = ctx.Request.UserHostAddress;

                Task.Run(() =>
                {
                    foreach (var item in events)
                    {
                        var datatype = watcher.Property(item.DataTypeName.ToLowerInvariant());
                        if (datatype == null)
                        {
                            continue;
                        }

                        var config = datatype.Value.ToObject <WatcherConfig>();

                        if (item.Action == "newAttachments")
                        {
                            if (config.autoPrintAttachment == true)
                            {
                                new DataWatcherHub().PrintDocument(item.AffectedRow);
                            }

                            continue;
                        }

                        if (config.version == true)
                        {
                            var version = new RowVersion()
                            {
                                Action          = item.Action,
                                RowData         = item.AffectedRow,
                                UserId          = user.Id,
                                UserHostAddress = userIP,
                                __createdAt     = DateTime.Now,
                                RowId           = (int)item.AffectedRow.Id,
                                DataType        = item.DataTypeName
                            };

                            item.Database.UpsertRecord(version);
                        }

                        var emailConfig = config[item.Action];
                        if (emailConfig != null)
                        {
                            var autoGenPdfConfig = emailConfig.autoGeneratePDF;
                            if (autoGenPdfConfig != null && autoGenPdfConfig.enable == true)
                            {
                                Object dataToClient = new
                                {
                                    config = autoGenPdfConfig,
                                    data   = item.AffectedRow,
                                };
                                new DataWatcherHub().GenPDFandUpload(dataToClient);
                            }

                            if (emailConfig.enable)
                            {
                                var subject = Razor.Parse <DatabaseEvent>(emailConfig.emailSubject, item);
                                var body    = Razor.Parse <DatabaseEvent>(emailConfig.emailTemplate, item);

                                MailSenderModule.SendEmail(emailConfig.sendTo, subject, body);
                            }
                        }
                    }
                });
            });
        }
Example #21
0
 void System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
 {
     writer.WriteAttributeString("ActionId", ActionId.ToString());
     writer.WriteAttributeString("Success", Success.ToString());
     writer.WriteAttributeString("AffectedRows", AffectedRows.ToString());
     writer.WriteAttributeString("RowVersion", RowVersion.ToString());
     writer.WriteStartElement("FailureMessage");
     if (!string.IsNullOrEmpty(FailureMessage))
     {
         writer.WriteValue(FailureMessage);
     }
     writer.WriteEndElement();
     writer.WriteStartElement("Result");
     if (Result != null)
     {
         writer.WriteValue(Result);
     }
     writer.WriteEndElement();
     writer.WriteStartElement("Parameters", Namespaces.Data);
     if (Parameters != null)
     {
         foreach (System.Xml.Serialization.IXmlSerializable parameter in Parameters)
         {
             writer.WriteStartElement("Parameter", Namespaces.Data);
             if (parameter != null)
             {
                 parameter.WriteXml(writer);
             }
             writer.WriteEndElement();
         }
     }
     writer.WriteEndElement();
     writer.WriteStartElement("AlternativeActions", Namespaces.Data);
     foreach (System.Xml.Serialization.IXmlSerializable parameter in AlternativeActions)
     {
         writer.WriteStartElement("PersistenceActionResult", Namespaces.Data);
         if (parameter != null)
         {
             parameter.WriteXml(writer);
         }
         writer.WriteEndElement();
     }
     writer.WriteEndElement();
     writer.WriteStartElement("BeforeActions", Namespaces.Data);
     foreach (System.Xml.Serialization.IXmlSerializable parameter in BeforeActions)
     {
         writer.WriteStartElement("PersistenceActionResult", Namespaces.Data);
         if (parameter != null)
         {
             parameter.WriteXml(writer);
         }
         writer.WriteEndElement();
     }
     writer.WriteEndElement();
     writer.WriteStartElement("AfterActions", Namespaces.Data);
     foreach (System.Xml.Serialization.IXmlSerializable parameter in AfterActions)
     {
         writer.WriteStartElement("PersistenceActionResult", Namespaces.Data);
         if (parameter != null)
         {
             parameter.WriteXml(writer);
         }
         writer.WriteEndElement();
     }
     writer.WriteEndElement();
 }