예제 #1
0
        private TableRow CheckAndGetEntity(ChangeDescription changeDescription, bool shouldExist)
        {
            UtilityRow utilityRow = this.ExecuteQuery <UtilityRow>(changeDescription);

            this.CheckPermissions(utilityRow, changeDescription);
            PointQueryTracker pointQuery = ((DbTableRowQueryProvider <UtilityRow>)changeDescription.QueryableRow.Provider).PointQuery;

            if (pointQuery != null)
            {
                this.CheckPartitionAndRowKeys(pointQuery.PartitionKey, pointQuery.RowKey, changeDescription.UpdateType);
            }
            if (utilityRow == null)
            {
                if (shouldExist)
                {
                    throw new TableServiceGeneralException(TableServiceError.EntityNotFound, null);
                }
                return(null);
            }
            changeDescription.ExistingRow = utilityRow;
            TableRow sqlEntity = this.GetSqlEntity(utilityRow.PartitionKey, utilityRow.RowKey, changeDescription.EtagConditionUsed);

            if (sqlEntity == null)
            {
                throw new TableServiceGeneralException(TableServiceError.UpdateConditionNotSatisfied, null);
            }
            return(sqlEntity);
        }
예제 #2
0
        public void SetConcurrencyValues(object resourceCookie, bool?checkForEquality, IEnumerable <KeyValuePair <string, object> > concurrencyValues)
        {
            ChangeDescription changeDescription = (ChangeDescription)resourceCookie;

            if (!checkForEquality.HasValue)
            {
                changeDescription.IfMatchHeaderMissing = true;
                changeDescription.UpdateType           = UpdateKind.InsertOrMerge;
                return;
            }
            changeDescription.IfMatchHeaderMissing = false;
            int      num      = 0;
            DateTime?nullable = null;

            foreach (KeyValuePair <string, object> concurrencyValue in concurrencyValues)
            {
                int num1 = num + 1;
                num = num1;
                if (num1 > 1)
                {
                    throw new XStoreArgumentException("Only a single concurrencyValue is supported.");
                }
                if (!string.Equals(concurrencyValue.Key, "Timestamp"))
                {
                    throw new XStoreArgumentException(string.Format("Unknown ConcurrencyValue '{0}'. Only Etag checks are supported.", concurrencyValue.Key));
                }
                nullable = new DateTime?((DateTime)concurrencyValue.Value);
            }
            changeDescription.EtagConditionUsed = nullable;
        }
예제 #3
0
        private void SetValuesInResponseIfRequired(ChangeDescription changeDescription)
        {
            TableRow sqlEntity = null;

            switch (changeDescription.UpdateType)
            {
            case UpdateKind.Insert:
            case UpdateKind.Replace:
            case UpdateKind.Merge:
            case UpdateKind.InsertOrMerge:
            case UpdateKind.InsertOrReplace:
            {
                string str = (changeDescription.ExistingRow != null ? changeDescription.ExistingRow.PartitionKey : ((UtilityRow)changeDescription.Row).PartitionKey);
                sqlEntity = this.GetSqlEntity(str, (changeDescription.ExistingRow != null ? changeDescription.ExistingRow.RowKey : ((UtilityRow)changeDescription.Row).RowKey), null);
                ((UtilityRow)changeDescription.Row).Timestamp = sqlEntity.Timestamp;
                return;
            }

            case UpdateKind.Delete:
            {
                return;
            }

            default:
            {
                return;
            }
            }
        }
예제 #4
0
        public void SetValue(object targetResource, string propertyName, object propertyValue)
        {
            object obj;

            try
            {
                ChangeDescription changeDescription = (ChangeDescription)targetResource;
                if (!TableResourceContainer.IsUtilityTables(this.m_currentResourceContainer.Name))
                {
                    UtilityRow row = (UtilityRow)changeDescription.Row;
                    if (!propertyName.Equals("Timestamp"))
                    {
                        if (changeDescription.UpdateType != UpdateKind.Insert && changeDescription.UpdateType != UpdateKind.InsertOrMerge && changeDescription.UpdateType != UpdateKind.InsertOrReplace && (propertyName.Equals("PartitionKey") || propertyName.Equals("RowKey")))
                        {
                            throw new InvalidOperationException("Cannot update key values.");
                        }
                        if (!TableDataContextHelper.IsValidPropertyName(propertyName, this.ApiVersion))
                        {
                            throw new TableServiceGeneralException(TableServiceError.PropertyNameInvalid, null);
                        }
                        if (row.ColumnValues.TryGetValue(propertyName, out obj) && obj != null)
                        {
                            throw new XStoreArgumentException("Multiple entries for same property specified in the input");
                        }
                        row[propertyName] = propertyValue;
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    UtilityTable utilityTable = (UtilityTable)changeDescription.Row;
                    if (changeDescription.UpdateType == UpdateKind.Insert)
                    {
                        utilityTable[propertyName] = propertyValue;
                        if (string.Equals(propertyName, "TableName"))
                        {
                            if (TableResourceContainer.IsUtilityTables(propertyValue as string))
                            {
                                throw new TableServiceArgumentException("Invalid table container name");
                            }
                            if (!Regex.IsMatch(propertyValue as string, "^[A-Za-z][A-Za-z0-9]{2,62}$"))
                            {
                                throw new InvalidResourceNameException("Invalid table name");
                            }
                        }
                    }
                }
            }
            catch (InvalidCastException invalidCastException1)
            {
                InvalidCastException invalidCastException = invalidCastException1;
                CultureInfo          invariantCulture     = CultureInfo.InvariantCulture;
                object[]             objArray             = new object[] { propertyName };
                throw new XStoreArgumentException(string.Format(invariantCulture, "Invalid data type for property {0}", objArray), invalidCastException);
            }
        }
예제 #5
0
        public object ResolveResource(object resource)
        {
            ChangeDescription changeDescription = (ChangeDescription)resource;

            if (TableResourceContainer.IsUtilityTables(this.m_currentResourceContainer.Name))
            {
                return((UtilityTable)changeDescription.Row);
            }
            return((UtilityRow)changeDescription.Row);
        }
예제 #6
0
        public object GetValue(object targetResource, string propertyName)
        {
            ChangeDescription changeDescription = (ChangeDescription)targetResource;

            if (TableResourceContainer.IsUtilityTables(this.m_currentResourceContainer.Name))
            {
                return(((UtilityTable)changeDescription.Row)[propertyName]);
            }
            return(((UtilityRow)changeDescription.Row)[propertyName]);
        }
예제 #7
0
        public object ResetResource(object resource)
        {
            ChangeDescription changeDescription = (ChangeDescription)resource;

            if (changeDescription.UpdateType == UpdateKind.Merge)
            {
                changeDescription.UpdateType = UpdateKind.Replace;
            }
            else if (changeDescription.UpdateType == UpdateKind.InsertOrMerge)
            {
                changeDescription.UpdateType = UpdateKind.InsertOrReplace;
            }
            return(resource);
        }
예제 #8
0
        private T ExecuteQuery <T>(ChangeDescription changeDescription)
        {
            ((DbTableRowQueryProvider <T>)changeDescription.QueryableRow.Provider).CheckForReadPermission = false;
            DbTableRowQueryProvider <T> provider   = (DbTableRowQueryProvider <T>)changeDescription.QueryableRow.Provider;
            IEnumerator <T>             enumerator = provider.Execute <IEnumerator <T> >(changeDescription.QueryableRow.Expression);

            if (!enumerator.MoveNext())
            {
                return(default(T));
            }
            T current = enumerator.Current;

            if (enumerator.MoveNext())
            {
                throw new DataServiceException(400, "Multiple objects match the query");
            }
            return(current);
        }
예제 #9
0
        public object CreateResource(string containerName, string fullTypeName)
        {
            ChangeDescription changeDescription = new ChangeDescription(this.AccountName, containerName)
            {
                UpdateType = UpdateKind.Insert
            };

            if (!TableResourceContainer.IsUtilityTables(containerName))
            {
                changeDescription.Row = new UtilityRow();
            }
            else
            {
                changeDescription.Row = new UtilityTable();
            }
            this.changeDescriptionList.Add(changeDescription);
            return(changeDescription);
        }
예제 #10
0
        private void CheckPermissions(UtilityRow existingRow, ChangeDescription changeDescription)
        {
            string partitionKey = null;
            string rowKey       = null;

            if (existingRow != null)
            {
                partitionKey = existingRow.PartitionKey;
                rowKey       = existingRow.RowKey;
            }
            else
            {
                partitionKey = ((UtilityRow)changeDescription.Row).PartitionKey;
                rowKey       = ((UtilityRow)changeDescription.Row).RowKey;
            }
            this.CheckPermission(this.m_currentResourceContainer.Name, false, false, changeDescription.UpdateType);
            XfeTableSASAuthorizationManager.CheckSignedAccessKeyBoundary(this.SignedAccountIdentifier, partitionKey, rowKey);
        }
예제 #11
0
        public object GetResource(IQueryable query, string fullTypeName)
        {
            ChangeDescription changeDescription = null;

            changeDescription = new ChangeDescription(this.AccountName, this.m_currentResourceContainer.Name)
            {
                UpdateType = UpdateKind.Merge
            };
            if (!TableResourceContainer.IsUtilityTables(this.m_currentResourceContainer.Name))
            {
                changeDescription.Row = new UtilityRow();
            }
            else
            {
                changeDescription.Row = new UtilityTable();
            }
            changeDescription.QueryableRow = query;
            this.changeDescriptionList.Add(changeDescription);
            return(changeDescription);
        }
예제 #12
0
        private void SaveTableChanges()
        {
            this.FailedCommandIndex = 0;
            if (this.changeDescriptionList == null || this.changeDescriptionList.Count != 1)
            {
                throw new XStoreArgumentException("Invalid number of table commands. Only a single table command is allowed.");
            }
            ChangeDescription changeDescription = this.changeDescriptionList.FirstOrDefault <ChangeDescription>();

            this.CheckPermission(changeDescription.TableName, true, false, changeDescription.UpdateType);
            if (changeDescription.UpdateType != UpdateKind.Insert)
            {
                if (changeDescription.UpdateType != UpdateKind.Delete)
                {
                    throw new NotSupportedException("Operation is not supported!");
                }
                UtilityTable utilityTable = this.ExecuteQuery <UtilityTable>(changeDescription);
                if (utilityTable == null)
                {
                    throw new DataServiceException(404, "Resource not found.");
                }
                changeDescription.Row = utilityTable;
                Microsoft.WindowsAzure.DevelopmentStorage.Store.TableContainer sqlTableContainer = this.GetSqlTableContainer(((UtilityTable)changeDescription.Row).TableName);
                this.m_dbContext.TableContainers.DeleteOnSubmit(sqlTableContainer);
                this.m_dbContext.SubmitChanges();
                return;
            }
            Microsoft.WindowsAzure.DevelopmentStorage.Store.TableContainer tableContainer = new Microsoft.WindowsAzure.DevelopmentStorage.Store.TableContainer()
            {
                AccountName = changeDescription.AccountName
            };
            if (string.IsNullOrEmpty(((UtilityTable)changeDescription.Row).TableName))
            {
                throw new TableServiceGeneralException(TableServiceError.PropertiesNeedValue, null);
            }
            tableContainer.TableName = ((UtilityTable)changeDescription.Row).TableName.ToLowerInvariant();
            tableContainer.CasePreservedTableName = ((UtilityTable)changeDescription.Row).TableName;
            this.m_dbContext.TableContainers.InsertOnSubmit(tableContainer);
            this.m_dbContext.SubmitChanges();
        }
예제 #13
0
        private void AddChangeToMap(string partitionKey, string rowKey, ChangeDescription changeDescription)
        {
            if (partitionKey == null || rowKey == null)
            {
                throw new TableServiceGeneralException(TableServiceError.PropertiesNeedValue, null);
            }
            if (this.batchPK == null)
            {
                this.batchPK = partitionKey;
            }
            else if (!string.Equals(this.batchPK, partitionKey, StringComparison.OrdinalIgnoreCase))
            {
                throw new TableServiceGeneralException(TableServiceError.CommandsInBatchActOnDifferentPartitions, null);
            }
            string key = this.GetKey(partitionKey, rowKey);

            if (this.changeDescriptionMap.ContainsKey(key))
            {
                CultureInfo invariantCulture = CultureInfo.InvariantCulture;
                object[]    objArray         = new object[] { key };
                throw new TableBatchDuplicateRowKeyException(string.Format(invariantCulture, "A command with RowKey '{0}' is already present in the batch. An entity can appear only once in a batch.", objArray));
            }
            this.changeDescriptionMap.Add(key, changeDescription);
        }
예제 #14
0
        private void ProcessChange(ChangeDescription changeDescription)
        {
            TableRow           sqlEntity          = null;
            PointQueryTracker  pointQuery         = null;
            DbTableDataContext failedCommandIndex = this;

            failedCommandIndex.FailedCommandIndex = failedCommandIndex.FailedCommandIndex + 1;
            switch (changeDescription.UpdateType)
            {
            case UpdateKind.Insert:
            {
                this.CheckPermissions(null, changeDescription);
                this.CheckPartitionAndRowKeys(((UtilityRow)changeDescription.Row).PartitionKey, ((UtilityRow)changeDescription.Row).RowKey, changeDescription.UpdateType);
                DateTime?nullable = null;
                sqlEntity = this.GetSqlEntity(((UtilityRow)changeDescription.Row).PartitionKey, ((UtilityRow)changeDescription.Row).RowKey, nullable);
                if (sqlEntity != null)
                {
                    throw new TableServiceGeneralException(TableServiceError.EntityAlreadyExists, null);
                }
                UtilityRow row = (UtilityRow)changeDescription.Row;
                this.AddChangeToMap(DevelopmentStorageDbDataContext.EncodeKeyString(row.PartitionKey), DevelopmentStorageDbDataContext.EncodeKeyString(row.RowKey), changeDescription);
                this.m_dbContext.TableRows.InsertOnSubmit(this.CreateAndPopulateSqlEntity(row));
                return;
            }

            case UpdateKind.Delete:
            {
                if (changeDescription.IfMatchHeaderMissing)
                {
                    throw new XStoreArgumentException("If-Match header is mandatory when deleting an entity.");
                }
                sqlEntity = this.CheckAndGetEntity(changeDescription, true);
                this.AddChangeToMap(sqlEntity.PartitionKey, sqlEntity.RowKey, changeDescription);
                this.m_dbContext.TableRows.DeleteOnSubmit(sqlEntity);
                return;
            }

            case UpdateKind.Replace:
            {
                sqlEntity = this.CheckAndGetEntity(changeDescription, true);
                this.AddChangeToMap(sqlEntity.PartitionKey, sqlEntity.RowKey, changeDescription);
                sqlEntity.Data = XmlUtility.GetXmlFromUtilityRow(changeDescription.Row as UtilityRow);
                return;
            }

            case UpdateKind.Merge:
            {
                sqlEntity = this.CheckAndGetEntity(changeDescription, true);
                this.AddChangeToMap(sqlEntity.PartitionKey, sqlEntity.RowKey, changeDescription);
                sqlEntity.Data = XmlUtility.MergeXmlProperties(changeDescription.Row as UtilityRow, sqlEntity.Data);
                return;
            }

            case UpdateKind.InsertOrMerge:
            {
                this.ExecuteQuery <UtilityRow>(changeDescription);
                pointQuery = ((DbTableRowQueryProvider <UtilityRow>)changeDescription.QueryableRow.Provider).PointQuery;
                if (pointQuery == null)
                {
                    throw new DataServiceException(400, "PK and RK not present in the required format");
                }
                (changeDescription.Row as UtilityRow).PartitionKey = pointQuery.PartitionKey;
                (changeDescription.Row as UtilityRow).RowKey       = pointQuery.RowKey;
                sqlEntity = this.CheckAndGetEntity(changeDescription, false);
                this.AddChangeToMap(DevelopmentStorageDbDataContext.EncodeKeyString(pointQuery.PartitionKey), DevelopmentStorageDbDataContext.EncodeKeyString(pointQuery.RowKey), changeDescription);
                if (sqlEntity != null)
                {
                    sqlEntity.Data = XmlUtility.MergeXmlProperties(changeDescription.Row as UtilityRow, sqlEntity.Data);
                    return;
                }
                this.m_dbContext.TableRows.InsertOnSubmit(this.CreateAndPopulateSqlEntity(changeDescription.Row as UtilityRow));
                return;
            }

            case UpdateKind.InsertOrReplace:
            {
                this.ExecuteQuery <UtilityRow>(changeDescription);
                pointQuery = ((DbTableRowQueryProvider <UtilityRow>)changeDescription.QueryableRow.Provider).PointQuery;
                if (pointQuery == null)
                {
                    throw new DataServiceException(400, "PK and RK not present in the required format");
                }
                (changeDescription.Row as UtilityRow).PartitionKey = pointQuery.PartitionKey;
                (changeDescription.Row as UtilityRow).RowKey       = pointQuery.RowKey;
                sqlEntity = this.CheckAndGetEntity(changeDescription, false);
                this.AddChangeToMap(DevelopmentStorageDbDataContext.EncodeKeyString(pointQuery.PartitionKey), DevelopmentStorageDbDataContext.EncodeKeyString(pointQuery.RowKey), changeDescription);
                if (sqlEntity != null)
                {
                    sqlEntity.Data = XmlUtility.GetXmlFromUtilityRow(changeDescription.Row as UtilityRow);
                    return;
                }
                this.m_dbContext.TableRows.InsertOnSubmit(this.CreateAndPopulateSqlEntity(changeDescription.Row as UtilityRow));
                return;
            }

            default:
            {
                return;
            }
            }
        }