Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to use Anki 2.1.54's code #202

Merged
merged 61 commits into from
Jun 27, 2022
Merged

Conversation

dae
Copy link
Contributor

@dae dae commented Jun 16, 2022

Requires the following branch: ankidroid/anki#2

  • Updates David's previous work to work with the latest desktop code.
  • Most of the Rust code has been moved into the branch above; only about
    120 lines of Rust remain here, to implement the small JNI interface. The
    AnkiDroid-specific routines flow through the same backend call interface
    as the other backend code, with errors handled correctly.
  • Migrates the code to Kotlin. The tests remain in Java - I couldn't
    figure out how to get the Kotlin plugin working on the tests. The conversion
    introduced some warnings on compile that should probably be addressed at one
    point.
  • Translations are now included as part of the build, including statically-typed
    accessors in Kotlin.
  • The code generation from the proto files now targets Kotlin, and marks
    input arguments as non-optional unless they've been explicitly declared
    as nullable in the proto files.

Some design notes:

There are some warnings showing that were introduced as part of the Kotlin conversion,
that can be fixed in a future commit.

Closes #209
Closes #175
Related #168 (was 'closes' but it currently stops on 1.58.1, so does not close although moves us from rust 1.54)
Closes #133
Closes #36
Closes #24
Closes #22
Closes #21
Closes #18
Closes #17
Closes #2

dae added a commit to ankitects/Anki-Android that referenced this pull request Jun 16, 2022
Depends on ankidroid/Anki-Android-Backend#202

Due to the removal and change of a few backend methods, syncing, importing
and the card templates screen will not work when the schema16 setting is
active (actually schema18 now). To get them working again, those code
paths will need to switch to the backend implementations.

A few notes:
- Downgrading happens automatically when loading the collection in schema11
mode, so the extra code dealing with downgrades & "can downgrade" reporting
can be stripped.
- Added the ability to run col.set_config("key", JSONObject.NULL), as
unit tests were attempting to write the entire collection config, which is
no longer supported.
- All tests pass on both old and new backends, though the latter required
disabling a few failed tests when running with the new schema
(eg notetype updating).

Integrates, and thus closes ankidroid#11579 and closes ankidroid#11581
@david-allison
Copy link
Member

david-allison commented Jun 16, 2022

This is a lot to review. I've had a skim and this looks good. Very happy to see BackendMutex going.

Could we limit the translations to the following, as that should produce a well-needed reduction in apk size and serves as a stopgap before we think about combining CrowdIn and Pontoon

        "af", "am", "ar", "az", "be", "bg", "bn", "ca", "ckb", "cs", "da",
        "de", "el", "en", "eo", "es-AR", "es-ES", "et", "eu", "fa", "fi", "fil", "fr", "fy-NL", "ga-IE", "gl", "got",
        "gu-IN", "heb", "hi", "hr", "hu", "hy-AM", "ind", "is", "it", "ja", "jv", "ka", "kk", "km", "kn", "ko", "ku",
        "ky", "lt", "lv", "mk", "ml-IN", "mn", "mr", "ms", "my", "nl", "nn-NO", "no", "or", "pa-IN", "pl", "pt-BR", "pt-PT",
        "ro", "ru", "sat", "sc", "sk", "sl", "sq", "sr", "ss", "sv-SE", "sw", "ta", "te", "tg", "tgl", "th", "ti", "tn", "tr",
        "ts", "tt-RU", "uk", "ur-PK", "uz", "ve", "vi", "wo", "xh", "yue", "zh-CN", "zh-TW", "zu"

'yue' is 'Cantonese', 'heb' is 'Hebrew', 'ind' is Indonesian (gotta love Android). I think the rest are standardized.

(For discussion) I'd prefer to stick to the 'standard' Java convention for package names in the generated code. I don't care what that is, if we want to move away from ankiweb

I'd prefer to keep SemVer and accept that once this is out of beta, it will lead to 'breaking changes' in the library once CodeGen causes breaks

README.md Outdated Show resolved Hide resolved
@mikehardy
Copy link
Member

@david-allison

Could we limit the translations to the following, as that should produce a well-needed reduction in apk size and serves as a stopgap before we think about combining CrowdIn and Pontoon

should produce --> premature optimization. what's the size of the translations + size per translation + expected reduction?

@dae
Copy link
Contributor Author

dae commented Jun 17, 2022

Translation size depends on how many strings are translated - almost full/almost empty examples:

[dae] code/droid/Anki-Android-Backend [new-anki]  % dua -A ftl/core/core/fr
  91.35 KB ftl/core/core/fr
[dae] code/droid/Anki-Android-Backend [new-anki]  % dua -A ftl/core/core/en-GB
   1.13 KB ftl/core/core/en-GB

AnkiMobile has fewer active languages, and I don't bother to strip them there. The key names are shared across languages, and likely compress well.

(For discussion) I'd prefer to stick to the 'standard' Java convention for package names in the generated code. I don't care what that is, if we want to move away from ankiweb

My thinking here is was that if you see a class imported from 'anki..', you can tell it's a DTO from the backend, and easily look it up in the .proto files or desktop code. And anki.decks.Deck is somewhat less awkward than net.ankiweb.anki.decks.Deck.
There are also other existing examples that don't follow reverse DNS notation, eg import java.util.Arrays, import androidx.sqlite.db.SupportSQLiteOpenHelper and so on.

@dae
Copy link
Contributor Author

dae commented Jun 17, 2022

The dependabot changes caused a conflict; I've rebased over them and updated the remaining deps in the last commit.

@dae
Copy link
Contributor Author

dae commented Jun 27, 2022

Feel free to push changes into this branch if you need to, it's easy enough to rebase over.

@david-allison
Copy link
Member

david-allison commented Jun 27, 2022

Got a warning when opening in Android Studio:

Compilation is not supported for following modules: Anki-Android-Backend. Unfortunately you can't have non-Gradle Java modules and Android-Gradle modules in one project
One resolved error (to be peeled off into a docs update).
Traceback (most recent call last):
  File "./tools/genfluent/genfluent.py", line 31, in <module>
    modules = get_strings()
  File "./tools/genfluent/genfluent.py", line 26, in get_strings
    subprocess.run(["cargo", "run", output_file], check=True, cwd="rslib-bridge/anki/rslib/i18n")
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 493, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 858, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 1704, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'rslib-bridge/anki/rslib/i18n'

Resolution: Needed a submodule update

Unresolved

Traceback (most recent call last):
  File "./tools/genfluent/genfluent.py", line 31, in <module>
    modules = get_strings()
  File "./tools/genfluent/genfluent.py", line 26, in get_strings
    subprocess.run(["cargo", "run", output_file], check=True, cwd="rslib-bridge/anki/rslib/i18n")
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 493, in run
    with Popen(*popenargs, **kwargs) as process:
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 858, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/subprocess.py", line 1704, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'cargo'

Note:. "$HOME/.cargo/env" is in my .profile and .zprofile and cargo runs in a shell

@dae
Copy link
Contributor Author

dae commented Jun 27, 2022

genfluent.sh uses /bin/bash; is .cargo/env on the PATH of the parent process? If you're loading AS from the macOS GUI, it may not have inherited path changes if they only apply to login shells

@mikehardy
Copy link
Member

Hmm - I opened in Android Studio on Ubuntu with no issue. Haven't tried in my x86-64 osx-kvms yet or on my wife's m1 machine which I have to ask for time slices on ;-). Maybe mac specific but that is unexpected. I'm out of time for the day though - this is my last out-the-door comment then I'll try again my Monday morning

@dae
Copy link
Contributor Author

dae commented Jun 27, 2022

Note you'll need to do a ./gradlew clean after the latest commits, as the protobuf generation doesn't remove old files when generating new ones, and it appears to have broken the build in this case. (and will need to update subrepos)

@dae dae changed the title Update to use Anki 2.1.53's code Update to use Anki 2.1.54's code Jun 27, 2022
@david-allison
Copy link
Member

david-allison commented Jun 27, 2022

Thanks! Finder doesn't respect $PATH: https://apple.stackexchange.com/questions/51677/how-to-set-path-for-finder-launched-applications

launchctl setenv PATH $PATH
launchctl setenv RUST_ANDROID_GRADLE_PYTHON_COMMAND python3
killall Dock

It would be useful if setup-python was moved earlier on. python is required by linker-wrapper: https://github.com/mozilla/rust-android-gradle/blob/master/plugin/src/main/resources/com/nishtahir/linker-wrapper.sh

Alternately, this can be fixed by setting RUST_ANDROID_GRADLE_PYTHON_COMMAND

"/Users/davidallison/StudioProjects/Anki-Android-Backend/rslib-bridge/target/x86_64-linux-android/release/deps/librsdroid.so" "-shared" "-Wl,-zrelro,-znow" "-Wl,-O1" "-nodefaultlibs"
  = note: /Users/davidallison/StudioProjects/Anki-Android-Backend/build/linker-wrapper/linker-wrapper.sh: line 4: python: command not found

working directory is incorrect for protoc-gen.sh: PWD = /Users/davidallison/.gradle/daemon/6.8.3

Execution failed for task ':rsdroid:generateDebugProto'.
> protoc: stdout: . stderr: PWD = /Users/davidallison/.gradle/daemon/6.8.3
  /Users/davidallison/StudioProjects/Anki-Android-Backend/tools/protoc-gen/protoc-gen.sh: line 5: tools/setup-python: No such file or directory
  /Users/davidallison/StudioProjects/Anki-Android-Backend/tools/protoc-gen/protoc-gen.sh: line 6: ./tools/protoc-gen/protoc-gen.py: No such file or directory
  --anki_out: protoc-gen-anki: Plugin failed with status code 127.

Copy link
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(my approval still stands)

@mikehardy
Copy link
Member

Verified the rslib/anki commit hash is 2f7a0202976b3a400542b0a9bf5312c0e633472a and that hash is both the actual hash on ankidroid/anki#ankidroid-2.1.54 and the one committed here. So the bump to that looks clean 🚀 - back to checking integration here then merge + release

Something is rough on the whole submodule thing though. I basically just deleted my clone and made a new one in order for all the submodules to work well. Not a huge deal for me and probably a local problem but just noting it in case others get stuck. Killing a local clone and making a new one isn't that painful and it's a O(1) operation - always just a few minutes - vs troubleshooting

Copy link
Member

@mikehardy mikehardy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my last item was a "nice to have" on rslib/anki commit hash and the submodule thing. Both conclusively nailed. Let's launch this sucker

@mikehardy
Copy link
Member

It's a lot of commits but I like the commit history here, nearly all of them are important, I believe they all actually worked independently (so bisect will work) but we don't bisect a lot here and this change is so huge that bisect wouldn't be too useful before/after anyway. So I'm rebase merging

@mikehardy mikehardy merged commit 8e09b32 into ankidroid:main Jun 27, 2022
@mikehardy
Copy link
Member

mikehardy commented Jun 27, 2022

1- tagged it 0.1.14-anki2.1.54 to match version in properties file, pushed the tag
2- made a release from the tag with auto-generated release notes
3- built Apple Silicon dylib following #164 and added it to the release
4- kicked off the two sonatype publish builds and I'll log in to finalize them in half an hour or so after they are built

dae added a commit to ankitects/Anki-Android that referenced this pull request Jun 28, 2022
Simplify backend handling; rework collection instantiation

When the Rust code was initially introduced, it was not clear whether
it would be usable on all devices, or whether it would need to be removed
for some reason. This no doubt influenced the design of the existing API,
which tries to make it easy to swap the Rust code out with something else.

Unfortunately this approach has some downsides:

- It makes it somewhat harder to follow, as method calls jump through
multiple interfaces before they're actually sent to the backend.
- It makes utilizing new methods considerably more cumbersome.

For example, take the extract_av_tags() call. It follows the following
path:

collection method or method in related helper class:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt#L242

to generic interface:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/DroidBackend.kt#L83

to specific implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidV16Backend.kt#L57

and if it's unusable with the legacy schema (which I don't believe is
actually true in this case), it also needs to be added to the other
implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidBackend.kt#L87

and then finally, a method in the backend module is invoked.

The backend module has code generation so that invoking a backend method
is as simple as making a method call, but currently you have to weave
the call through 3 or so levels of indirection before you can actually
use it. With something like 170 available methods, that's a fair amount
of extra work required.

Rather than trying to insulate libanki from the backend code, this PR
drops some of the indirection in favour of the approach the desktop takes:
libanki is the insulation layer; it can call freely into the backend methods,
but consumers (eg the GUI code) are expected to only call methods on the
collection, and not access the backend directly.

In addition to the above, collection initialization has been reworked
to be more similar to the computer version. Instead of the collection
being created from a database object, a backend is passed into the
collection creation, and the collection takes care of creating a DB
instance that wraps the backend.

Remove always-on isUsingRustBackend

Drop the legacy upgrade/initialization code

Schema 11 was introduced in 2012, and decks that still are <11 are very
rare. The desktop dropped support for schema 10 back in early 2020.

This also removes the need to modify SCHEMA_VERSION when switching
between TESTING_USE_V16_BACKEND.

Remove DOWNGRADE_REQUIRED and slightly simplify startup error handling

- The backend automatically downgrades when required, and possible. No
backup is required, as the downgrade happens in a single transaction,
and the downgrade code has proven itself over time.
- Store the type of failure in getColSafe(), so it can be checked later.

Update to work with desktop 2.1.53 code

Depends on ankidroid/Anki-Android-Backend#202

Due to the removal and change of a few backend methods, syncing, importing
and the card templates screen will not work when the schema16 setting is
active (actually schema18 now). To get them working again, those code
paths will need to switch to the backend implementations.

A few notes:
- Downgrading happens automatically when loading the collection in schema11
mode, so the extra code dealing with downgrades & "can downgrade" reporting
can be stripped.
- Added the ability to run col.set_config("key", JSONObject.NULL), as
unit tests were attempting to write the entire collection config, which is
no longer supported.
- All tests pass on both old and new backends, though the latter required
disabling a few failed tests when running with the new schema
(eg notetype updating).

Integrates, and thus closes ankidroid#11579 and closes ankidroid#11581
dae added a commit to ankitects/Anki-Android that referenced this pull request Jun 28, 2022
Squashes a few commits:

Move the legacy schema toggle into BackendFactory

Simplify backend handling; rework collection instantiation

When the Rust code was initially introduced, it was not clear whether
it would be usable on all devices, or whether it would need to be removed
for some reason. This no doubt influenced the design of the existing API,
which tries to make it easy to swap the Rust code out with something else.

Unfortunately this approach has some downsides:

- It makes it somewhat harder to follow, as method calls jump through
multiple interfaces before they're actually sent to the backend.
- It makes utilizing new methods considerably more cumbersome.

For example, take the extract_av_tags() call. It follows the following
path:

collection method or method in related helper class:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt#L242

to generic interface:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/DroidBackend.kt#L83

to specific implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidV16Backend.kt#L57

and if it's unusable with the legacy schema (which I don't believe is
actually true in this case), it also needs to be added to the other
implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidBackend.kt#L87

and then finally, a method in the backend module is invoked.

The backend module has code generation so that invoking a backend method
is as simple as making a method call, but currently you have to weave
the call through 3 or so levels of indirection before you can actually
use it. With something like 170 available methods, that's a fair amount
of extra work required.

Rather than trying to insulate libanki from the backend code, this PR
drops some of the indirection in favour of the approach the desktop takes:
libanki is the insulation layer; it can call freely into the backend methods,
but consumers (eg the GUI code) are expected to only call methods on the
collection, and not access the backend directly.

In addition to the above, collection initialization has been reworked
to be more similar to the computer version. Instead of the collection
being created from a database object, a backend is passed into the
collection creation, and the collection takes care of creating a DB
instance that wraps the backend.

Remove always-on isUsingRustBackend

Drop the legacy upgrade/initialization code

Schema 11 was introduced in 2012, and decks that still are <11 are very
rare. The desktop dropped support for schema 10 back in early 2020.

This also removes the need to modify SCHEMA_VERSION when switching
between TESTING_USE_V16_BACKEND.

Remove DOWNGRADE_REQUIRED and slightly simplify startup error handling

- The backend automatically downgrades when required, and possible. No
backup is required, as the downgrade happens in a single transaction,
and the downgrade code has proven itself over time.
- Store the type of failure in getColSafe(), so it can be checked later.

Update to work with desktop 2.1.53 code

Depends on ankidroid/Anki-Android-Backend#202

Due to the removal and change of a few backend methods, syncing, importing
and the card templates screen will not work when the schema16 setting is
active (actually schema18 now). To get them working again, those code
paths will need to switch to the backend implementations.

A few notes:
- Downgrading happens automatically when loading the collection in schema11
mode, so the extra code dealing with downgrades & "can downgrade" reporting
can be stripped.
- Added the ability to run col.set_config("key", JSONObject.NULL), as
unit tests were attempting to write the entire collection config, which is
no longer supported.
- All tests pass on both old and new backends, though the latter required
disabling a few failed tests when running with the new schema
(eg notetype updating).

Integrates, and thus closes ankidroid#11579 and closes ankidroid#11581
dae added a commit to ankitects/Anki-Android that referenced this pull request Jun 28, 2022
Squashes a few commits:

Move the legacy schema toggle into BackendFactory

Simplify backend handling; rework collection instantiation

When the Rust code was initially introduced, it was not clear whether
it would be usable on all devices, or whether it would need to be removed
for some reason. This no doubt influenced the design of the existing API,
which tries to make it easy to swap the Rust code out with something else.

Unfortunately this approach has some downsides:

- It makes it somewhat harder to follow, as method calls jump through
multiple interfaces before they're actually sent to the backend.
- It makes utilizing new methods considerably more cumbersome.

For example, take the extract_av_tags() call. It follows the following
path:

collection method or method in related helper class:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt#L242

to generic interface:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/DroidBackend.kt#L83

to specific implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidV16Backend.kt#L57

and if it's unusable with the legacy schema (which I don't believe is
actually true in this case), it also needs to be added to the other
implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidBackend.kt#L87

and then finally, a method in the backend module is invoked.

The backend module has code generation so that invoking a backend method
is as simple as making a method call, but currently you have to weave
the call through 3 or so levels of indirection before you can actually
use it. With something like 170 available methods, that's a fair amount
of extra work required.

Rather than trying to insulate libanki from the backend code, this PR
drops some of the indirection in favour of the approach the desktop takes:
libanki is the insulation layer; it can call freely into the backend methods,
but consumers (eg the GUI code) are expected to only call methods on the
collection, and not access the backend directly.

In addition to the above, collection initialization has been reworked
to be more similar to the computer version. Instead of the collection
being created from a database object, a backend is passed into the
collection creation, and the collection takes care of creating a DB
instance that wraps the backend.

Remove always-on isUsingRustBackend

Drop the legacy upgrade/initialization code

Schema 11 was introduced in 2012, and decks that still are <11 are very
rare. The desktop dropped support for schema 10 back in early 2020.

This also removes the need to modify SCHEMA_VERSION when switching
between TESTING_USE_V16_BACKEND.

Remove DOWNGRADE_REQUIRED and slightly simplify startup error handling

- The backend automatically downgrades when required, and possible. No
backup is required, as the downgrade happens in a single transaction,
and the downgrade code has proven itself over time.
- Store the type of failure in getColSafe(), so it can be checked later.

Update to work with desktop 2.1.53 code

Depends on ankidroid/Anki-Android-Backend#202

Due to the removal and change of a few backend methods, syncing, importing
and the card templates screen will not work when the schema16 setting is
active (actually schema18 now). To get them working again, those code
paths will need to switch to the backend implementations.

A few notes:
- Downgrading happens automatically when loading the collection in schema11
mode, so the extra code dealing with downgrades & "can downgrade" reporting
can be stripped.
- Added the ability to run col.set_config("key", JSONObject.NULL), as
unit tests were attempting to write the entire collection config, which is
no longer supported.
- All tests pass on both old and new backends, though the latter required
disabling a few failed tests when running with the new schema
(eg notetype updating).

Integrates, and thus closes ankidroid#11579 and closes ankidroid#11581
mikehardy pushed a commit to ankidroid/Anki-Android that referenced this pull request Jun 29, 2022
Squashes a few commits:

Move the legacy schema toggle into BackendFactory

Simplify backend handling; rework collection instantiation

When the Rust code was initially introduced, it was not clear whether
it would be usable on all devices, or whether it would need to be removed
for some reason. This no doubt influenced the design of the existing API,
which tries to make it easy to swap the Rust code out with something else.

Unfortunately this approach has some downsides:

- It makes it somewhat harder to follow, as method calls jump through
multiple interfaces before they're actually sent to the backend.
- It makes utilizing new methods considerably more cumbersome.

For example, take the extract_av_tags() call. It follows the following
path:

collection method or method in related helper class:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt#L242

to generic interface:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/DroidBackend.kt#L83

to specific implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidV16Backend.kt#L57

and if it's unusable with the legacy schema (which I don't believe is
actually true in this case), it also needs to be added to the other
implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidBackend.kt#L87

and then finally, a method in the backend module is invoked.

The backend module has code generation so that invoking a backend method
is as simple as making a method call, but currently you have to weave
the call through 3 or so levels of indirection before you can actually
use it. With something like 170 available methods, that's a fair amount
of extra work required.

Rather than trying to insulate libanki from the backend code, this PR
drops some of the indirection in favour of the approach the desktop takes:
libanki is the insulation layer; it can call freely into the backend methods,
but consumers (eg the GUI code) are expected to only call methods on the
collection, and not access the backend directly.

In addition to the above, collection initialization has been reworked
to be more similar to the computer version. Instead of the collection
being created from a database object, a backend is passed into the
collection creation, and the collection takes care of creating a DB
instance that wraps the backend.

Remove always-on isUsingRustBackend

Drop the legacy upgrade/initialization code

Schema 11 was introduced in 2012, and decks that still are <11 are very
rare. The desktop dropped support for schema 10 back in early 2020.

This also removes the need to modify SCHEMA_VERSION when switching
between TESTING_USE_V16_BACKEND.

Remove DOWNGRADE_REQUIRED and slightly simplify startup error handling

- The backend automatically downgrades when required, and possible. No
backup is required, as the downgrade happens in a single transaction,
and the downgrade code has proven itself over time.
- Store the type of failure in getColSafe(), so it can be checked later.

Update to work with desktop 2.1.53 code

Depends on ankidroid/Anki-Android-Backend#202

Due to the removal and change of a few backend methods, syncing, importing
and the card templates screen will not work when the schema16 setting is
active (actually schema18 now). To get them working again, those code
paths will need to switch to the backend implementations.

A few notes:
- Downgrading happens automatically when loading the collection in schema11
mode, so the extra code dealing with downgrades & "can downgrade" reporting
can be stripped.
- Added the ability to run col.set_config("key", JSONObject.NULL), as
unit tests were attempting to write the entire collection config, which is
no longer supported.
- All tests pass on both old and new backends, though the latter required
disabling a few failed tests when running with the new schema
(eg notetype updating).

Integrates, and thus closes #11579 and closes #11581
mikehardy pushed a commit to ankidroid/Anki-Android that referenced this pull request Jun 29, 2022
Squashes a few commits:

Move the legacy schema toggle into BackendFactory

Simplify backend handling; rework collection instantiation

When the Rust code was initially introduced, it was not clear whether
it would be usable on all devices, or whether it would need to be removed
for some reason. This no doubt influenced the design of the existing API,
which tries to make it easy to swap the Rust code out with something else.

Unfortunately this approach has some downsides:

- It makes it somewhat harder to follow, as method calls jump through
multiple interfaces before they're actually sent to the backend.
- It makes utilizing new methods considerably more cumbersome.

For example, take the extract_av_tags() call. It follows the following
path:

collection method or method in related helper class:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt#L242

to generic interface:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/DroidBackend.kt#L83

to specific implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidV16Backend.kt#L57

and if it's unusable with the legacy schema (which I don't believe is
actually true in this case), it also needs to be added to the other
implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidBackend.kt#L87

and then finally, a method in the backend module is invoked.

The backend module has code generation so that invoking a backend method
is as simple as making a method call, but currently you have to weave
the call through 3 or so levels of indirection before you can actually
use it. With something like 170 available methods, that's a fair amount
of extra work required.

Rather than trying to insulate libanki from the backend code, this PR
drops some of the indirection in favour of the approach the desktop takes:
libanki is the insulation layer; it can call freely into the backend methods,
but consumers (eg the GUI code) are expected to only call methods on the
collection, and not access the backend directly.

In addition to the above, collection initialization has been reworked
to be more similar to the computer version. Instead of the collection
being created from a database object, a backend is passed into the
collection creation, and the collection takes care of creating a DB
instance that wraps the backend.

Remove always-on isUsingRustBackend

Drop the legacy upgrade/initialization code

Schema 11 was introduced in 2012, and decks that still are <11 are very
rare. The desktop dropped support for schema 10 back in early 2020.

This also removes the need to modify SCHEMA_VERSION when switching
between TESTING_USE_V16_BACKEND.

Remove DOWNGRADE_REQUIRED and slightly simplify startup error handling

- The backend automatically downgrades when required, and possible. No
backup is required, as the downgrade happens in a single transaction,
and the downgrade code has proven itself over time.
- Store the type of failure in getColSafe(), so it can be checked later.

Update to work with desktop 2.1.53 code

Depends on ankidroid/Anki-Android-Backend#202

Due to the removal and change of a few backend methods, syncing, importing
and the card templates screen will not work when the schema16 setting is
active (actually schema18 now). To get them working again, those code
paths will need to switch to the backend implementations.

A few notes:
- Downgrading happens automatically when loading the collection in schema11
mode, so the extra code dealing with downgrades & "can downgrade" reporting
can be stripped.
- Added the ability to run col.set_config("key", JSONObject.NULL), as
unit tests were attempting to write the entire collection config, which is
no longer supported.
- All tests pass on both old and new backends, though the latter required
disabling a few failed tests when running with the new schema
(eg notetype updating).

Integrates, and thus closes #11579 and closes #11581

refactor: Rename Storage.java to .kt

com.ichi2.libanki.Storage

refactor: Convert Storage to Kotlin

com.ichi2.libanki.Storage

Remove the time argument to Storage.collection()

Collection does not currently take a time argument, and relies on the
global object instead, so this change brings Storage in line with it.

Reuse the backend when closing+reopening a collection

Avoids having to re-initialize the translations, and reduces leaks
(the import + export code leaks backends still)
mikehardy pushed a commit to ankidroid/Anki-Android that referenced this pull request Jun 29, 2022
Squashes a few commits:

Move the legacy schema toggle into BackendFactory

Simplify backend handling; rework collection instantiation

When the Rust code was initially introduced, it was not clear whether
it would be usable on all devices, or whether it would need to be removed
for some reason. This no doubt influenced the design of the existing API,
which tries to make it easy to swap the Rust code out with something else.

Unfortunately this approach has some downsides:

- It makes it somewhat harder to follow, as method calls jump through
multiple interfaces before they're actually sent to the backend.
- It makes utilizing new methods considerably more cumbersome.

For example, take the extract_av_tags() call. It follows the following
path:

collection method or method in related helper class:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt#L242

to generic interface:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/DroidBackend.kt#L83

to specific implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidV16Backend.kt#L57

and if it's unusable with the legacy schema (which I don't believe is
actually true in this case), it also needs to be added to the other
implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidBackend.kt#L87

and then finally, a method in the backend module is invoked.

The backend module has code generation so that invoking a backend method
is as simple as making a method call, but currently you have to weave
the call through 3 or so levels of indirection before you can actually
use it. With something like 170 available methods, that's a fair amount
of extra work required.

Rather than trying to insulate libanki from the backend code, this PR
drops some of the indirection in favour of the approach the desktop takes:
libanki is the insulation layer; it can call freely into the backend methods,
but consumers (eg the GUI code) are expected to only call methods on the
collection, and not access the backend directly.

In addition to the above, collection initialization has been reworked
to be more similar to the computer version. Instead of the collection
being created from a database object, a backend is passed into the
collection creation, and the collection takes care of creating a DB
instance that wraps the backend.

Remove always-on isUsingRustBackend

Drop the legacy upgrade/initialization code

Schema 11 was introduced in 2012, and decks that still are <11 are very
rare. The desktop dropped support for schema 10 back in early 2020.

This also removes the need to modify SCHEMA_VERSION when switching
between TESTING_USE_V16_BACKEND.

Remove DOWNGRADE_REQUIRED and slightly simplify startup error handling

- The backend automatically downgrades when required, and possible. No
backup is required, as the downgrade happens in a single transaction,
and the downgrade code has proven itself over time.
- Store the type of failure in getColSafe(), so it can be checked later.

Update to work with desktop 2.1.53 code

Depends on ankidroid/Anki-Android-Backend#202

Due to the removal and change of a few backend methods, syncing, importing
and the card templates screen will not work when the schema16 setting is
active (actually schema18 now). To get them working again, those code
paths will need to switch to the backend implementations.

A few notes:
- Downgrading happens automatically when loading the collection in schema11
mode, so the extra code dealing with downgrades & "can downgrade" reporting
can be stripped.
- Added the ability to run col.set_config("key", JSONObject.NULL), as
unit tests were attempting to write the entire collection config, which is
no longer supported.
- All tests pass on both old and new backends, though the latter required
disabling a few failed tests when running with the new schema
(eg notetype updating).

Integrates, and thus closes #11579 and closes #11581
mikehardy pushed a commit to ankidroid/Anki-Android that referenced this pull request Jun 29, 2022
Squashes a few commits:

Move the legacy schema toggle into BackendFactory

Simplify backend handling; rework collection instantiation

When the Rust code was initially introduced, it was not clear whether
it would be usable on all devices, or whether it would need to be removed
for some reason. This no doubt influenced the design of the existing API,
which tries to make it easy to swap the Rust code out with something else.

Unfortunately this approach has some downsides:

- It makes it somewhat harder to follow, as method calls jump through
multiple interfaces before they're actually sent to the backend.
- It makes utilizing new methods considerably more cumbersome.

For example, take the extract_av_tags() call. It follows the following
path:

collection method or method in related helper class:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt#L242

to generic interface:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/DroidBackend.kt#L83

to specific implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidV16Backend.kt#L57

and if it's unusable with the legacy schema (which I don't believe is
actually true in this case), it also needs to be added to the other
implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidBackend.kt#L87

and then finally, a method in the backend module is invoked.

The backend module has code generation so that invoking a backend method
is as simple as making a method call, but currently you have to weave
the call through 3 or so levels of indirection before you can actually
use it. With something like 170 available methods, that's a fair amount
of extra work required.

Rather than trying to insulate libanki from the backend code, this PR
drops some of the indirection in favour of the approach the desktop takes:
libanki is the insulation layer; it can call freely into the backend methods,
but consumers (eg the GUI code) are expected to only call methods on the
collection, and not access the backend directly.

In addition to the above, collection initialization has been reworked
to be more similar to the computer version. Instead of the collection
being created from a database object, a backend is passed into the
collection creation, and the collection takes care of creating a DB
instance that wraps the backend.

Remove always-on isUsingRustBackend

Drop the legacy upgrade/initialization code

Schema 11 was introduced in 2012, and decks that still are <11 are very
rare. The desktop dropped support for schema 10 back in early 2020.

This also removes the need to modify SCHEMA_VERSION when switching
between TESTING_USE_V16_BACKEND.

Remove DOWNGRADE_REQUIRED and slightly simplify startup error handling

- The backend automatically downgrades when required, and possible. No
backup is required, as the downgrade happens in a single transaction,
and the downgrade code has proven itself over time.
- Store the type of failure in getColSafe(), so it can be checked later.

Update to work with desktop 2.1.53 code

Depends on ankidroid/Anki-Android-Backend#202

Due to the removal and change of a few backend methods, syncing, importing
and the card templates screen will not work when the schema16 setting is
active (actually schema18 now). To get them working again, those code
paths will need to switch to the backend implementations.

A few notes:
- Downgrading happens automatically when loading the collection in schema11
mode, so the extra code dealing with downgrades & "can downgrade" reporting
can be stripped.
- Added the ability to run col.set_config("key", JSONObject.NULL), as
unit tests were attempting to write the entire collection config, which is
no longer supported.
- All tests pass on both old and new backends, though the latter required
disabling a few failed tests when running with the new schema
(eg notetype updating).

Integrates, and thus closes #11579 and closes #11581

Remove the time argument to Storage.collection()

Collection does not currently take a time argument, and relies on the
global object instead, so this change brings Storage in line with it.

Reuse the backend when closing+reopening a collection

Avoids having to re-initialize the translations, and reduces leaks
(the import + export code leaks backends still)
mikehardy pushed a commit to ankitects/Anki-Android that referenced this pull request Jun 29, 2022
Squashes a few commits:

Move the legacy schema toggle into BackendFactory

Simplify backend handling; rework collection instantiation

When the Rust code was initially introduced, it was not clear whether
it would be usable on all devices, or whether it would need to be removed
for some reason. This no doubt influenced the design of the existing API,
which tries to make it easy to swap the Rust code out with something else.

Unfortunately this approach has some downsides:

- It makes it somewhat harder to follow, as method calls jump through
multiple interfaces before they're actually sent to the backend.
- It makes utilizing new methods considerably more cumbersome.

For example, take the extract_av_tags() call. It follows the following
path:

collection method or method in related helper class:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt#L242

to generic interface:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/DroidBackend.kt#L83

to specific implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidV16Backend.kt#L57

and if it's unusable with the legacy schema (which I don't believe is
actually true in this case), it also needs to be added to the other
implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidBackend.kt#L87

and then finally, a method in the backend module is invoked.

The backend module has code generation so that invoking a backend method
is as simple as making a method call, but currently you have to weave
the call through 3 or so levels of indirection before you can actually
use it. With something like 170 available methods, that's a fair amount
of extra work required.

Rather than trying to insulate libanki from the backend code, this PR
drops some of the indirection in favour of the approach the desktop takes:
libanki is the insulation layer; it can call freely into the backend methods,
but consumers (eg the GUI code) are expected to only call methods on the
collection, and not access the backend directly.

In addition to the above, collection initialization has been reworked
to be more similar to the computer version. Instead of the collection
being created from a database object, a backend is passed into the
collection creation, and the collection takes care of creating a DB
instance that wraps the backend.

Remove always-on isUsingRustBackend

Drop the legacy upgrade/initialization code

Schema 11 was introduced in 2012, and decks that still are <11 are very
rare. The desktop dropped support for schema 10 back in early 2020.

This also removes the need to modify SCHEMA_VERSION when switching
between TESTING_USE_V16_BACKEND.

Remove DOWNGRADE_REQUIRED and slightly simplify startup error handling

- The backend automatically downgrades when required, and possible. No
backup is required, as the downgrade happens in a single transaction,
and the downgrade code has proven itself over time.
- Store the type of failure in getColSafe(), so it can be checked later.

Update to work with desktop 2.1.53 code

Depends on ankidroid/Anki-Android-Backend#202

Due to the removal and change of a few backend methods, syncing, importing
and the card templates screen will not work when the schema16 setting is
active (actually schema18 now). To get them working again, those code
paths will need to switch to the backend implementations.

A few notes:
- Downgrading happens automatically when loading the collection in schema11
mode, so the extra code dealing with downgrades & "can downgrade" reporting
can be stripped.
- Added the ability to run col.set_config("key", JSONObject.NULL), as
unit tests were attempting to write the entire collection config, which is
no longer supported.
- All tests pass on both old and new backends, though the latter required
disabling a few failed tests when running with the new schema
(eg notetype updating).

Integrates, and thus closes ankidroid#11579 and closes ankidroid#11581

Remove the time argument to Storage.collection()

Collection does not currently take a time argument, and relies on the
global object instead, so this change brings Storage in line with it.

Reuse the backend when closing+reopening a collection

Avoids having to re-initialize the translations, and reduces leaks
(the import + export code leaks backends still)
mikehardy pushed a commit to ankidroid/Anki-Android that referenced this pull request Jun 29, 2022
Squashes a few commits:

Move the legacy schema toggle into BackendFactory

Simplify backend handling; rework collection instantiation

When the Rust code was initially introduced, it was not clear whether
it would be usable on all devices, or whether it would need to be removed
for some reason. This no doubt influenced the design of the existing API,
which tries to make it easy to swap the Rust code out with something else.

Unfortunately this approach has some downsides:

- It makes it somewhat harder to follow, as method calls jump through
multiple interfaces before they're actually sent to the backend.
- It makes utilizing new methods considerably more cumbersome.

For example, take the extract_av_tags() call. It follows the following
path:

collection method or method in related helper class:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt#L242

to generic interface:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/DroidBackend.kt#L83

to specific implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidV16Backend.kt#L57

and if it's unusable with the legacy schema (which I don't believe is
actually true in this case), it also needs to be added to the other
implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidBackend.kt#L87

and then finally, a method in the backend module is invoked.

The backend module has code generation so that invoking a backend method
is as simple as making a method call, but currently you have to weave
the call through 3 or so levels of indirection before you can actually
use it. With something like 170 available methods, that's a fair amount
of extra work required.

Rather than trying to insulate libanki from the backend code, this PR
drops some of the indirection in favour of the approach the desktop takes:
libanki is the insulation layer; it can call freely into the backend methods,
but consumers (eg the GUI code) are expected to only call methods on the
collection, and not access the backend directly.

In addition to the above, collection initialization has been reworked
to be more similar to the computer version. Instead of the collection
being created from a database object, a backend is passed into the
collection creation, and the collection takes care of creating a DB
instance that wraps the backend.

Remove always-on isUsingRustBackend

Drop the legacy upgrade/initialization code

Schema 11 was introduced in 2012, and decks that still are <11 are very
rare. The desktop dropped support for schema 10 back in early 2020.

This also removes the need to modify SCHEMA_VERSION when switching
between TESTING_USE_V16_BACKEND.

Remove DOWNGRADE_REQUIRED and slightly simplify startup error handling

- The backend automatically downgrades when required, and possible. No
backup is required, as the downgrade happens in a single transaction,
and the downgrade code has proven itself over time.
- Store the type of failure in getColSafe(), so it can be checked later.

Update to work with desktop 2.1.53 code

Depends on ankidroid/Anki-Android-Backend#202

Due to the removal and change of a few backend methods, syncing, importing
and the card templates screen will not work when the schema16 setting is
active (actually schema18 now). To get them working again, those code
paths will need to switch to the backend implementations.

A few notes:
- Downgrading happens automatically when loading the collection in schema11
mode, so the extra code dealing with downgrades & "can downgrade" reporting
can be stripped.
- Added the ability to run col.set_config("key", JSONObject.NULL), as
unit tests were attempting to write the entire collection config, which is
no longer supported.
- All tests pass on both old and new backends, though the latter required
disabling a few failed tests when running with the new schema
(eg notetype updating).

Integrates, and thus closes #11579 and closes #11581

Remove the time argument to Storage.collection()

Collection does not currently take a time argument, and relies on the
global object instead, so this change brings Storage in line with it.

Reuse the backend when closing+reopening a collection

Avoids having to re-initialize the translations, and reduces leaks
(the import + export code leaks backends still)
dorrin-sot pushed a commit to dorrin-sot/Anki-Android that referenced this pull request Jul 14, 2022
Squashes a few commits:

Move the legacy schema toggle into BackendFactory

Simplify backend handling; rework collection instantiation

When the Rust code was initially introduced, it was not clear whether
it would be usable on all devices, or whether it would need to be removed
for some reason. This no doubt influenced the design of the existing API,
which tries to make it easy to swap the Rust code out with something else.

Unfortunately this approach has some downsides:

- It makes it somewhat harder to follow, as method calls jump through
multiple interfaces before they're actually sent to the backend.
- It makes utilizing new methods considerably more cumbersome.

For example, take the extract_av_tags() call. It follows the following
path:

collection method or method in related helper class:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt#L242

to generic interface:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/DroidBackend.kt#L83

to specific implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidV16Backend.kt#L57

and if it's unusable with the legacy schema (which I don't believe is
actually true in this case), it also needs to be added to the other
implementation:
https://github.com/ankidroid/Anki-Android/blob/cea79e1b077bc30e7eed8f37529002aae416d34d/AnkiDroid/src/main/java/com/ichi2/libanki/backend/RustDroidBackend.kt#L87

and then finally, a method in the backend module is invoked.

The backend module has code generation so that invoking a backend method
is as simple as making a method call, but currently you have to weave
the call through 3 or so levels of indirection before you can actually
use it. With something like 170 available methods, that's a fair amount
of extra work required.

Rather than trying to insulate libanki from the backend code, this PR
drops some of the indirection in favour of the approach the desktop takes:
libanki is the insulation layer; it can call freely into the backend methods,
but consumers (eg the GUI code) are expected to only call methods on the
collection, and not access the backend directly.

In addition to the above, collection initialization has been reworked
to be more similar to the computer version. Instead of the collection
being created from a database object, a backend is passed into the
collection creation, and the collection takes care of creating a DB
instance that wraps the backend.

Remove always-on isUsingRustBackend

Drop the legacy upgrade/initialization code

Schema 11 was introduced in 2012, and decks that still are <11 are very
rare. The desktop dropped support for schema 10 back in early 2020.

This also removes the need to modify SCHEMA_VERSION when switching
between TESTING_USE_V16_BACKEND.

Remove DOWNGRADE_REQUIRED and slightly simplify startup error handling

- The backend automatically downgrades when required, and possible. No
backup is required, as the downgrade happens in a single transaction,
and the downgrade code has proven itself over time.
- Store the type of failure in getColSafe(), so it can be checked later.

Update to work with desktop 2.1.53 code

Depends on ankidroid/Anki-Android-Backend#202

Due to the removal and change of a few backend methods, syncing, importing
and the card templates screen will not work when the schema16 setting is
active (actually schema18 now). To get them working again, those code
paths will need to switch to the backend implementations.

A few notes:
- Downgrading happens automatically when loading the collection in schema11
mode, so the extra code dealing with downgrades & "can downgrade" reporting
can be stripped.
- Added the ability to run col.set_config("key", JSONObject.NULL), as
unit tests were attempting to write the entire collection config, which is
no longer supported.
- All tests pass on both old and new backends, though the latter required
disabling a few failed tests when running with the new schema
(eg notetype updating).

Integrates, and thus closes ankidroid#11579 and closes ankidroid#11581

Remove the time argument to Storage.collection()

Collection does not currently take a time argument, and relies on the
global object instead, so this change brings Storage in line with it.

Reuse the backend when closing+reopening a collection

Avoids having to re-initialize the translations, and reduces leaks
(the import + export code leaks backends still)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment