Laden...

[gelöst] Windows RT: PhoneGap-App mit WebSQL portieren

Erstellt von Levion vor 10 Jahren Letzter Beitrag vor 10 Jahren 1.820 Views
Levion Themenstarter:in
114 Beiträge seit 2009
vor 10 Jahren
[gelöst] Windows RT: PhoneGap-App mit WebSQL portieren

Hi,

ich habe eine relativ umfangreiche PhoneGap-App die per WebSQL Daten speichert und ließt, die ich gerne nach Windows RT portieren möchte. WebSQL wird allerdings in JavaScript-Apps nicht unterstützt 🙄. Der Grund ist, dass die Apps in der IE 10 Engine laufen und da gibt es kein WebSQL. PhoneGap-Api-Doku.

Ich habe jetzt schon folgende Optionen überlegt:

LocalStorage/IndexedDB

In den sauren Apfel beißen und alles auf LocalStorage umbauen. Wie gesagt, die Anwendung ist recht umfangreich und darauf habe ich eigentlich am wenigesten Lust.

SQLite-Wrapper

Man kann offenbar Komponenten in C#/VB basteln um Funktionalitäten z.B. auch SQLLite verfügbar zu machen. Das finde ich eigentlich sehr elegant und man könnte daraus gleich ein PhoneGap-Plugin bauen. Der Aufwand ist allerdings auch nicht ohne.

Kennt jemand das Problem und kann vielleicht was dazu sagen?

Grüße

Levion Themenstarter:in
114 Beiträge seit 2009
vor 10 Jahren

Ich hab mitlerweile einen Weg gefunden mein Problem zu lösen. Ich hab zwei Varianten gefunden die recht vielversprechend sind.

SQLite3-WinRT
Das ist eine Komponente die den Zugriff auf SQLite-Funktionalität ermöglicht. Im Prinzip genau das, was ich bereits im vorhergegangenen Posting angedacht habe.

https://github.com/doo/SQLite3-WinRT

Lawnchair
Das ist eine JS-Library die als Wrapper für DOM, IndexDB, WebSQL etc. funktioniert. Wenn ich ein neues Projekt beginnen würde, würde ich evtl. diese Lib nehmen, weil man damit schnell die Persistenztechnik umschalten kann.

http://brian.io/lawnchair/

Fazit
Für meine Zwecke baue ich einen kleinen Layer, der zwischen WebSQL und SQLite3 schaltet.

A
2 Beiträge seit 2013
vor 10 Jahren

Für meine Zwecke baue ich einen kleinen Layer, der zwischen WebSQL und SQLite3 schaltet.

Hallo. Bevor ich das Rad doppelt erfinde: Ist der Quelltext davon verfügbar?

Levion Themenstarter:in
114 Beiträge seit 2009
vor 10 Jahren

Den Wrapper habe ich in TypeScript programmiert. Ich hoffe du kannst trotzdem was damit anfangen.


/**
\* @class Exception is fired if an error occurs
\*/
export class SQLError {

	/**
	* Constructor
	* @param code number Errorcode
	* @param message string Message of the error
	* @param statement string Statement that triggers this Exception
	*/
	constructor(private code: number, private message: string, private statement: string) {
	}

	public getCode(): number {
		return this.code;
	}

	public getMessage(): string {
		return this.message;
	}

	public getStatement(): string {
		return this.statement;
	}
}

/**
\* @interface The results of a statement
\*/
export interface SQLResultSet {
	insertId: number;
	rows: any;
	rowsAffected: number;
}

/*
\* @interface The main interface to describe SQL databases
\*/
export interface IDatabase {
	open(name: string, version: string, displayName: string, size: number, success: () => void , sqlError: (error: SQLError) => void ): void;
	executeSql(sql: string, args: any, success?: (results: SQLResultSet) => void , error?: (error: SQLError) => void );
}

/*
\* @class Wrapper for the native WebKit-SQL-Database
\*/
export class WebKitSQLDatabase implements IDatabase {

	private sqlError: (error: SQLError) => void;
	private database: any;
	private window: any;

	/**
	* Opens the database
	* @param name Name of database
	* @param version Version of database
	* @param displayName Displayed Name of database
	* @param size Size of database
	* @param success Callback if the opening was successfull
	* @param sqlError Callback if an error occured
	*/
	open(name: string, version: string, displayName: string, size: number, success: () => void , sqlError: (error: SQLError) => void ): void {
		this.sqlError = sqlError;
		this.window = <any>window;

		this.database = this.window.openDatabase(name, version, displayName, size, () => {
		});

		success();
	}

	/**
	* Executes the SQL
	* @param sql Statement to execute
	* @param args Arguments of statement
	* @param success Callback if the statement was successfull
	*/
	executeSql(sql: string, args: any, success?: (results: SQLResultSet) => void , errorCallback?: (error: SQLError) => void ) {

		console.log(sql + ", " + args);

		var millis = new Date().getTime();
		this.database.transaction(
				(transaction: any) => {
					transaction.executeSql(sql, args, (transaction: any, result: SQLResultSet) => {
						var insertId = undefined;

						try {
							insertId = result.insertId;
						} catch (e) {
						}

						var results: SQLResultSet = {
							insertId: insertId,
							rows: [],
							rowsAffected: result.rowsAffected
						};

						if (result.rows) {
							var len: number = result.rows.length;
							for (var i: number = 0; i < len; i++) {
								results.rows[i] = result.rows.item(i);
							}
						}
						console.log("Execution time: " + (new Date().getTime() - millis));
						if (success) success(results);
					});
				},
				(error: any) => {
					if (errorCallback)
						errorCallback(new SQLError(error.code, error.message, sql))
					else
						this.sqlError(new SQLError(error.code, error.message, sql));
				});
	}
}

declare var Windows: any;
declare var SQLite3JS: any;

/*
\* @class Wrapper for the SQLite3-WinRT-Wrapper-Database
\*/
export class SQLite3Database implements IDatabase {
	private sqlError: (error: SQLError) => void;
	private database: any;

	/**
	* Opens the database
	* @param name Name of database
	* @param version Version of database
	* @param displayName Displayed Name of database
	* @param size Size of database
	* @param success Callback if the opening was successfull
	* @param sqlError Callback if an error occured
	*/
	open(name: string, version: string, displayName: string, size: number, success: () => void , sqlError: (error: SQLError) => void ): void {
		var dbPath = Windows.Storage.ApplicationData.current.localFolder.path + '\\' + name + '.sqlite';

		SQLite3JS.openAsync(dbPath)
		.then((db) => {
			this.database = db;
			this.sqlError = sqlError;
			success();
		});
	}

	/**
	* Executes the SQL
	* @param sql Statement to execute
	* @param args Arguments of statement
	* @param success Callback if the statement was successfull
	*/
	executeSql(sql: string, args: any, success?: (results: SQLResultSet) => void , errorCallback?: (error: SQLError) => void ) {
		var results: SQLResultSet = {
			insertId: undefined,
			rows: [],
			rowsAffected: 0
		};

		this.database.eachAsync(sql, args, (row: any) => {
			if (row) {
				results.rows[results.rows.length] = row;
				results.rowsAffected++;
			}
		}).then(
			() => {
				if (this.database.lastInsertRowId) {
					results.insertId = this.database.lastInsertRowId;
					this.database.lastInsertRowId = undefined;
				}

				if (success) success(results);
			},
			(error) => {
				if (errorCallback)
					errorCallback(new SQLError(error.code, error.message, sql));
				else
					this.sqlError(new SQLError(error.code, error.message, sql));
			}
		);
	}
}

/**
\* Creates database object
\*/
export function getDatabase(): IDatabase {
	if (!!(<any>window).openDatabase) {
		return new WebKitSQLDatabase();
	} else {
		return new SQLite3Database();
	}
}

A
2 Beiträge seit 2013
vor 10 Jahren

Den Wrapper habe ich in
>
programmiert. Ich hoffe du kannst trotzdem was damit anfangen.

Ja, vielen Dank.