Modify Bennedum Sqlite Extension?

Dear @TIMAI2,
Can you help me?
I have an app using original Tom's extension and use many of it's functions (thus I can not use yr simplified extension).
There is however ExportDatabase that does not work due to an error in (obsolete) private function resolveFileName - so the fix is simple to remove it in the line :

os = new FileOutputStream(resolveFileName(fileName));

so that it reads

os = new FileOutputStream(fileName);

and have user prepare directory/filename (I know it will work only in ASD but it is Ok) .

However I do not have skill to compile such modified extension - can I ask you a favor to do it for me and I hope for other members too and repost it here?

I guess porting yr ListFixer would be nice but it is not a must as I have a workaround.
Best regards

Use my extension, it will do everything Tom's extension does.

Thanks for so quick answer !!!

Unfortunately, SimpleSqliteV3 does not have all functions of Tom's- in particular, the Upgrade and Async calls which my app uses heavily ... or there is another heavier version I missed ?
Best rgds, Kuba

It is a bit more complicated than that :slight_smile:

I do not see an "Upgrade" in the original extension? Do you mean Update ? If so, this can be handled with the appropriate SQL statement.

With regard to Async, I have chosen to not include it, in my view, 99% of situations can be handled with additional blocks. SimpleSqlite is intended to be...simple.

re May be more complicated, but filename is messed-up as part of it was duplicated (if u put anything as filename, set DebugDialog = true then u will see what I mean). It looked to me resolveFileName might have been responsible - of course I can't be sure until I compile it but my Android studio does not want to pull appinventor imports from appinventor repo (probably it is much more complex and I'm probably doing a lot of things wrong - this is why I'm seeking help with tooling)

re Upgrade - I meant functionality (being event DatabaseUpgrade) not function.

re Async - in case of this app I think it is needed as without it did ANR

Thanks again for you involvement !
Kuba sp5nzf

Good luck with the fork.

If it helps, this is some part of what I did:


  private InputStream openInputStream(final String fileName) throws IOException {
    if (fileName.startsWith("//")) {
      if (isRepl)
        return new FileInputStream(getReplFilePath() + fileName.substring(2));
        return context.getAssets().open(fileName.substring(2));
    } else
      return new FileInputStream(resolveFileName(fileName));

  private String resolveFileName(String fileName) {
    String completeFileName = fileName;
    if (fileName.startsWith("/")) {
      completeFileName = getExternalStoragePath() + fileName;
    } else if (fileName.startsWith("//")) {
      if (isRepl) {
        fileName = fileName.substring(2);
        completeFileName = getReplFilePath() + fileName;
    } else {
      completeFileName = GetPrivateDirPath() + "/" + fileName;
    return completeFileName;

  public String getExternalStoragePath(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
      return context.getExternalFilesDir(null).getAbsolutePath();
      return Environment.getExternalStorageDirectory().getAbsolutePath();

  public String GetPrivateDirPath(){
    return context.getFilesDir().getAbsolutePath();

  private String getReplFilePath(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
      return getExternalStoragePath() + "/assets/";
    } else {
    //  return getExternalStoragePath() + "/AppInventor/assets/";
      return context.getExternalFilesDir(null).getAbsolutePath() + "/AppInventor/assets/";

this is only thing it would do... but I can do it in blocks outside of extension. This is why I want to get rid of resolveFileName

So this IS easy. WHat is NOT easy is how to compile it (now I'm stack with no place to pull* from

Use Rush and Intellij Idea, copy the aix code over, edit as required (including removing all code not required in Rush), then compile.

thanks @TIMAI2 .
it looks like I have no clue how to make it find DesignerComponent component :frowning:
same for category in @SimpleProperty(category

good night

Dear @TIMAI2,
which JAVA do you use ?

The Rush docs says 16 but it throws an error that "Unsupported class file major version 60"

version 8, Rush also advises 8, unless you are desugaring some elements.

1 Like

Dear @TIMAI2 ,
Thanks a lot for support and inspiration !
It works and I'm testing Tab's extension fixed for ASD (4 functions: ImportDatabase, ExportDatabase, InsertFile, ExecuteFile). Will seek Your advice how to share once tested.

Dear All Beginners,
You will have to get rid of some Annotations to rush-compile extensions from Niotron etc - see Rush docs.

Hi @TIMAI2 ,

I am testing your extension and all works as expected. I just have a question for you. Why do we have to get a return from this block:


And why don't create a block without return, like this:


In order to not to be necessary put the "SQL Command executed" in a place, once we have ON ERROR triggering the result...

Of course we can turn the label to FALSE and not show it, but it could be interesting the way I said...

You will want the output (answer) from any query/sql you run.....
Just saves on another event block, and this is how it was done in the original extension, so I didn't change it.

As I have siad in my documentation:

I have forked this code, and stripped it back to make a barebones or expert sqlite extension, far fewer blocks, but retaining all the functionality.

Ok, thank you for your answer. Now my doubt is: I get data from a MySQL database and it return a JSON with names and data. How can I use this JSON to insert data into SQLite table?


You would need to parse the json values to be able to load them into a suitable sqlite table.

1 Like