/// <inheritdoc/>
 public void AddIndex(string nsName, params Index[] indexDefinitions)
 {
     using (var nsNameRx = nsName.GetHandle())
         foreach (var index in indexDefinitions)
         {
             if (index.JsonPaths == null || index.JsonPaths.Count == 0)
             {
                 index.JsonPaths = new List <string> {
                     index.Name
                 }
             }
             ;
             using (var jsonRx = SerializeJson(index).GetStringHandle())
                 Assert.ThrowIfError(() =>
                                     ReindexerBinding.reindexer_add_index(Rx, nsNameRx, jsonRx, _ctxInfo)
                                     );
         }
 }
        public void ParallelModifyItemPacked()
        {
            var nsName = "ParallelTestNs";

            AssertError(ReindexerBinding.reindexer_open_namespace(_rx, nsName.GetHandle(),
                                                                  new StorageOpts {
                options = StorageOpt.kStorageOptCreateIfMissing | StorageOpt.kStorageOptEnabled
            },
                                                                  _ctxInfo));

            var indexDefJson = JsonSerializer.ToJsonString(
                new Index
            {
                Name      = "Id",
                IsPk      = true,
                FieldType = FieldType.Int64,
                IndexType = IndexType.Hash,
                JsonPaths = new List <string> {
                    "Id"
                }
            }, Utf8Json.Resolvers.StandardResolver.ExcludeNull);

            AssertError(ReindexerBinding.reindexer_add_index(_rx, nsName.GetHandle(), indexDefJson.GetHandle(), _ctxInfo));

            using (var ser1 = new CJsonWriter())
            {
                ser1.PutVString(nsName);
                ser1.PutVarCUInt((int)DataFormat.FormatJson);
                ser1.PutVarCUInt((int)ItemModifyMode.Upsert);
                ser1.PutVarCUInt(0);
                ser1.PutVarCUInt(0);

                reindexer_buffer.PinBufferFor(ser1.CurrentBuffer, args =>
                {
                    Parallel.For(0, 30000, i =>
                    {
                        var dataHandle = reindexer_buffer.From(Encoding.UTF8.GetBytes($"{{\"Id\":{i}, \"Guid\":\"{Guid.NewGuid()}\"}}"));
                        var rsp        = ReindexerBinding.reindexer_modify_item_packed(_rx, args, dataHandle.Buffer, _ctxInfo);
                        try
                        {
                            if (rsp.err_code != 0)
                            {
                                Assert.AreEqual(null, (string)rsp.@out);
                            }

                            Assert.AreNotEqual(UIntPtr.Zero, [email protected]_ptr);

                            var reader         = new CJsonReader(rsp.@out);
                            var rawQueryParams = reader.ReadRawQueryParams();

                            Assert.AreEqual(1, rawQueryParams.count);

                            reader.ReadRawItemParams();
                        }
                        finally
                        {
                            dataHandle.Dispose();
                            [email protected]();
                        }
                    });
                });
            }

            Thread.Sleep(6000);
#pragma warning disable S1215 // "GC.Collect" should not be called
            GC.Collect();
            GC.WaitForPendingFinalizers();
#pragma warning restore S1215 // "GC.Collect" should not be called
            AssertError(ReindexerBinding.reindexer_truncate_namespace(_rx, nsName.GetHandle(), _ctxInfo));
        }
        public void ModifyItemPacked(string itemJson = null)
        {
            AssertError(ReindexerBinding.reindexer_open_namespace(_rx, DataTestNamespace.GetHandle(),
                                                                  new StorageOpts {
                options = StorageOpt.kStorageOptCreateIfMissing | StorageOpt.kStorageOptEnabled
            },
                                                                  _ctxInfo));

            var indexDefJson = JsonSerializer.ToJsonString(
                new Index
            {
                Name      = "Id",
                IsPk      = true,
                FieldType = FieldType.Int64,
                IndexType = IndexType.Hash,
                JsonPaths = new List <string> {
                    "Id"
                }
            }, Utf8Json.Resolvers.StandardResolver.ExcludeNull);

            AssertError(ReindexerBinding.reindexer_add_index(_rx, DataTestNamespace.GetHandle(), indexDefJson.GetHandle(), _ctxInfo));
            indexDefJson = JsonSerializer.ToJsonString(
                new Index
            {
                Name      = "Guid",
                IsPk      = false,
                FieldType = FieldType.String,
                IndexType = IndexType.Hash,
                JsonPaths = new List <string> {
                    "Guid"
                }
            }, Utf8Json.Resolvers.StandardResolver.ExcludeNull);
            AssertError(ReindexerBinding.reindexer_add_index(_rx, DataTestNamespace.GetHandle(), indexDefJson.GetHandle(), _ctxInfo));

            var rsp = ReindexerBinding.reindexer_select(_rx,
                                                        $"SELECT \"indexes.name\" FROM #namespaces WHERE name = \"{DataTestNamespace}\"".GetHandle(),
                                                        1, new int[0], 0, _ctxInfo);

            if (rsp.err_code != 0)
            {
                Assert.AreEqual(null, (string)rsp.@out);
            }
            Assert.AreNotEqual(UIntPtr.Zero, [email protected]_ptr);

            var(json, offsets, explain) = BindingHelpers.RawResultToJson(rsp.@out, "items", "total_count");
            var indexNames = JsonSerializer.Deserialize <ItemsOf <Namespace> >(json).Items.SelectMany(n => n.Indexes.Select(i => i.Name)).ToList();

            CollectionAssert.Contains(indexNames as ICollection, "Id");
            CollectionAssert.Contains(indexNames as ICollection, "Guid");

            using (var ser1 = new CJsonWriter())
            {
                ser1.PutVString(DataTestNamespace);
                ser1.PutVarCUInt((int)DataFormat.FormatJson); //format
                ser1.PutVarCUInt((int)ItemModifyMode.Upsert); //mode
                ser1.PutVarCUInt(0);                          //stateToken
                ser1.PutVarCUInt(0);                          //len(precepts)

                reindexer_buffer.PinBufferFor(ser1.CurrentBuffer, args =>
                {
                    using (var data = reindexer_buffer.From(Encoding.UTF8.GetBytes(itemJson ?? $"{{\"Id\":1, \"Guid\":\"{Guid.NewGuid()}\"}}")))
                    {
                        rsp = ReindexerBinding.reindexer_modify_item_packed(_rx, args, data.Buffer, _ctxInfo);
                        if (rsp.err_code != 0)
                        {
                            Assert.AreEqual(null, (string)rsp.@out);
                        }

                        Assert.AreNotEqual(UIntPtr.Zero, [email protected]_ptr);

                        var reader         = new CJsonReader(rsp.@out);
                        var rawQueryParams = reader.ReadRawQueryParams();

                        Assert.AreEqual(1, rawQueryParams.count);

                        reader.ReadRawItemParams();

                        if ([email protected]_ptr != UIntPtr.Zero)
                        {
                            AssertError(ReindexerBinding.reindexer_free_buffer(rsp.@out));
                        }
                    }
                });
            }
        }