// データ種類の追加
      // POST api/unitadd/{User名}/{Module名}
      public string Post(string fir, string sec, [FromBody]UnitAdd unitadd) {

          var user = RDB.db.Users.Where(p => p.idName.Equals(fir)).Single();
          var module = user.Modules.Where(p => p.Name.Equals(sec)).Single();
          var units = module.Units;

          if (common.PasswordError(unitadd.pw, module.wPassWord)) {
            return "Password Error";
          }

          foreach (var unitlist in unitadd.ul) {

            Unit unit = new Unit();
            string[] unitype = unitlist.Split('|');
            unit.Unit1 = unitype[0];
            unit.TypeDataId = int.Parse(unitype[1]);
            unit.Modules.Add(module);
            RDB.db.Units.Add(unit);

            RDB.db.SaveChanges();

          }

          return "Success!";

        }
        // データ種類の設定(新規作成)
        // POST api/unitnew/{User名}/{Module名}
        public string Post(string fir, string sec, [FromBody]UnitAdd unitadd) {

            var user = RDB.db.Users.Where(p => p.idName.Equals(fir)).Single();
            var module = user.Modules.Where(p => p.Name.Equals(sec)).Single();
            var units = module.Units;

            if (common.PasswordError(unitadd.pw, module.wPassWord)) {
                return "Password Error";
            }

            // 既に設定されているデータ種類は、全部削除
            while (!(units.FirstOrDefault() == null)) {
                units.Remove(units.FirstOrDefault());
                //RDB.db.DeleteObject(units.FirstOrDefault());
                RDB.db.SaveChanges();
            }

            foreach (var unitlist in unitadd.ul) {
                Unit unit = new Unit();
                string[] unitype = unitlist.Split('|');
                unit.Unit1 = unitype[0];
                unit.TypeDataId = int.Parse(unitype[1]);
                unit.Modules.Add(module);
                RDB.db.Units.Add(unit);
                RDB.db.SaveChanges();
            }

            return "Success!";

        }
        // Azure Tableへアップロードされたデータを格納
        // POST api/dataadd/{UserID名}/{Module名}
        public string Post(string fir, string sec, [FromBody]List<DataAdd> dataaddList) {

            //string json = new JavaScriptSerializer().Serialize(dataaddList);
            //return json;
            if (dataaddList == null) {
                return "JSONの書式が間違っています。";
            } else if (dataaddList[0].dat == null) {
                return "データがnullです。";
            } else if (dataaddList.Count > 1) {
                foreach (DataAdd dataadd in dataaddList) {
                    if (dataadd.dt == null) {
                        return "2行以上のデータを送信する場合は、更新時刻データが必須です。";
                    }
                }
            }

            // RDBの中から、ターゲットモジュールなどを検索
            var user = RDB.db.Users.Where(p => p.idName.Equals(fir)).Single();
            var module = user.Modules.Where(p => p.Name.Equals(sec)).Single();
            var units = module.Units;

            // パスワードチェック(ハッシュ関数込み)
            try {
                if (!(module.wPassWord == null)) {
                    // データ追加時は、Hash関数で暗号化されたパスワードを使う
                    string HashPW = common.GetHashPassword(dataaddList[0].dt, sec, module.wPassWord);
                    try {
                        if (!(dataaddList[0].pw.Equals(HashPW))) {
                            return "PassWord error";
                        }
                    } catch {
                        return "You need to password";
                    }
                }
            } catch {
                return "PassWord Check Error";
            }

            try {
                table = common.AzureAccess(); // Azure Tableへアクセス
            } catch {
                return "Azure Access Error";
            }

            // batchを使って、まとめてデータを格納する
            List<TableBatchOperation> batchOperationTakeList = new List<TableBatchOperation>();
            List<TableBatchOperation> batchOperationValueList = new List<TableBatchOperation>();
            TableBatchOperation batchOperationTake = new TableBatchOperation();
            TableBatchOperation batchOperationValue = new TableBatchOperation();

            string date = "";
            int num1 = 0;

            Marimo marimo = new Marimo();

            // 入力されたコードの「改行」はまりもコードコンパイラの中では"|"として扱う
            // 「置換の際にエラーが起きる」=「まりもコードは入力されていないので実行する必要なし」
            bool Flag_MarimoCode = true;
            try {
                string codelists = module.Code.Replace(Environment.NewLine, "|");
                string[] codelist = codelists.Split('|');
                marimo.codelist = codelist;
            } catch {
                Flag_MarimoCode = false;
            }

            // データ格納中の場合はModuleテーブルのTypeプロパティを"2"にする
            module.Type = "2";
            RDB.db.SaveChanges();

            try {

                foreach (DataAdd dataadd in dataaddList) {

                    // 送られてくる行データ毎にまりもコード実行
                    marimo.dataadd = dataadd;
                    if (Flag_MarimoCode) {
                        marimo.RunMarimo();
                    }

                    // 現在設定されているデータ種類の個数よりもアップロードされたデータの列数が多い場合、RDBにデータ種類を追加する
                    if (marimo.dataadd.dat.Count > units.Count) {
                        int count = marimo.dataadd.dat.Count - units.Count;
                        for (int i = 0; i < count; i++) {
                            Unit unit = new Unit();
                            unit.Unit1 = "";
                            unit.TypeDataId = 10;
                            unit.Modules.Add(module);
                            RDB.db.Units.Add(unit);
                        }
                        RDB.db.SaveChanges();
                        units = module.Units;
                    }

                    if (marimo.dataadd.dt == null) {
                        DateTime now = DateTime.Now;
                        date = now.ToString("yyyyMMdd-HHmmss-ffff");
                    } else {
                        date = marimo.dataadd.dt;
                    }
                    string time = common.GetTimeIndex(date);

                    // 100件ずつまとめてListに追加して、後でListごとまとめて格納する
                    DataEntity customer1 = new DataEntity("Take," + module.id, time);
                    batchOperationTake.Insert(customer1);
                    if (batchOperationTake.Count == 100) {
                        batchOperationTakeList.Add(batchOperationTake);
                        batchOperationTake = new TableBatchOperation();
                    }
                    int num2 = 0;
                    foreach (var unit in units) {
                        if (marimo.dataadd.dat.Count == num2) {
                            break;
                        }
                        DataEntity customer2 = new DataEntity("Value," + module.id, time + "," + unit.id);
                        customer2.DataVal = marimo.dataadd.dat[num2];
                        batchOperationValue.Insert(customer2);
                        if (batchOperationValue.Count == 100) {
                            batchOperationValueList.Add(batchOperationValue);
                            batchOperationValue = new TableBatchOperation();
                        }
                        num2++;
                    }

                    num1++;

                }

                if (batchOperationTake.Count > 0) {
                    batchOperationTakeList.Add(batchOperationTake);
                }
                if (batchOperationValue.Count > 0) {
                    batchOperationValueList.Add(batchOperationValue);
                }

                // 100件ずつまとめられたListを分散処理させながらKVSに格納
                Parallel.ForEach(batchOperationTakeList, Operation => {
                    table.ExecuteBatch(Operation);
                });
                Parallel.ForEach(batchOperationValueList, Operation => {
                    table.ExecuteBatch(Operation);
                });

                if (!date.Equals("")) {
                    module.Latest = date;
                }
                TableQuery<DataEntity> query = new TableQuery<DataEntity>().Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "Take," + module.id));
                module.NumData = table.ExecuteQuery(query).Count();

            } catch {
                module.Type = "0";
                RDB.db.SaveChanges();
                return "Error!";
            }

            // データ格納中以外はModuleテーブルのTypeプロパティは"0"となる
            module.Type = "0";
            RDB.db.SaveChanges();

            return "Success!";
        }
    // Azure Blobにデータを追加
    // POST api/blobadd/{UserID名}/{Module名}
    public string Post(string fir, string sec, [FromBody]BlobAdd blobadd) {

      // RDBの中からターゲットモジュールなどの検索
      var user = RDB.db.Users.Where(p => p.idName.Equals(fir)).Single();
      var module = user.Modules.Where(p => p.Name.Equals(sec)).Single();
      var units = module.Units;

      // パスワードチェック(ハッシュ関数込み)
      if (!(module.wPassWord == null)) {
        string HashPW = common.GetHashPassword(blobadd.dataaddlist[0].dt, sec, module.wPassWord);
        try {
          if (!(blobadd.dataaddlist[0].pw.Equals(HashPW))) {
            return "PassWord error";
          }
        } catch {
          return "You need to password";
        }
      }

      try {

        // データ挿入中はTypeプロパティは"2"
        module.Type = "2";
        RDB.db.SaveChanges();

        // もし、データ種類の設定を事前に行っていなければ、初期設定をする
        if (units.Count == 0) { 
          Unit unit = new Unit();
          unit.Unit1 = "File Name";
          unit.TypeDataId = 12;
          unit.Modules.Add(module);
          RDB.db.SaveChanges();
          units = module.Units;
        }

        string time = common.GetTimeIndex(blobadd.dataaddlist[0].dt);

        // Table内には、モジュールIDとBlobデータ格納時刻とファイル名が入る
        #region Insert AzureTable

        table = common.AzureAccess();

        DataEntity customer1 = new DataEntity("Take," + module.id, time);
        customer1.DataVal = "BlobData";
        TableOperation insertOperationTake = TableOperation.Insert(customer1);
        table.Execute(insertOperationTake);

        DataEntity customer2 = new DataEntity("Value," + module.id, time + "," + units.FirstOrDefault().id);
        customer2.DataVal = blobadd.filename;
        TableOperation insertOperationValue = TableOperation.Insert(customer2);
        table.Execute(insertOperationValue);

        #endregion

        // Blob内には、送信されたデータ全てをSONテキストとして1行に格納される
        #region Insert AzureBlob

        JavaScriptSerializer serializer = new JavaScriptSerializer();
        string json = serializer.Serialize(blobadd);

        CloudBlobContainer container = common.BlobAccess();

        CloudBlockBlob blockBlob = container.GetBlockBlobReference(module.id.ToString() + "," + time);

        blockBlob.UploadText(json);
        blockBlob.Properties.ContentType = "application/JSON";
        blockBlob.SetProperties();

        #endregion

        module.Latest = blobadd.dataaddlist[0].dt;
        module.NumData += 1;

      } catch {
        module.Type = "0";
        RDB.db.SaveChanges();
      }
      module.Type = "0";
      RDB.db.SaveChanges();

      return "Success!";
    }