diff --git a/src/agApi/agCollections.erl b/src/agApi/agCollections.erl index 866da38..685dbbb 100644 --- a/src/agApi/agCollections.erl +++ b/src/agApi/agCollections.erl @@ -185,6 +185,21 @@ collCnt(PoolNameOrSocket, CollName) -> Path = <<"/_api/collection/", CollName/binary, "/count">>, agVstCli:callAgency(PoolNameOrSocket, ?AgGet, Path). +% 重新计算集合的文档数 +% PUT /_api/collection/{collection-name}/recalculateCount +% 路径参数 +% collection-name(必填):集合的名称。 +% 重新计算集合的文档计数(如果不一致)。 +% 它返回具有属性的对象 +% 结果:如果重新计算文档计数成功,则为true。 +% 注意:此方法特定于RocksDB存储引擎 +% 返回码 +% 200:如果文档计数成功重新计算,则返回HTTP 200。 +% 404:如果集合名称未知,则返回HTTP 404。 +collRecnt(PoolNameOrSocket, CollName) -> + Path = <<"/_api/collection/", CollName/binary, "/recalculateCount">>, + agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path). + % 获取集合的统计信息 % GET /_api/collection/{collection-name}/figures % 从版本3.4.0开始,不建议使用按其数字ID访问集合。您应该通过它们的名称来引用它们。 @@ -300,7 +315,7 @@ collChecksum(PoolNameOrSocket, CollName, QueryPars) -> % GET /_api/collection % 从版本3.4.0开始,不建议使用按其数字ID访问集合。您应该通过它们的名称来引用它们。 % 查询参数 -% e(可选):是否应从结果中排除系统集合。 +% excludeSystem(可选):是否应从结果中排除系统集合。 % 返回带有属性集合的对象,该属性集合包含所有集合描述的数组。在名称中还可以使用对象作为对象,在集合名称中作为键使用相同的信息。 % 通过为可选查询参数excludeSystem提供值为true的值, 将从响应中排除所有系统集合。 % 返回码 @@ -336,8 +351,7 @@ loadColl(PoolNameOrSocket, CollName) -> agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path). loadColl(PoolNameOrSocket, CollName, MapData) -> - BodyStr = eVPack:encodeBin(MapData), - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, <<"/_api/collection/", CollName/binary, "/load">>, ?AgDefQuery, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPut, <<"/_api/collection/", CollName/binary, "/load">>, ?AgDefQuery, ?AgDefHeader, eVPack:encodeBin(MapData)). % 卸载集合 % PUT /_api/collection/{collection-name}/unload @@ -358,57 +372,6 @@ unloadColl(PoolNameOrSocket, CollName) -> Path = <<"/_api/collection/", CollName/binary, "/unload">>, agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path). -% 将索引加载到内存中 -% PUT /_api/collection/{collection-name}/loadIndexesIntoMemory -% 从版本3.4.0开始,不建议使用按其数字ID访问集合。您应该通过它们的名称来引用它们。 -% 路径参数 -% collection-name(必填):此路由尝试将这个collection的所有索引条目缓存到主内存中。因此,它将遍历集合的所有索引,并将索引值而不是整个文档数据存储在内存中。可以在缓存中找到的所有查找都比未存储在缓存中的查找要快得多,因此可以提高性能。还可以保证缓存与存储的数据一致。 -% 目前,此功能仅在RocksDB存储引擎上有用,因为在MMFiles引擎中,所有索引无论如何都在内存中。 -% 在RocksDB上,此函数将遵守所有内存限制,如果要加载的索引小于您的内存限制,则此函数可确保大多数索引值都已缓存。如果索引大于您的内存限制,则此函数将填满直至达到此限制的值,并且暂时无法控制集合中的哪些索引应优先于其他索引。 -% 成功后,此函数返回属性result设置为的对象true -% 返回码 -% 200:如果所有索引都已加载 -% 400:如果缺少集合名称,则返回HTTP 400。 -% 404:如果集合名称未知,则返回HTTP 404。 -collLoadIndexesIntoMemory(PoolNameOrSocket, CollName) -> - Path = <<"/_api/collection/", CollName/binary, "/loadIndexesIntoMemory">>, - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path). - -% 更改集合的属性 -% PUT /_api/collection/{collection-name}/properties -% 从版本3.4.0开始,不建议使用按其数字ID访问集合。您应该通过它们的名称来引用它们。 -% 路径参数 -% collection-name(必填):集合的名称。 -% 更改集合的属性。需要具有属性的对象 -% waitForSync:如果为true,则创建或更改文档将等待,直到数据已同步到磁盘。 -% journalSize:日志或数据文件的最大大小,以字节为单位。该值必须至少为1048576(1 MB)。请注意,更改journalSize值时,它仅对创建的其他日志或数据文件有效。现有的日志或数据文件将不受影响。 -% schema:指定文档的收集级别架构的对象。属性键rule,level并且message必须遵循文档架构验证中记录的规则 -% -% 成功后,将返回具有以下属性的对象: -% id:集合的标识符。 -% name:集合的名称。 -% waitForSync:新值。 -% journalSize:新值。 -% status:集合状态为数字。 -% type:集合类型。有效类型为: -% 2:文件收集 -% 3:边缘收集 -% isSystem:如果为true,则该集合为系统集合。 -% isVolatile:如果为true,则收集数据将仅保留在内存中,并且ArangoDB不会将数据写入或同步到磁盘。 -% doCompact:是否将压缩集合。 -% keyOptions:JSON对象,其中包含密钥生成选项: -% type:指定密钥生成器的类型。当前可用的生成器是传统的,自动递增的,uuid的 和填充的。 -% allowUserKeys:如果设置为true,则允许在文档的_key属性中提供自己的键值。如果设置为 false,那么密钥生成器将独自负责生成密钥,并且在文档的_key属性中提供自己的密钥值被视为错误。 -% schema(可选,默认为null):指定文档的收集级别架构的对象。属性键rule,level并且message必须遵循文档架构验证中记录的规则 -% 注意:除了waitForSync,journalSize和name之外,创建集合后就无法更改集合属性。要重命名集合,必须使用重命名端点。 -% 返回码 -% 400:如果缺少集合名称,则返回HTTP 400。 -% 404:如果集合名称未知,则 返回HTTP 404。 -collChangeProps(PoolNameOrSocket, CollName, MapData) -> - Path = <<"/_api/collection/", CollName/binary, "/properties">>, - BodyStr = eVPack:encodeBin(MapData), - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, ?AgDefQuery, ?AgDefHeader, BodyStr). - % 重命名集合 % PUT /_api/collection/{collection-name}/rename % 从版本3.4.0开始,不建议使用按其数字ID访问集合。您应该通过它们的名称来引用它们。 @@ -431,37 +394,49 @@ collChangeProps(PoolNameOrSocket, CollName, MapData) -> % 404:如果集合名称未知,则 返回HTTP 404。 renameColl(PoolNameOrSocket, OldName, MapData) -> Path = <<"/_api/collection/", OldName/binary, "/rename">>, - BodyStr = eVPack:encodeBin(MapData), - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, ?AgDefQuery, ?AgDefQuery, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, ?AgDefQuery, ?AgDefHeader, eVPack:encodeBin(MapData)). -% 旋转收藏夹的日记 -% PUT /_api/collection/{collection-name}/rotate +% 将索引加载到内存中 +% PUT /_api/collection/{collection-name}/loadIndexesIntoMemory +% 从版本3.4.0开始,不建议使用按其数字ID访问集合。您应该通过它们的名称来引用它们。 % 路径参数 -% collection-name(必填):集合的名称。 -% 旋转集合的日记帐。集合的当前日志将关闭,并成为只读数据文件。Rotate方法的目的是使文件中的数据可用于压缩(压缩仅对只读数据文件而不对日志执行)。 -% 如果没有当前日志,随后将新数据保存在集合中将自动创建一个新的日志文件。 -% 它返回具有属性的对象 -% 结果:如果旋转成功,则为true -% 注意:此方法特定于MMFiles存储引擎,并且在群集中不可用。 +% collection-name(必填):此路由尝试将这个collection的所有索引条目缓存到主内存中。因此,它将遍历集合的所有索引,并将索引值而不是整个文档数据存储在内存中。可以在缓存中找到的所有查找都比未存储在缓存中的查找要快得多,因此可以提高性能。还可以保证缓存与存储的数据一致。 +% 目前,此功能仅在RocksDB存储引擎上有用,因为在MMFiles引擎中,所有索引无论如何都在内存中。 +% 在RocksDB上,此函数将遵守所有内存限制,如果要加载的索引小于您的内存限制,则此函数可确保大多数索引值都已缓存。如果索引大于您的内存限制,则此函数将填满直至达到此限制的值,并且暂时无法控制集合中的哪些索引应优先于其他索引。 +% 成功后,此函数返回属性result设置为的对象true % 返回码 -% 400:如果该集合当前没有日记,则返回HTTP 400。 +% 200:如果所有索引都已加载 +% 400:如果缺少集合名称,则返回HTTP 400。 % 404:如果集合名称未知,则返回HTTP 404。 -% 3.7中删掉了该方法 -collRotate(PoolNameOrSocket, CollName) -> - Path = <<"/_api/collection/", CollName/binary, "/rotate">>, +collLoadIndexesIntoMemory(PoolNameOrSocket, CollName) -> + Path = <<"/_api/collection/", CollName/binary, "/loadIndexesIntoMemory">>, agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path). -% 重新计算集合的文档数 -% PUT /_api/collection/{collection-name}/recalculateCount +% 更改集合的属性 +% PUT /_api/collection/{collection-name}/properties +% 从版本3.4.0开始,不建议使用按其数字ID访问集合。您应该通过它们的名称来引用它们。 % 路径参数 -% collection-name(必填):集合的名称。 -% 重新计算集合的文档计数(如果不一致)。 -% 它返回具有属性的对象 -% 结果:如果重新计算文档计数成功,则为true。 -% 注意:此方法特定于RocksDB存储引擎 -% 返回码 -% 200:如果文档计数成功重新计算,则返回HTTP 200。 -% 404:如果集合名称未知,则返回HTTP 404。 -collRecount(PoolNameOrSocket, CollName) -> - Path = <<"/_api/collection/", CollName/binary, "/recalculateCount">>, - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path). \ No newline at end of file +% 集合名称(必需):集合的名称。 +% 更改集合的属性。期望具有属性的对象 +% waitForSync:如果为true,则创建或更改文档将等到数据同步到磁盘。 +% schema:指定文档集合级别架构的对象。属性键rule,level并且message必须遵循文档架构验证中记录的规则 +% 成功时将返回具有以下属性的对象: +% id:集合的标识符。 +% name:集合的名称。 +% waitForSync:新值。 +% status:集合的状态为数字。 +% type:集合类型。有效类型是: +% 2:文件收集 +% 3:边缘集合 +% isSystem:如果为true,则该集合是系统集合。 +% keyOptions:包含密钥生成选项的 JSON 对象: +% type:指定密钥生成器的类型。当前可用的生成器是传统的、自动增量的、uuid 和填充的。 +% allowUserKeys:如果设置为true,则允许在文档的_key属性中提供自己的键值。如果设置为 false,则密钥生成器全权负责生成密钥,并且在文档的_key属性中提供自己的密钥值被视为错误。 +% schema(可选,默认为null):指定文档集合级别架构的对象。属性键rule,level并且message必须遵循文档架构验证中记录的规则 +% 注意:除了waitForSync和name 之外,一旦创建了集合,就不能更改集合属性。要重命名集合,必须使用重命名端点。 +% 返回代码 +% 400:如果缺少集合名称,则返回HTTP 400。 +% 404:如果集合名称未知,则 返回HTTP 404。 +collChangeProps(PoolNameOrSocket, CollName, MapData) -> + Path = <<"/_api/collection/", CollName/binary, "/properties">>, + agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, ?AgDefQuery, ?AgDefHeader, eVPack:encodeBin(MapData)). \ No newline at end of file diff --git a/src/agApi/agDocuments.erl b/src/agApi/agDocuments.erl index 2e86bb2..ddc51a6 100644 --- a/src/agApi/agDocuments.erl +++ b/src/agApi/agDocuments.erl @@ -122,11 +122,11 @@ getDoc(PoolNameOrSocket, CollName, Key, Headers) -> % 304:如果给出“ If-None-Match”标题并且文档具有相同版本,则返回 % 404:如果找不到文档或集合,则返回 % 412:如果给出“ If-Match”标头并且找到的文档具有不同版本,则返回412。响应还将在Etag标头中包含找到的文档的当前版本。 -getDocHead(PoolNameOrSocket, CollName, Key) -> +getHead(PoolNameOrSocket, CollName, Key) -> Path = <<"/_api/document/", CollName/binary, "/", (agMiscUtils:toBinary(Key))/binary>>, agVstCli:callAgency(PoolNameOrSocket, ?AgHead, Path). -getDocHead(PoolNameOrSocket, CollName, Key, Headers) -> +getHead(PoolNameOrSocket, CollName, Key, Headers) -> Path = <<"/_api/document/", CollName/binary, "/", (agMiscUtils:toBinary(Key))/binary>>, agVstCli:callAgency(PoolNameOrSocket, ?AgHead, Path, ?AgDefQuery, Headers, ?AgDefBody). @@ -168,13 +168,11 @@ getDocHead(PoolNameOrSocket, CollName, Key, Headers) -> % 409:如果在索引属性中具有相同限定词的文档与现有文档发生冲突并因此违反了该唯一约束,则在单个文档的情况下返回409。在这种情况下,响应主体包含一个错误文档。 newDoc(PoolNameOrSocket, CollName, MapData) -> Path = <<"/_api/document/", CollName/binary>>, - BodyStr = eVPack:encodeBin(MapData), - agVstCli:callAgency(PoolNameOrSocket, ?AgPost, Path, ?AgDefQuery, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPost, Path, ?AgDefQuery, ?AgDefHeader, eVPack:encodeBin(MapData)). newDoc(PoolNameOrSocket, CollName, MapData, QueryPars) -> Path = <<"/_api/document/", CollName/binary>>, - BodyStr = eVPack:encodeBin(MapData), - agVstCli:callAgency(PoolNameOrSocket, ?AgPost, Path, QueryPars, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPost, Path, QueryPars, ?AgDefHeader, eVPack:encodeBin(MapData)). % 替换文档 % PUT /_api/document/{collection}/{key} @@ -211,18 +209,15 @@ newDoc(PoolNameOrSocket, CollName, MapData, QueryPars) -> % 412:如果违反了前提条件,则返回。该响应还将在_rev 属性中包含找到的文档的当前修订。此外,将返回属性_id和_key。 replaceDoc(PoolNameOrSocket, CollName, Key, MapData) -> Path = <<"/_api/document/", CollName/binary, "/", (agMiscUtils:toBinary(Key))/binary>>, - BodyStr = eVPack:encodeBin(MapData), - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, ?AgDefQuery, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, ?AgDefQuery, ?AgDefHeader, eVPack:encodeBin(MapData)). replaceDoc(PoolNameOrSocket, CollName, Key, MapData, QueryPars) -> Path = <<"/_api/document/", CollName/binary, "/", (agMiscUtils:toBinary(Key))/binary>>, - BodyStr = eVPack:encodeBin(MapData), - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, QueryPars, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, QueryPars, ?AgDefHeader, eVPack:encodeBin(MapData)). replaceDoc(PoolNameOrSocket, CollName, Key, MapData, QueryPars, Headers) -> Path = <<"/_api/document/", CollName/binary, "/", (agMiscUtils:toBinary(Key))/binary>>, - BodyStr = eVPack:encodeBin(MapData), - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, QueryPars, Headers, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, QueryPars, Headers, eVPack:encodeBin(MapData)). % 更新文档 % PATCH /_api/document/{collection}/{key} @@ -262,18 +257,15 @@ replaceDoc(PoolNameOrSocket, CollName, Key, MapData, QueryPars, Headers) -> % 412:如果违反了前提条件,则返回。该响应还将在_rev 属性中包含找到的文档的当前修订。此外,将返回属性_id和_key。 updateDoc(PoolNameOrSocket, CollName, Key, MapData) -> Path = <<"/_api/document/", CollName/binary, "/", (agMiscUtils:toBinary(Key))/binary>>, - BodyStr = eVPack:encodeBin(MapData), - agVstCli:callAgency(PoolNameOrSocket, ?AgPatch, Path, ?AgDefQuery, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPatch, Path, ?AgDefQuery, ?AgDefHeader, eVPack:encodeBin(MapData)). updateDoc(PoolNameOrSocket, CollName, Key, MapData, QueryPars) -> Path = <<"/_api/document/", CollName/binary, "/", (agMiscUtils:toBinary(Key))/binary>>, - BodyStr = eVPack:encodeBin(MapData), - agVstCli:callAgency(PoolNameOrSocket, ?AgPatch, Path, QueryPars, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPatch, Path, QueryPars, ?AgDefHeader, eVPack:encodeBin(MapData)). updateDoc(PoolNameOrSocket, CollName, Key, MapData, QueryPars, Headers) -> Path = <<"/_api/document/", CollName/binary, "/", (agMiscUtils:toBinary(Key))/binary>>, - BodyStr = eVPack:encodeBin(MapData), - agVstCli:callAgency(PoolNameOrSocket, ?AgPatch, Path, QueryPars, Headers, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPatch, Path, QueryPars, Headers, eVPack:encodeBin(MapData)). % 删除文档 % DELETE /_api/document/{collection}/{key} @@ -329,54 +321,63 @@ delDoc(PoolNameOrSocket, CollName, Key, QueryPars, Headers) -> % 对于该操作的返回 列表 如果文档不存在 或者_rev条件不满足 则返回列表的中包含相关的错误 可能需要在使用的时候过滤正确和非正确的返回文档 getDocs(PoolNameOrSocket, CollName, KeyOrMapDataList) -> Path = <<"/_api/document/", CollName/binary>>, - BodyStr = eVPack:encodeBin(KeyOrMapDataList), - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, #{<<"onlyget">> => <<"true">>}, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, #{<<"onlyget">> => <<"true">>}, ?AgDefHeader, eVPack:encodeBin(KeyOrMapDataList)). getDocs(PoolNameOrSocket, CollName, KeyOrMapDataList, QueryPars) -> - LastQueryPars = QueryPars#{<<"onlyget">> => <<"true">>}, + LastQueryPars = case QueryPars of + #{<<"onlyget">> := <<"true">>} -> + QueryPars; + #{onlyget := <<"true">>} -> + QueryPars; + _ -> + QueryPars#{<<"onlyget">> => <<"true">>} + end, Path = <<"/_api/document/", CollName/binary>>, - BodyStr = eVPack:encodeBin(KeyOrMapDataList), - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, LastQueryPars, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, LastQueryPars, ?AgDefHeader, eVPack:encodeBin(KeyOrMapDataList)). % 创建多个文档 % POST /_api/document/{collection}#multiple % 路径参数 % collection(必填):要在其中创建文档的集合的名称。 % 查询参数 -% collection(可选):集合的名称。这仅是为了向后兼容。在ArangoDB版本<3.0中,URL路径为/ _api / document,并且此查询参数是必需的。这种组合仍然有效,但是建议的方法是在URL路径中指定集合。 -% waitForSync(可选):等待文档已同步到磁盘。 -% returnNew(可选):另外 ,在结果的new属性下返回完整的新文档。 -% returnOld(可选):另外 ,在结果的old属性下返回完整的旧文档。仅在使用覆盖选项时可用。 -% silent(可选):如果设置为true,则将返回一个空对象作为响应。创建的文档将不返回任何元数据。此选项可用于节省一些网络流量。 -% overwrite(可选):如果设置为true,则插入将成为替换插入。如果已经存在具有相同_key的文档,则不会由于违反唯一约束而拒绝新文档,而是将替换旧文档。 -% 请求正文(json) +% collection (可选):集合的名称。这只是为了向后兼容。在 ArangoDB 版本 < 3.0 中,URL 路径为/_api/document并且需要此查询参数。这种组合仍然有效,但推荐的方法是在 URL 路径中指定集合。 +% waitForSync(可选):等到文档同步到磁盘。 +% returnNew(可选):另外 在结果中返回属性new下的完整新文档。 +% returnOld(可选):另外返回 结果中属性old下的完整旧文档。仅在使用覆盖选项时可用。 +% silent (可选):如果设置为true,则将返回一个空对象作为响应。不会为创建的文档返回元数据。此选项可用于节省一些网络流量。 +% overwrite(可选):如果设置为true,则插入变为替换插入。如果具有相同_key的文档已经存在,则新文档不会因违反唯一约束而被拒绝,而是会替换旧文档。请注意,带有overwrite参数的操作需要_key请求有效负载中的属性,因此它们只能在由 分片的集合上执行_key。 +% overwriteMode(可选):此选项取代覆盖并提供以下模式: +% "ignore": 如果指定_key值的文档已经存在,则什么都不做,也不进行写操作。在这种情况下,插入操作将返回成功。此模式不支持使用 返回旧文档版本RETURN OLD。使用时 RETURN NEW,如果文档已经存在,将返回null。 +% "replace": 如果具有指定_key值的文档已经存在,它将被指定的文档值覆盖。当未指定覆盖模式但覆盖 标志设置为true时,也将使用此模式。 +% "update":如果具有指定_key值的文档已经存在,它将使用指定的文档值修补(部分更新)。覆盖模式可以通过keepNull和 mergeObjects参数进一步控制。 +% "conflict": 如果具有指定_key值的文档已经存在,则返回唯一约束冲突错误,以便插入操作失败。如果未设置覆盖模式,并且覆盖标志为false或未设置,这也是默认行为。 +% keepNull(可选):如果打算使用 update-insert 命令删除现有属性,则可以使用值为 false的 URL 查询参数keepNull。这将修改 patch 命令的行为,以从包含在 patch 文档中且属性值为null的现有文档中删除任何属性。此选项仅控制更新插入行为。 +% mergeObjects(可选):控制如果对象(不是数组)同时存在于现有文档和更新插入文档中,则是否将其合并。如果设置为false,补丁文档中的值将覆盖现有文档的值。如果设置为true,对象将被合并。默认值为true。此选项仅控制更新插入行为。 +% 请求正文 (json) % 要创建的文档数组。 -% 从正文中给定的文档创建新文档,除非已经有给定_key的文档。如果未提供_key,则会自动生成一个新的唯一_key。 -% 结果主体将包含一个长度与输入数组相同的JSON数组,并且每个条目都包含对应输入的运算结果。如果发生错误,则该条目是一个文档,其属性error设置为true,errorCode设置为发生的错误代码。 -% 正文中可能始终给定的_id和_rev属性被忽略,URL部分或查询参数集合分别计数。 -% 如果silent未设置为true,则响应的主体包含具有以下属性的JSON对象数组: -% _id包含新创建的文档的文档标识符 -% _key包含文档密钥 -% _rev包含文档修订版 -% 如果collection参数waitForSync为false,则在文档被接受后,调用将立即返回。直到文档同步到磁盘后,它才会等待。 -% 可选地,即使已为整个集合禁用了waitForSync标志,查询参数waitForSync也可用于强制将文档创建操作同步到磁盘。因此,waitForSync查询参数可用于强制执行此特定操作的同步。要使用此功能,请将waitForSync参数设置为true。如果 未指定waitForSync参数或将其设置为false,则将应用集合的默认waitForSync行为。该waitForSync查询参数不能用于禁用同步用于具有默认集合waitForSync值为true。 -% 如果查询参数returnNew为true,则对于每个生成的文档,将在结果中的new属性下返回完整的新文档。 -% 应与一些附加的HTTP头的文件已经发生了错误的X阿朗戈-差错代码:被设置,其中包含一个地图,与它们的重数一起发生的错误代码,如在1205:10,1210:17,其意味着在10种情况下发生了错误1205“非法文档句柄”,在17种情况下发生了错误1210“违反唯一约束”。 -% 返回码 -% 201:如果waitForSync为true,并且已处理操作,则返回。 -% 202:如果waitForSync为false并且已处理操作,则返回。 -% 400:如果正文不包含文档数组的有效JSON表示形式,则返回。在这种情况下,响应主体包含一个错误文档。 -% 404:如果collection指定的collection未知,则返回。在这种情况下,响应主体包含一个错误文档。 -% 按照MapDataList的顺序返回执行结果 正确或者错误 +% 从正文中给定的文档创建新文档,除非已经有一个带有_key的文档。如果没有_key被赋予一个新的独特的_key自动生成。 +% 结果主体将包含一个与输入数组长度相同的 JSON 数组,每个条目包含对相应输入的操作结果。如果出现错误,条目是一个文档,其属性error设置为true并且 errorCode 设置为发生的错误代码。 +% 可能给定的正文中的_id和_rev属性总是被忽略,URL 部分或查询参数集合分别计数。 +% 如果Silent未设置为true,则响应正文包含具有以下属性的 JSON 对象数组: +% _id包含新创建的文档的文档标识符 +% _key包含文档密钥 +% _rev包含文档修订 +% 如果集合参数waitForSync为false,则一旦文档被接受,调用就会返回。它不会等到文档同步到磁盘。 +% 或者,查询参数waitForSync可用于强制将文档创建操作同步到磁盘,即使在整个集合的waitForSync标志已被禁用的情况下。因此,waitForSync查询参数可用于强制仅同步此特定操作。要使用它,请将waitForSync参数设置为true。如果 未指定waitForSync参数或将其设置为false,则应用集合的默认waitForSync行为。该waitForSync查询参数不能用于禁用同步用于具有默认集合waitForSync值为true。 +% 如果查询参数returnNew为true,则对于每个生成的文档,在结果中的new属性下返回完整的新文档。 +% 应与一些附加的HTTP头的文件已经发生了错误的X阿朗戈-差错代码:被设置,其中包含一个地图,与它们的重数一起发生的错误代码,如在1205:10,1210:17,其意味着在 10 种情况下发生了错误 1205“非法文档句柄”,在 17 种情况下发生了错误 1210“违反了唯一约束”。 +% 返回代码 +% 201:如果waitForSync为true并且操作已处理,则返回。 +% 202:如果waitForSync为false并且操作已处理,则返回。 +% 400:如果正文不包含文档数组的有效 JSON 表示,则返回。在这种情况下,响应正文包含一个错误文档。 +% 404:collection指定的collection未知时返回。在这种情况下,响应正文包含一个错误文档。 newDocs(PoolNameOrSocket, CollName, MapDataList) -> Path = <<"/_api/document/", CollName/binary>>, - BodyStr = eVPack:encodeBin(MapDataList), - agVstCli:callAgency(PoolNameOrSocket, ?AgPost, Path, ?AgDefQuery, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPost, Path, ?AgDefQuery, ?AgDefHeader, eVPack:encodeBin(MapDataList)). newDocs(PoolNameOrSocket, CollName, MapDataList, QueryPars) -> Path = <<"/_api/document/", CollName/binary>>, - BodyStr = eVPack:encodeBin(MapDataList), - agVstCli:callAgency(PoolNameOrSocket, ?AgPost, Path, QueryPars, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPost, Path, QueryPars, ?AgDefHeader, eVPack:encodeBin(MapDataList)). % 替换多个文件 % PUT /_api/document/{collection} @@ -405,25 +406,23 @@ newDocs(PoolNameOrSocket, CollName, MapDataList, QueryPars) -> % 404:如果找不到集合,则返回。 replaceDocs(PoolNameOrSocket, CollName, MapDataList) -> Path = <<"/_api/document/", CollName/binary>>, - BodyStr = eVPack:encodeBin(MapDataList), - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, ?AgDefQuery, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, ?AgDefQuery, ?AgDefHeader, eVPack:encodeBin(MapDataList)). replaceDocs(PoolNameOrSocket, CollName, MapDataList, QueryPars) -> Path = <<"/_api/document/", CollName/binary>>, - BodyStr = eVPack:encodeBin(MapDataList), - agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, QueryPars, ?AgDefHeader, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgPut, Path, QueryPars, ?AgDefHeader, eVPack:encodeBin(MapDataList)). % 更新多个文件 % PATCH /_api/document/{collection} % 路径参数 % collection(必填):要在其中更新文档的集合的名称。 % 查询参数 -% keepNull(可选):如果要使用patch命令删除现有属性,则可以将URL查询参数keepNull与false一起使用。这将修改patch命令的行为,以从属性文档中删除属性文件值为null的现有文档。 -% mergeObjects(可选):控制如果现有文档和修补程序文档中都存在对象(不是数组),是否将合并对象。如果设置为false,则修补程序文档中的值将覆盖现有文档的值。如果设置为true,则对象将被合并。默认值为 true。 -% waitForSync(可选):等待新文档同步到磁盘。 -% ignoreRevs(可选):默认情况下,或者如果将其设置为true,则忽略给定文档中的_rev属性。如果将其设置为false,则将正文文档中给定的_rev属性作为前提。仅当当前版本是指定的版本时,文档才会更新。 -% returnOld(可选):在结果的old属性下还返回更改后的文档的完整先前修订。 -% returnNew(可选): 在结果的new属性下还返回完整的新文档。 +% keepNull(可选):如果要使用patch命令删除现有属性,则可以将URL查询参数keepNull与false一起使用。这将修改patch命令的行为,以从属性文档中删除属性文件值为null的现有文档。 +% mergeObjects(可选):控制如果现有文档和修补程序文档中都存在对象(不是数组),是否将合并对象。如果设置为false,则修补程序文档中的值将覆盖现有文档的值。如果设置为true,则对象将被合并。默认值为 true。 +% waitForSync(可选):等待新文档同步到磁盘。 +% ignoreRevs(可选):默认情况下,或者如果将其设置为true,则忽略给定文档中的_rev属性。如果将其设置为false,则将正文文档中给定的_rev属性作为前提。仅当当前版本是指定的版本时,文档才会更新。 +% returnOld(可选):在结果的old属性下还返回更改后的文档的完整先前修订。 +% returnNew(可选): 在结果的new属性下还返回完整的新文档。 % 请求正文(json) % 文档更新数组的JSON表示形式是对象。 % 部分更新文档,要更新的文档由主体对象中的_key属性指定。请求的正文必须包含文档更新的JSON数组,其中包含要修补的属性(补丁文档)。修补程序文档中的所有属性(如果尚不存在)将被添加到现有文档中,如果存在的话将被覆盖在现有文档中。 @@ -473,7 +472,7 @@ updateDocs(PoolNameOrSocket, CollName, MapDataList, QueryPars) -> delDocs(PoolNameOrSocket, CollName, KeyOrMapDataList) -> Path = <<"/_api/document/", CollName/binary, "/">>, BodyStr = eVPack:encodeBin(KeyOrMapDataList), - agVstCli:callAgency(PoolNameOrSocket, ?AgDelete, Path, ?AgDefQuery, ?AgDefQuery, BodyStr). + agVstCli:callAgency(PoolNameOrSocket, ?AgDelete, Path, ?AgDefQuery, ?AgDefHeader, BodyStr). delDocs(PoolNameOrSocket, CollName, KeyOrMapDataList, QueryPars) -> Path = <<"/_api/document/", CollName/binary>>, diff --git a/src/agVstCli/agAgencyUtils.erl b/src/agVstCli/agAgencyUtils.erl index 8413cf2..f7d0550 100644 --- a/src/agVstCli/agAgencyUtils.erl +++ b/src/agVstCli/agAgencyUtils.erl @@ -80,10 +80,14 @@ initReConnState(IsReconnect, Min, Max) -> end. -spec resetReConnState(undefined | reConnState()) -> reConnState() | undefined. +resetReConnState(undefined) -> + undefined; resetReConnState(#reConnState{min = Min} = ReConnState) -> ReConnState#reConnState{current = Min}. -spec updateReConnState(reConnState()) -> reConnState(). +updateReConnState(undefined) -> + undefined; updateReConnState(#reConnState{current = Current, max = Max} = ReConnState) -> NewCurrent = Current + Current, ReConnState#reConnState{current = if NewCurrent >= Max -> Max; true -> NewCurrent end}. diff --git a/src/agVstCli/agSslAgencyIns.erl b/src/agVstCli/agSslAgencyIns.erl index 569cde9..7e7c417 100644 --- a/src/agVstCli/agSslAgencyIns.erl +++ b/src/agVstCli/agSslAgencyIns.erl @@ -84,7 +84,7 @@ handleMsg({ssl_error, Socket, Reason}, ssl:close(Socket), agAgencyUtils:dealClose(SrvState, CliState, {error, {ssl_error, Reason}}); handleMsg(?AgMDoDBConn, - #srvState{poolName = PoolName, serverName = ServerName, reConnState = _ReConnState} = SrvState, + #srvState{poolName = PoolName, serverName = ServerName, reConnState = ReConnState} = SrvState, CliState) -> case ?agBeamPool:getv(PoolName) of #dbOpts{port = Port, hostname = HostName, dbName = DbName, user = User, password = Password, vstSize = VstSize} -> @@ -97,7 +97,7 @@ handleMsg(?AgMDoDBConn, {ok, MsgBin} -> case eVPack:decodeHeader(MsgBin) of [1, 2, 200, _] -> - {ok, SrvState#srvState{dbName = DbName, socket = Socket, vstSize = VstSize}, CliState}; + {ok, SrvState#srvState{dbName = DbName, reConnState = agAgencyUtils:resetReConnState(ReConnState), socket = Socket, vstSize = VstSize}, CliState}; _Err -> ?AgWarn(ServerName, "auth error: ~p~n", [_Err]), agAgencyUtils:reConnTimer(SrvState, CliState) diff --git a/src/agVstCli/agTcpAgencyIns.erl b/src/agVstCli/agTcpAgencyIns.erl index 4681cc7..1676ffb 100644 --- a/src/agVstCli/agTcpAgencyIns.erl +++ b/src/agVstCli/agTcpAgencyIns.erl @@ -90,7 +90,7 @@ handleMsg({tcp_error, Socket, Reason}, gen_tcp:close(Socket), agAgencyUtils:dealClose(SrvState, CliState, {error, {tcp_error, Reason}}); handleMsg(?AgMDoDBConn, - #srvState{poolName = PoolName, serverName = ServerName, reConnState = _ReConnState} = SrvState, + #srvState{poolName = PoolName, serverName = ServerName, reConnState = ReConnState} = SrvState, CliState) -> case ?agBeamPool:getv(PoolName) of #dbOpts{port = Port, hostname = HostName, dbName = DbName, user = User, password = Password, vstSize = VstSize} -> @@ -103,7 +103,8 @@ handleMsg(?AgMDoDBConn, {ok, MsgBin} -> case eVPack:decodeHeader(MsgBin) of [1, 2, 200, _] -> - {ok, SrvState#srvState{dbName = DbName, socket = Socket, vstSize = VstSize}, CliState}; + ?AgWarn(ServerName, "connect success: old server state:~n ~p~n client state~n ~p ~n", [SrvState, CliState]), + {ok, SrvState#srvState{dbName = DbName, reConnState = agAgencyUtils:resetReConnState(ReConnState), socket = Socket, vstSize = VstSize}, CliState}; _Err -> ?AgWarn(ServerName, "auth error: ~p~n", [_Err]), agAgencyUtils:reConnTimer(SrvState, CliState) diff --git a/src/user_default.erl b/src/user_default.erl index 9f333fe..598a5a5 100644 --- a/src/user_default.erl +++ b/src/user_default.erl @@ -6,11 +6,14 @@ start() -> eSync:run(), application:ensure_all_started(eArango), - agVstCli:startPool(tt, [{poolSize, 10}], []). + agVstCli:startPool(tt, [{poolSize, 1}], []). + +stop() -> + agVstCli:stopPool(tt). tt(C, N) -> application:ensure_all_started(eArango), - agVstCli:startPool(tt, [{poolSize, 16}], []), + agVstCli:startPool(tt, [{poolSize, 1}], []), StartTime = erlang:system_time(millisecond), io:format("IMY********************** started~n"), [spawn(?MODULE, test, [N, StartTime]) || _Idx <- lists:seq(1, C)].