Browse Source

Add support for "-" JSON index to db operations

pull/8/head
Anton Tarasenko 3 years ago
parent
commit
627d3db6f2
  1. 5
      sources/Data/Database/Database.uc
  2. 32
      sources/Data/Database/Local/DBRecord.uc
  3. 13
      sources/Data/Database/Tests/TEST_LocalDatabase.uc

5
sources/Data/Database/Database.uc

@ -104,6 +104,8 @@ public function DBReadTask ReadData(
*
* @param pointer JSON pointer to the location in the database, where `data`
* should be written (as a JSON value).
* This JSON pointer can make use of "-" index for JSON arrays that allows
* appending data at their end.
* `none` is always treated as an invalid JSON pointer.
* @param data Data that needs to be written at the specified location
* inside the database. For method to succeed this object needs to have
@ -273,6 +275,9 @@ public function DBKeysTask GetDataKeys(JSONPointer pointer)
* @param pointer JSON pointer to the location in the database, where
* data should be incremented (by `increment`).
* `none` is always treated as an invalid JSON pointer.
* This JSON pointer can make use of "-" index for JSON arrays that allows
* to add `none` value at the end of that array and then "increment" it
* with `increment` parameter.
* @param increment JSON-compatible value to be used as an increment for
* the data at the specified location inside the database.
* @return Task object that corresponds to this `IncrementData()` call.

32
sources/Data/Database/Local/DBRecord.uc

@ -133,8 +133,9 @@ struct StorageItem
};
var private config array<StorageItem> storage;
var private const int LATIN_LETTERS_AMOUNT;
var private const int LOWER_A_CODEPOINT, UPPER_A_CODEPOINT;
var private const int LATIN_LETTERS_AMOUNT;
var private const int LOWER_A_CODEPOINT, UPPER_A_CODEPOINT;
var private const string JSONPOINTER_NEW_ARRAY_ELEMENT;
/**
* Since `DBRecord` represents JSON array or object, we can use
@ -422,16 +423,18 @@ public final function bool SaveObject(
return false;
}
directContainer = pointer.record;
itemKey = __().text.ToString(jsonPointer.Pop(true));
if (directContainer.isJSONArray)
{
index = jsonPointer.PopNumeric(true);
if (index < 0 && itemKey == JSONPOINTER_NEW_ARRAY_ELEMENT) {
index = directContainer.GetStorageLength();
}
if (index < 0) {
return false;
}
}
else
{
itemKey = __().text.ToString(jsonPointer.Pop(true));
else {
index = directContainer.FindItem(itemKey);
}
directContainer.SetItem(index, ConvertObjectToItem(newItem), itemKey);
@ -624,16 +627,18 @@ public final function Database.DBQueryResult IncrementObject(
return DBR_InvalidPointer;
}
directContainer = pointer.record;
itemKey = __().text.ToString(jsonPointer.Pop(true));
if (directContainer.isJSONArray)
{
index = jsonPointer.PopNumeric(true);
if (index < 0 && itemKey == JSONPOINTER_NEW_ARRAY_ELEMENT) {
index = directContainer.GetStorageLength();
}
if (index < 0) {
return DBR_InvalidPointer;
}
}
else
{
itemKey = __().text.ToString(jsonPointer.Pop(true));
else {
index = directContainer.FindItem(itemKey);
}
if (directContainer.IncrementItem(index, object, itemKey)) {
@ -752,6 +757,8 @@ private final function bool IncrementItem(
}
if (IncrementItemByObject(itemToIncrement, object))
{
// Increment object cannot overwrite existing `DBRecord` with
// other value, so it's safe to skip cleaning check
storage[index] = itemToIncrement;
storage[index].k = itemName;
return true;
@ -1154,7 +1161,10 @@ private final function bool ReadNumericObjectInto(
// Add storing bytes
defaultproperties
{
LATIN_LETTERS_AMOUNT = 26
LOWER_A_CODEPOINT = 97
UPPER_A_CODEPOINT = 65
LATIN_LETTERS_AMOUNT = 26
LOWER_A_CODEPOINT = 97
UPPER_A_CODEPOINT = 65
// JSON Pointers allow using "-" as an indicator that element must be
// added at the end of the array
JSONPOINTER_NEW_ARRAY_ELEMENT = "-"
}

13
sources/Data/Database/Tests/TEST_LocalDatabase.uc

@ -710,6 +710,7 @@ protected static function SubTest_WritingArrayIndicies(LocalDatabaseInstance db)
db.WriteData(__().json.Pointer(P("")), templateObject);
db.WriteData(__().json.Pointer(P("/A")), templateArray);
db.WriteData(__().json.Pointer(P("/A/100")), __().box.int(-342));
db.WriteData(__().json.Pointer(P("/A/-")), __().box.int(95));
Issue("Database allows writing data into negative JSON array indices.");
writeTask = db.WriteData(__().json.Pointer(P("/A/-5")), __().box.int(1202));
@ -717,12 +718,13 @@ protected static function SubTest_WritingArrayIndicies(LocalDatabaseInstance db)
writeTask.TryCompleting();
Issue("Database cannot extend stored JSON array's length by assigning to"
@ "the out-of-bounds index.");
@ "the out-of-bounds index or \"-\".");
ReadFromDB(db, "/A");
resultArray = DynamicArray(default.resultObject);
TEST_ExpectTrue(resultArray.GetLength() == 101);
TEST_ExpectTrue(resultArray.GetLength() == 102);
TEST_ExpectNone(resultArray.GetItem(99));
TEST_ExpectTrue(resultArray.GetInt(100) == -342);
TEST_ExpectTrue(resultArray.GetInt(101) == 95);
TEST_ExpectTrue(resultArray.GetBool(0));
}
@ -1221,14 +1223,17 @@ protected static function SubTest_IncrementMissing(LocalDatabaseInstance db)
task.connect = DBIncrementHandler;
task.TryCompleting();
TEST_ExpectTrue(default.resultType == DBR_Success);
task = db.IncrementData(__().json.Pointer(P("/B/A/1//10")), none);
db.IncrementData(__().json.Pointer(P("/B/A/1//10")), none);
task = db.IncrementData(__().json.Pointer(P("/B/A/1//-")),
__().box.int(85));
task.connect = DBIncrementHandler;
task.TryCompleting();
TEST_ExpectTrue(default.resultType == DBR_Success);
db.CheckDataType(__().json.Pointer(P("/L"))).connect = DBCheckHandler;
ReadFromDB(db, "/B/A/1/");
TEST_ExpectTrue(default.resultDataType == JSON_Number);
TEST_ExpectTrue(DynamicArray(default.resultObject).GetLength() == 11);
TEST_ExpectTrue(DynamicArray(default.resultObject).GetLength() == 12);
TEST_ExpectTrue(DynamicArray(default.resultObject).GetInt(11) == 85);
}
defaultproperties

Loading…
Cancel
Save