Skip to content

Commit

Permalink
fix issue#534
Browse files Browse the repository at this point in the history
  • Loading branch information
jepiqueau committed Apr 22, 2024
1 parent fa0c4a9 commit f267782
Show file tree
Hide file tree
Showing 16 changed files with 680 additions and 344 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# 5.7.3-1 (2024-04-22)

### Chore

- Update to @capacitor/core@5.7.3
- Update to @capacitor/ios@5.7.3
- Update to @capacitor/android@5.7.3
- Update to @capacitor/cli@5.7.3
- Update to jeep-sqlite@2.7.0

### Bug Fixes

- Fix GetFromHTTPRequest not working issue#534 (Android,iOS, Electron)


# 5.7.2 (2024-04-09)

### Chore
Expand Down
Binary file modified android/.gradle/buildOutputCleanup/buildOutputCleanup.lock
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
package com.getcapacitor.community.database.sqlite.SQLite;

import java.net.MalformedURLException;
import android.content.Context;
import android.content.res.AssetManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

public class UtilsDownloadFromHTTP {

Expand All @@ -16,34 +20,46 @@ public class UtilsDownloadFromHTTP {
private final UtilsFile _uFile = new UtilsFile();

public void download(Context context, String fileUrl) throws Exception {
AssetManager assetManager = context.getAssets();
String fileName = fileUrl.substring(fileUrl.lastIndexOf('/') + 1);
String dbName = fileName;
Boolean isZip = false;
if (!fileName.contains("SQLite.db")) {
if (_uFile.getFileExtension((fileName)).equals("db")) {
dbName = fileName.substring(0, fileName.length() - 3) + "SQLite.db";
}
if (_uFile.isLast(fileName, ".zip")) {
isZip = true;
Boolean isZip = false;
String fileName = "";
try {
String[] fileDetails = getFileDetails(fileUrl);
fileName = fileDetails[0];
String extension = fileDetails[1];
if (!fileName.contains("SQLite.db")) {
switch(extension) {
case "db":
fileName = fileName.substring(0, fileName.length() - 3) + "SQLite.db";
break;
case "zip":
isZip = true;
break;
default:
throw new Exception("Unknown file type. Filename: " + fileName);
}
}

} catch (Exception e) {
throw new Exception(e.getMessage());
}


File cacheDir = context.getCacheDir();
String cachePath = cacheDir.getAbsolutePath();
String tmpFilePath = cachePath + File.separator + dbName;
String tmpFilePath = cachePath + File.separator + fileName;
String databasePath = _uFile.getDatabaseDirectoryPath(context);
File databaseDir = new File(databasePath);
try {
// delete file if exists in cache
Boolean isExists = _uFile.isPathExists(tmpFilePath);
if (isExists) {
_uFile.deleteFile(cachePath, dbName);
_uFile.deleteFile(cachePath, fileName);
}
downloadFileToCache(fileUrl, cachePath);
downloadFileToCache(fileUrl, fileName, cachePath);
if (isZip) {
_uFile.unzipCopyDatabase(cachePath, null, tmpFilePath, true);
// delete zip file from cache
_uFile.deleteFile(cachePath, dbName);
_uFile.deleteFile(cachePath, fileName);
}
// move files to database folder
_uFile.moveAllDBs(cacheDir, databaseDir);
Expand All @@ -52,55 +68,64 @@ public void download(Context context, String fileUrl) throws Exception {
}
}

public static void downloadFileToCache(String fileURL, String cacheDir) throws Exception {
public static String[] getFileDetails(String url) throws Exception {
try {
URL javaUrl = new URL(url);
String path = javaUrl.getPath();
String decodedPath = URLDecoder.decode(path, StandardCharsets.UTF_8.toString()); // Decode URL-encoded path
String filename = decodedPath.substring(decodedPath.lastIndexOf('/') + 1); // Extract filename from decoded path
String extension = getFileExtension(filename);
if(extension == null) {
throw new Exception("extension db or zip not found");
}
return new String[]{filename, extension};
} catch (MalformedURLException e) {
e.printStackTrace();
throw new Exception(e.getMessage());
}
}
public static String getFileExtension(String filename) {
Pattern pattern = Pattern.compile("\\.([a-zA-Z0-9]+)(?:[\\?#]|$)");
Matcher matcher = pattern.matcher(filename);

if (matcher.find()) {
return matcher.group(1).toLowerCase(); // returns the matched extension in lowercase
}

return null; // no extension found
}
public static void downloadFileToCache(String fileURL, String fileName, String cacheDir) throws Exception {
HttpURLConnection httpConn = null;
try {
URL url = new URL(fileURL);
httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestMethod("GET");
int responseCode = httpConn.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
String fileName = "";
String disposition = httpConn.getHeaderField("Content-Disposition");
// String contentType = httpConn.getContentType();
int contentLength = httpConn.getContentLength();

if (disposition != null) {
// extracts file name from header field
int index = disposition.indexOf("filename=");
if (index > 0) {
fileName = disposition.substring(index + 10, disposition.length() - 1);
}
} else {
// extracts file name from URL
fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1);
}
String dbName = fileName;
if (!fileName.contains("SQLite.db")) {
if (fileName.substring(fileName.length() - 3).equals(".db")) {
dbName = fileName.substring(0, fileName.length() - 3) + "SQLite.db";
}
}

// System.out.println("Content-Type = " + contentType);
// System.out.println("Content-Disposition = " + disposition);
// System.out.println("Content-Length = " + contentLength);
// System.out.println("fileName = " + fileName);
// opens input stream from the HTTP connection
InputStream inputStream = httpConn.getInputStream();
// create temporary file path
String tmpFilePath = cacheDir + File.separator + dbName;
// opens an output stream to save into file
FileOutputStream outputStream = new FileOutputStream(tmpFilePath);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
// opens input stream from the HTTP connection
try (InputStream inputStream = httpConn.getInputStream();
FileOutputStream outputStream = new FileOutputStream(tmpFilePath)) {

outputStream.close();
inputStream.close();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
outputStream.close();
inputStream.close();

System.out.println("File " + fileName + " downloaded (" + contentLength + ")");
System.out.println("File " + fileName + " downloaded (" + contentLength + ")");
}
} else {
String msg = "No file to download. Server replied HTTP code: " + responseCode;
throw new IOException(msg);
Expand Down
53 changes: 38 additions & 15 deletions electron/src/electron-utils/utilsFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,17 @@ export class UtilsFile {
* @returns
*/
public getExtName(filePath: string): string {
return this.Path.extname(filePath);

const matches = filePath.match(/\.([a-zA-Z0-9]+)(?:[\\?#]|$)/);
return matches ?`.${matches[1].toLowerCase()}` : ''; // returns the matched extension in lowercase

// return this.Path.extname(filePath);
}
public getBaseName(filePath: string): string {
return this.Path.basename(filePath, this.Path.extname(filePath));
const decodedUrl = decodeURIComponent(filePath); // Decode the URL component
const baseName = this.Path.basename(decodedUrl, this.Path.extname(filePath));
return baseName;

}
/**
* IsPathExists
Expand Down Expand Up @@ -236,34 +243,47 @@ export class UtilsFile {
overwrite: boolean,
): Promise<void> {
const pZip: string = this.Path.join(fPath, db);
// Read the Zip file
this.NodeFs.readFile(pZip, (err: any, data: any) => {
if (err) {
console.log(err);
return Promise.reject(`unzipDatabase ${JSON.stringify(err)}`);
}

try {
// Read the Zip file
const data = await this.NodeFs.promises.readFile(pZip);

const zip = new this.JSZip();
zip.loadAsync(data).then((contents: any) => {
Object.keys(contents.files).forEach(filename => {
const contents = await zip.loadAsync(data);

// Create an array to store promises for writing files
const writePromises: Promise<void>[] = [];

Object.keys(contents.files).forEach(filename => {
writePromises.push(
zip
.file(filename)
.async('nodebuffer')
.then(async (content: any) => {
const toDb: string = this.setPathSuffix(filename);
const pDb: string = this.Path.join(this.getDatabasesPath(), toDb);

// check filePath exists
const isPath = this.isPathExists(pDb);

if (!isPath || overwrite) {
if (overwrite && isPath) {
await this.deleteFilePath(pDb);
}
this.NodeFs.writeFileSync(pDb, content);
await this.NodeFs.promises.writeFile(pDb, content);
}
return Promise.resolve();
});
});
})
);
});
});

// Wait for all write promises to resolve
await Promise.all(writePromises);

return Promise.resolve();
} catch (err) {
console.log(err);
return Promise.reject(`unzipDatabase ${JSON.stringify(err)}`);
}
}
/**
* CopyFileName
Expand Down Expand Up @@ -541,6 +561,8 @@ export class UtilsFile {
}
}
}

return Promise.resolve();
}
/**
* RestoreFileName
Expand Down Expand Up @@ -594,6 +616,7 @@ export class UtilsFile {
res.body.on('error', reject);
fileStream.on('finish', resolve);
});

}
public readFileAsPromise(
path: string,
Expand Down
1 change: 1 addition & 0 deletions electron/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,7 @@ export class CapacitorSQLite implements CapacitorSQLitePlugin {
`getFromHTTPRequest: cannot move file from cache overwrite: ${overwrite}`,
);
}
return;
}

async getDatabaseList(): Promise<capSQLiteValues> {
Expand Down
25 changes: 13 additions & 12 deletions ios/Plugin/CapacitorSQLite.swift
Original file line number Diff line number Diff line change
Expand Up @@ -589,12 +589,9 @@ enum CapacitorSQLiteError: Error {
self.retHandler.rResult(call: call)
return
case .failure(let error):

if error == .downloadFromHTTPFailed {
let msg = "Download from HTTP failed"
self.retHandler.rResult(call: call, message: msg)
return
}
let msg = "Download from HTTP failed: \(error.localizedDescription)"
self.retHandler.rResult(call: call, message: msg)
return

}

Expand Down Expand Up @@ -1013,6 +1010,7 @@ enum CapacitorSQLiteError: Error {
// MARK: - deleteDatabase

// swiftlint:disable cyclomatic_complexity
// swiftlint:disable function_body_length
@objc func deleteDatabase(_ dbName: String, readonly: Bool) throws {
guard isInit else {
throw CapacitorSQLiteError.failed(message: initMessage)
Expand All @@ -1030,10 +1028,12 @@ enum CapacitorSQLiteError: Error {
do {
if !mDb.isDBOpen() {
// check the state of the DB
let state: State = UtilsSQLCipher.getDatabaseState(databaseLocation: databaseLocation, databaseName: "\(mDbName)SQLite.db", account: account)
if !isEncryption &&
(state.rawValue == "ENCRYPTEDGLOBALSECRET" ||
state.rawValue == "ENCRYPTEDSECRET") {
let state: State = UtilsSQLCipher.getDatabaseState(databaseLocation: databaseLocation,
databaseName: "\(mDbName)SQLite.db",
account: account)
if !isEncryption &&
(state.rawValue == "ENCRYPTEDGLOBALSECRET" ||
state.rawValue == "ENCRYPTEDSECRET") {
var msg = "Cannot delete an Encrypted database with "
msg += "No Encryption set in capacitor.config"
throw CapacitorSQLiteError.failed(message: msg)
Expand Down Expand Up @@ -1066,6 +1066,7 @@ enum CapacitorSQLiteError: Error {
throw CapacitorSQLiteError.failed(message: msg)
}
}
// swiftlint:enable function_body_length
// swiftlint:enable cyclomatic_complexity

// MARK: - isJsonValid
Expand Down Expand Up @@ -1547,7 +1548,7 @@ enum CapacitorSQLiteError: Error {
// get the database files
let dbList: [String] = try UtilsFile.getFileList(path: aPath, ext: ".db")
// filter for db including SQLite
let dbWithSQLite = dbList.filter { $0.contains("SQLite") }
let dbWithSQLite = dbList.filter({ $0.contains("SQLite") })

return dbWithSQLite

Expand All @@ -1567,7 +1568,7 @@ enum CapacitorSQLiteError: Error {
let dbList: [String] = try UtilsMigrate
.getMigratableList(folderPath: folderPath)
// filter for db not including SQLite
let dbNoSQLite = dbList.filter { !$0.contains("SQLite") }
let dbNoSQLite = dbList.filter({ !$0.contains("SQLite") })

return dbNoSQLite

Expand Down

0 comments on commit f267782

Please sign in to comment.