Извините за долгое вступление.
Люди из CRAN настоятельно рекомендовали написать тесты для моего пакета, и благодаря этим тестам я обнаружил, что где-то происходит сбой. При выполнении тестов я получаю следующий вывод:
Loading RBaseX
Testing RBaseX
✓ | OK F W S | Context
✓ | 2 | test_first [0.1 s]
✓ | 8 | test_QueryClass
⠋ | 1 | test_RbaseX
Database 'TestOpen' is niet gevonden.
Database 'TestOpen' is niet gevonden.
Database 'TestOpen' is niet gevonden.
Database 'Testopen' is gesloten.
✓ | 5 | test_RbaseX [0.2 s]
⠏ | 0 | test_Wrappers
✓ | 6 | test_Wrappers
⠦ | 6 1 | test_Wrappers
══ Results ════════════════════════════
Duration: 0.5 s
OK: 21
Failed: 1
Warnings: 0
Skipped: 0
После добавления новых тестов либо в новый тестовый файл, либо в существующий тестовый файл, в последней строке всегда отображается счетчик в F-столбце. имеет значение 1. Нет указания на причину сбоя.
Мой первый вопрос - как следует интерпретировать точки в первом столбце. Они дают информацию о причине?
Мои следующие вопросы касаются процесса finalize ().
Мой пакет основан на 3 классах R6:
- "BasexClient" основной класс
- «SocketClass»
- «QueryClass»
После инициализации экземпляр «SocketClass» используется для установления sh соединения с BaseX -сервер (XML -database). SocketClass также предоставляет функции для записи или чтения из соединения. Соединение закрывается в процессе finalize ().
Для более сложных запросов могут использоваться экземпляры из QueryClass. Каждый экземпляр этого QueryClass регистрируется в базе данных. При успешной регистрации ID возвращается. Этот идентификатор используется при взаимодействии с базой данных. Количество запросов, которые можно зарегистрировать, не ограничено. Ссылка на экземпляры QueryClass поддерживается в закрытом поле (списке) для BaseXClient.
Следующий код показывает, как создается новый сеанс и как добавляются два запроса:
Session <- BasexClient$new("localhost", 1984L, username = "admin", password = "admin")
Query_1 <- Session$Query("for $i in 1 to 2 return $i")
Query_2 <- Session$Query("for $i in 3 to 4 return $i")
str(Query_1)
говорит мне структуру Query_1:
List of 2
$ queryObject:Classes 'QueryClass', 'R6' <QueryClass>
Public:
Bind: function (...)
clone: function (deep = FALSE)
Close: function ()
Context: function (value, type)
ExecuteQuery: function ()
Full: function ()
Info: function ()
initialize: function (query, Parent)
More: function ()
Next: function ()
Options: function ()
Updating: function ()
Private:
cache: NULL
clean: function (input)
default_query_pattern: function (Caller)
parent: BasexClient, R6
pos: NULL
raw_id: 31 00
receive_more: function (input, output)
req_result:
sock: SocketClass, R6
write_code_ID: function (id_code)
$ success : logi TRUE
Один из методов для QueryClass - это Close (). Этот метод отменяет регистрацию запроса в базе данных.
Query_1$queryObject$Close()
Нет ограничения на количество зарегистрированных запросов, и нет способа гарантировать, что все запросы явно закрыты. Поэтому я хотел бы использовать finalize (), чтобы закрыть все запросы. Список со ссылками на зарегистрированные QueryInstances доступен как личное поле экземпляра BaseXClient. Я попробовал это:
finalize = function() {
for (index in 1:length(private$QueryList)) {self$private$QueryList[index]$queryObject$Close()}
}
rm(Session)
не дает ошибок, но testthat повторяется Error: attempt to apply non-function
.
Мои вопросы:
- При использовании
rm(Session)
, в в каком порядке будут завершены элементы BasexClient, SocketClass и QueryClass? Если сначала удалить SocketClass, то логично, что экземпляры QueryClass не могут быть закрыты, поскольку соединение с базой данных больше не существует. - Как можно управлять порядком finalize ()?
Бен