示例#1
0
        /// <summary>
        /// <para>Compare two dictionaries (of the same types) and creates SQL inserts
        ///  or updates accordingly.</para>
        /// <remarks>Second dictionary can be null (only inserts queries will be produced)</remarks>
        /// <remarks>Use DBTableName and DBFieldName attributes to specify table and field names, in TK</remarks>
        /// </summary>
        /// <typeparam name="T">Type of the primary key (uint)</typeparam>
        /// <param name="storeList">Dictionary retrieved from  parser</param>
        /// <param name="dbList">Dictionary retrieved from  DB</param>
        /// <param name="commentSetter"></param>
        /// <returns>A string containing full SQL queries</returns>
        public static string Compare <T>(IEnumerable <Tuple <T, TimeSpan?> > storeList, RowList <T> dbList, Func <T, string> commentSetter)
            where T : IDataModel, new()
        {
            if (!IsTableVisible <T>())
            {
                return(string.Empty);
            }

            var fields = GetFields <T>();

            if (fields == null)
            {
                return(string.Empty);
            }

            var rowsIns       = new RowList <T>();
            var rowsUpd       = new Dictionary <Row <T>, RowList <T> >();
            var verBuildField = fields.FirstOrDefault(f => f.Item2.Name == "VerifiedBuild");

            foreach (var elem1 in storeList)
            {
                if (dbList != null && dbList.ContainsKey(elem1.Item1) && !Settings.ForceInsertQueries) // update
                {
                    if (verBuildField != null)
                    {
                        var buildvSniff = (int)verBuildField.Item2.GetValue(elem1.Item1);
                        var buildvDB    = (int)verBuildField.Item2.GetValue(dbList[elem1.Item1].Data);

                        if (buildvDB > buildvSniff) // skip update if DB already has a VerifiedBuild higher than this one
                        {
                            continue;
                        }
                    }

                    var row              = new Row <T>();
                    var elem2            = dbList[elem1.Item1].Data;
                    var fieldUpdateCount = 0;
                    var comment          = commentSetter(elem1.Item1);
                    var differingValues  = new T(); // we are creating a new object here to always have the same values for non db fields

                    foreach (var field in fields)
                    {
                        var val1   = field.Item2.GetValue(elem1.Item1);
                        var val2   = field.Item2.GetValue(elem2);
                        var attrib = field.Item3.First();

                        var arr1 = val1 as Array;
                        if (arr1 != null)
                        {
                            var  arr2        = (Array)val2;
                            bool arraysEqual = true;
                            var  arrayLength = Math.Min(Math.Min(attrib.Count, arr1.Length), arr2.Length);
                            for (var i = 0; i < arrayLength; ++i)
                            {
                                var value1 = arr1.GetValue(i);
                                var value2 = arr2.GetValue(i);

                                if (Utilities.EqualValues(value1, value2))
                                {
                                    arr1.SetValue(null, i);
                                }
                                else
                                {
                                    arraysEqual = false;
                                    fieldUpdateCount++;
                                }
                            }

                            if (!arraysEqual)
                            {
                                field.Item2.SetValue(differingValues, arr1);
                            }
                            else
                            {
                                field.Item2.SetValue(differingValues, null); // make sure to null default values
                            }
                            continue;
                        }

                        if (!IsFieldEqual(val1, val2, attrib))
                        {
                            fieldUpdateCount++;
                            field.Item2.SetValue(differingValues, val1);
                        }
                        else
                        {
                            field.Item2.SetValue(differingValues, null); // make sure to null default values
                        }
                    }

                    // no updates required, skip
                    if (fieldUpdateCount == 0)
                    {
                        continue;
                    }

                    // only set comment for rows which arent updating VerifiedBuild only
                    if (fieldUpdateCount != 1 || verBuildField == null || verBuildField.Item2.GetValue(elem1.Item1) == null)
                    {
                        row.Comment = comment;
                    }

                    row.Data = differingValues;
                    if (rowsUpd.TryGetValue(row, out var conditions))
                    {
                        conditions.Add(elem2);
                        continue;
                    }
                    rowsUpd.Add(row, new RowList <T>().Add(elem2));
                }
                else // insert new
                {
                    var row = new Row <T>
                    {
                        Comment = commentSetter(elem1.Item1),
                        Data    = elem1.Item1
                    };

                    rowsIns.Add(row);
                }
            }

            return(new SQLInsert <T>(rowsIns).Build() + Environment.NewLine +
                   new SQLUpdate <T>(rowsUpd).Build());
        }
示例#2
0
 public SQLInsertRow(Row <T> row)
 {
     _row = row;
 }
示例#3
0
 public Row <T> this[Row <T> key] => this[key.Data];
示例#4
0
 public SQLUpdateRow(Row <T> value, RowList <T> conditions)
 {
     _value      = value;
     WhereClause = new SQLWhere <T>(conditions, true);
 }
示例#5
0
 public bool ContainsKey(Row <T> key)
 {
     return(ContainsKey(key.Data));
 }