Exemplo n.º 1
0
        /// <summary>
        /// Обновляет кросс-таблицы для массивных свойств (collection, collection-membership, array)
        /// </summary>
        /// <param name="xs">Реализация XStorageConnection</param>
        /// <param name="datagram">датаграмма</param>
        protected void updateCrossTables(XStorageConnection xs, XDatagram datagram)
        {
            XDbStatementDispatcher disp = xs.CreateStatementDispatcher();

            foreach (XStorageObjectToSave xobj in datagram.ObjectsToInsert)
            {
                updateCrossTablesForObject(xs, disp, xobj);
            }
            foreach (XStorageObjectToSave xobj in datagram.ObjectsToUpdate)
            {
                updateCrossTablesForObject(xs, disp, xobj);
            }
            disp.ExecutePendingStatementsAndReturnTotalRowsAffected();
        }
Exemplo n.º 2
0
        /// <summary>
        /// Выполняет удаление в БД объектов в списке в порядке их следования в нем
        /// </summary>
        /// <param name="xs">Экземпляр XStorageConection</param>
        /// <param name="disp">Диспетчер запросов</param>
        /// <param name="aDelObjects">список объектов (типа ObjectToDelete), для которых надо выполнить delete в БД</param>
        protected virtual int doDelete(XStorageConnection xs, XDbStatementDispatcher disp, ICollection aDelObjects)
        {
            int           nRowsAffected    = 0;                         // количество удаленных записей
            bool          bForcedMode      = false;                     // признак форсированного удаления (есть хотя бы один объект с незаданным ts)
            string        sTypeNamePrev    = String.Empty;              // наименование типа предыдущего объекта (в цикле)
            StringBuilder queryTextBuilder = new StringBuilder();       // построитель оператора delete


            if (aDelObjects.Count == 0)
            {
                return(0);
            }
            foreach (XStorageObjectToDelete obj in aDelObjects)
            {
                if (obj.TS == -1)
                {
                    bForcedMode = true;
                }
                if (sTypeNamePrev != obj.ObjectType)
                {
                    // объект нового типа (в т.ч. первый)
                    if (queryTextBuilder.Length > 0)
                    {
                        disp.DispatchStatement(queryTextBuilder.ToString(), true);
                        queryTextBuilder.Length = 0;
                    }
                    queryTextBuilder.AppendFormat("DELETE FROM {0} WHERE {1}={2}",
                                                  xs.GetTableQName(obj.TypeInfo),       // 0
                                                  xs.ArrangeSqlName("ObjectID"),        // 1
                                                  xs.ArrangeSqlGuid(obj.ObjectID)       // 2
                                                  );
                    // если для объекта задан TS, добавим условие на него
                    if (obj.AnalyzeTS)
                    {
                        queryTextBuilder.AppendFormat(" AND {0}={1}",
                                                      xs.ArrangeSqlName("ts"),
                                                      obj.TS
                                                      );
                    }
                }
                else
                {
                    // еще один объект того же типа
                    queryTextBuilder.AppendFormat(" OR {0}={1}",
                                                  xs.ArrangeSqlName("ObjectID"),        // 0
                                                  xs.ArrangeSqlGuid(obj.ObjectID)       // 1
                                                  );
                    // если для объекта задан TS, добавим условие на него
                    if (obj.AnalyzeTS)
                    {
                        queryTextBuilder.AppendFormat(" AND {0}={1}",
                                                      xs.ArrangeSqlName("ts"),
                                                      obj.TS
                                                      );
                    }
                }
                sTypeNamePrev = obj.ObjectType;
            }
            if (queryTextBuilder.Length > 0)
            {
                disp.DispatchStatement(queryTextBuilder.ToString(), true);
            }

            nRowsAffected = disp.ExecutePendingStatementsAndReturnTotalRowsAffected();

            if (!bForcedMode)
            {
                if (nRowsAffected != aDelObjects.Count)
                {
                    // количество удаленных объектов не совпадает с ожидаемым кол-вом.
                    // если в БД остался хотя бы один объект из тех, которые мы удалили, то
                    // это означает, что у него "устарел" ts, следовательно будем ругаться.
                    // Иначе (в БД нет ниодного объект из тех, которые мы удаляли) все хорошо, просто
                    // нас кто-то опередил, но главное результат - все требуемые объекты удалены.
                    sTypeNamePrev    = String.Empty;
                    queryTextBuilder = new StringBuilder();
                    XDbCommand cmd = xs.CreateCommand();
                    cmd.CommandType = CommandType.Text;
                    foreach (XStorageObjectToDelete obj in aDelObjects)
                    {
                        if (sTypeNamePrev != obj.ObjectType)
                        {
                            // объект нового типа (в т.ч. первый)
                            if (queryTextBuilder.Length > 0)
                            {
                                cmd.CommandText = queryTextBuilder.ToString();
                                if (Convert.ToInt32(cmd.ExecuteScalar()) > 0)
                                {
                                    throw new XOutdatedTimestampException();
                                }
                                queryTextBuilder.Length = 0;
                            }
                            queryTextBuilder.AppendFormat("SELECT COUNT(1) FROM {0} WHERE {1}={2}",
                                                          xs.GetTableQName(obj.TypeInfo),               // 0
                                                          xs.ArrangeSqlName("ObjectID"),                // 1
                                                          xs.ArrangeSqlGuid(obj.ObjectID)               // 2
                                                          );
                        }
                        else
                        {
                            // еще один объект того же типа
                            queryTextBuilder.AppendFormat(" OR {0}={1}",
                                                          xs.ArrangeSqlName("ObjectID"),                // 0
                                                          xs.ArrangeSqlGuid(obj.ObjectID)               // 1
                                                          );
                        }
                        sTypeNamePrev = obj.ObjectType;
                    }
                    cmd.CommandText = queryTextBuilder.ToString();
                    if (Convert.ToInt32(cmd.ExecuteScalar()) > 0)
                    {
                        throw new XOutdatedTimestampException();
                    }
                }
            }

            return(nRowsAffected);
        }