This commit is contained in:
Parashuram 2014-04-01 16:52:39 -07:00
Коммит ea51503e01
23 изменённых файлов: 4187 добавлений и 0 удалений

7
License.txt Normal file
Просмотреть файл

@ -0,0 +1,7 @@
Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use these files except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

57
README.md Normal file
Просмотреть файл

@ -0,0 +1,57 @@
WebSQL plugin for Apache Cordova
==================================
Adds WebSQL functionality as Apache Cordova Plugin implemetned on top of native SQLite database. Support of Windows Phone8 and Windows8.
### Sample usage ###
Plugin follows [WebDatabase](http://www.w3.org/TR/webdatabase/) specification, no special changes are required. See sample usage below.
var dbSize = 5 * 1024 * 1024; // 5MB
var db = openDatabase("Todo", "", "Todo manager", dbSize, function() {
console.log('db successfully opened or created');
});
db.transaction(function (tx) {
tx.executeSql("INSERT INTO todo(todo, added_on) VALUES (?,?)",
['my todo item', new Date()], onSuccess, onError);
});
### Installation Instructions ###
Plugin is [Apache Cordova CLI](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html) 3.x compliant.
1.Make sure an up-to-date version of Node.js is installed, then type the following command to install the [Cordova CLI](https://github.com/apache/cordova-cli):
npm install -g cordova
2.Create a project and add the platforms you want to support:
cordova create sampleApp
cd sampleApp
cordova platform add windows8
cordova platform add wp8
3.Add WebSql plugin to your project:
cordova plugin add https://github.com/MSOpenTech/cordova-plugin-websql
4.Build and run, for example:
cordova build windows8
cordova emulate windows8
To learn more, read [Apache Cordova CLI Usage Guide](http://cordova.apache.org/docs/en/edge/guide_cli_index.md.html).
### Prerequisites ###
In order to build plugin for __Windows8__ target platform, you must manually install the [SQLite for Windows Runtime Extension SDK v3.8.2](http://sqlite.org/2013/sqlite-winrt-3080200.vsix).
### Quirks ###
* The db version, display name, and size parameter values are not supported and will be ignored
* rowsAffected and insertId properties of sqlResultSet are not supported http://www.w3.org/TR/webdatabase/#sqlresultset
* Every sql call is performed in its own transaction; so rollback for nested transactions is not supported.
### Copyrights ###
Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

55
plugin.xml Normal file
Просмотреть файл

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-->
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="com.msopentech.websql"
version="0.0.1">
<name>Web SQL plugin</name>
<description>Web Sql Plugin for Apache Cordova</description>
<license>Apache 2.0</license>
<keywords>cordova, websql, db, database</keywords>
<repo>TODO</repo>
<issue>TODO</issue>
<platform name="wp8">
<js-module src="www/WebSQL.js" name="WebSQL">
<merges target="window" />
</js-module>
<js-module src="www/Database.js" name="Database" />
<js-module src="www/SqlTransaction.js" name="SqlTransaction" />
<config-file target="config.xml" parent="/*">
<feature name="WebSql">
<param name="wp-package" value="WebSql"/>
</feature>
</config-file>
<source-file src="src/wp/WebSql.cs" />
<source-file src="src/wp/SQLite.cs" />
<framework src="src/wp/Community.CsharpSqlite.WinPhone.dll" custom="true"/>
</platform>
<platform name="windows8">
<js-module src="www/WebSQL.js" name="WebSQL">
<merges target="window" />
</js-module>
<js-module src="www/Database.js" name="Database" />
<js-module src="www/SqlTransaction.js" name="SqlTransaction" />
<framework src="src/windows8/SQLite.Proxy.winmd" custom="true"/>
<framework src="src/windows8/SQLitePCL.dll" custom="true"/>
<framework src="src/windows8/SQLitePCL.Ext.dll" custom="true"/>
<lib-file Include="Microsoft.VCLibs, version=11.0"/>
<lib-file Include="SQLite.WinRT, Version=3.8.2"/>
<js-module src="src/windows8/WebSqlProxy.js" name="WebSqlProxy">
<merges target="" />
</js-module>
<source-file src="src/windows8/cordova-plugin-websql.bat" target-dir="../../../../../hooks/before_build"/>
<source-file src="src/windows8/lib/cordova-plugin-websql.js" target-dir="../../../../../hooks/before_build/lib"/>
</platform>
</plugin>

Двоичные данные
src/windows8/SQLite.Proxy.winmd Normal file

Двоичный файл не отображается.

2
src/windows8/SQLite.Proxy/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,2 @@
/bin/
/obj/

Просмотреть файл

@ -0,0 +1,29 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SQLite.Proxy")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SQLite.Proxy")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]

Просмотреть файл

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\SQLitePCL.3.8.2.0\build\netcore45\SQLitePCL.props" Condition="Exists('..\packages\SQLitePCL.3.8.2.0\build\netcore45\SQLitePCL.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{E602BB9A-2446-4DF4-8B31-3E68A00277DB}</ProjectGuid>
<OutputType>winmdobj</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SQLite.Proxy</RootNamespace>
<AssemblyName>SQLite.Proxy</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<OutputPath>bin\ARM\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Compile Include="SQLiteProxy.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="SQLitePCL">
<HintPath>D:\Projects\Html5\git\cordova\cordova-plugin-websql\src\windows8\SQLitePCL.dll</HintPath>
</Reference>
<Reference Include="SQLitePCL.Ext">
<HintPath>D:\Projects\Html5\git\cordova\cordova-plugin-websql\src\windows8\SQLitePCL.Ext.dll</HintPath>
</Reference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '11.0' ">
<VisualStudioVersion>11.0</VisualStudioVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'x64|AnyCPU'">
<OutputPath>bin\x64\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'x64|ARM'">
<OutputPath>bin\ARM\x64\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'x64|x64'">
<OutputPath>bin\x64\x64\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'x64|x86'">
<OutputPath>bin\x86\x64\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ARM|AnyCPU'">
<OutputPath>bin\ARM\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ARM|ARM'">
<OutputPath>bin\ARM\ARM\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ARM|x64'">
<OutputPath>bin\x64\ARM\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ARM|x86'">
<OutputPath>bin\x86\ARM\</OutputPath>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,143 @@
/*
* Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
*/
using SQLitePCL;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
namespace SQLite.Proxy
{
public sealed class SQLiteProxy
{
public static string executeSql(string dbname, [ReadOnlyArray()] object[] args)
{
try
{
var query = (string)args[0];
var queryParams = (object[])args[1];
using (var connection = new SQLiteConnection(dbname))
{
using (var statement = connection.Prepare(query))
{
// pass query arguments
for (int argIdx = 0; argIdx < queryParams.Length; argIdx++)
{
// bind index starts from 1
statement.Bind(argIdx + 1, queryParams[argIdx]);
}
var resultSet = new SqlResultSet();
while (true)
{
var queryStatus = statement.Step();
if (queryStatus == SQLiteResult.ROW)
{
resultSet.Rows.Add(ReadResultSetRow(statement));
continue;
}
if (queryStatus == SQLiteResult.OK || queryStatus == SQLiteResult.DONE)
{
return Serialize(typeof(SqlResultSet), resultSet);
}
// ERROR
throw new Exception("Query failed with status: " + queryStatus);
}
}
}
}
catch (Exception ex)
{
// You can't access the original message text from JavaScript code.
// http://msdn.microsoft.com/en-US/library/windows/apps/br230301.aspx#ThrowingExceptions
// so we return it via custom object
return Serialize(typeof(InvocationError), new InvocationError(ex));
}
}
private class QueryRow : List<QueryColumn> { }
private class SqlResultSetRowList : List<QueryRow> { }
[DataContract]
private class SqlResultSet
{
[DataMember(Name = "insertId")]
public long InsertId;
[DataMember(Name = "rowsAffected")]
public long RowsAffected;
[DataMember(Name = "rows")]
public readonly SqlResultSetRowList Rows = new SqlResultSetRowList();
};
[DataContract]
private class QueryColumn
{
[DataMember]
public string Key;
[DataMember]
public object Value;
public QueryColumn(string key, object value)
{
Key = key;
Value = value;
}
}
[DataContract]
private class InvocationError
{
[DataMember(Name = "_invocationError")]
private string Error;
public InvocationError(Exception ex)
{
Error = ex.Message;
}
}
private static QueryRow ReadResultSetRow(ISQLiteStatement statement)
{
var row = new QueryRow();
int columnIdx = 0;
while (true)
{
var key = statement.ColumnName(columnIdx);
if (String.IsNullOrWhiteSpace(key))
{
break;
}
row.Add(new QueryColumn(key, statement[columnIdx]));
columnIdx++;
}
return row;
}
private static string Serialize(Type type, object obj)
{
using (var stream = new MemoryStream())
{
var jsonSer = new DataContractJsonSerializer(type);
jsonSer.WriteObject(stream, obj);
stream.Position = 0;
return new StreamReader(stream).ReadToEnd();
}
}
}
}

Двоичные данные
src/windows8/SQLitePCL.Ext.dll Normal file

Двоичный файл не отображается.

Двоичные данные
src/windows8/SQLitePCL.dll Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,46 @@
/*
* Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
*/
module.exports = {
db: null,
open: function (success, fail, args) {
try {
this.db = args[0];
success();
} catch(ex) {
fail(ex);
}
},
close: function (success, fail, args) {
try {
this.db = null;
success();
} catch (ex) {
fail(ex);
}
},
executeSql: function (success, fail, args) {
try {
var res = SQLite.Proxy.SQLiteProxy.executeSql(this.db, args);
res = JSON.parse(res);
// You can't access the original message text from JavaScript code.
// http://msdn.microsoft.com/en-US/library/windows/apps/br230301.aspx#ThrowingExceptions
// so we return it via custom object
if (res && res._invocationError) {
fail(new Error(res._invocationError));
return;
}
success(res);
} catch(ex) {
fail(ex);
}
},
};
require("cordova/windows8/commandProxy").add("WebSql", module.exports);

Просмотреть файл

@ -0,0 +1,3 @@
@ECHO OFF
SET full_path=%~dp0
cscript "%full_path%lib\cordova-plugin-websql.js" %0 //nologo

122
src/windows8/lib/cordova-plugin-websql.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,122 @@
/*
* Copyright (c) Microsoft Open Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
var fso = WScript.CreateObject('Scripting.FileSystemObject');
var wscript_shell = WScript.CreateObject("WScript.Shell");
// logs messaged to stdout and stderr
function Log(msg, error) {
if (error) {
WScript.StdErr.WriteLine(msg);
}
else {
WScript.StdOut.WriteLine(msg);
}
}
// returns the contents of a file
function read(filename) {
if (fso.FileExists(filename)) {
var f=fso.OpenTextFile(filename, 1,2);
var s=f.ReadAll();
f.Close();
return s;
}
else {
Log('Cannot read non-existant file : ' + filename, true);
WScript.Quit(2);
}
return null;
}
// writes content to a file
function write(filename, content) {
var f=fso.OpenTextFile(filename, 2,2);
f.Write(content);
f.Close();
}
function getFileByExtension(path, ext) {
var proj_folder = fso.GetFolder(path);
var proj_files = new Enumerator(proj_folder.Files);
for (;!proj_files.atEnd(); proj_files.moveNext()) {
if (fso.GetExtensionName(proj_files.item()) == ext) {
return path + '\\' + fso.GetFileName(proj_files.item());
}
}
return null;
}
function patchProject(path) {
Log('Patching windows8 project file:');
var projFile = getFileByExtension(path, 'jsproj');
if (projFile == null) {
Log('Project file not found', true);
return;
};
Log('\t' + projFile);
var projContent = read(projFile);
if (projContent.indexOf('SQLite.WinRT81, Version=3.8.2') > 0) {
Log('Already patched, skip...');
return;
}
var patch = '<ItemGroup>' +
'<SDKReference Include="Microsoft.VCLibs, version=12.0" />' +
'<SDKReference Include="SQLite.WinRT81, Version=3.8.2" />' +
'</ItemGroup>';
projContent = projContent.replace('</Project>', patch + '</Project>');
write(projFile, projContent);
}
function patchSolution(path) {
Log('Patching windows8 solution file:');
var projFile = getFileByExtension(path, 'sln');
if (projFile == null) {
Log('Solution file not found', true);
return;
};
Log('\t' + projFile);
var projContent = read(projFile);
if (projContent.indexOf('ActiveCfg = Debug|Any CPU') <= 0) {
Log('Already patched, skip...');
return;
}
projContent = projContent.replace('ActiveCfg = Debug|Any CPU', 'ActiveCfg = Debug|x64');
projContent = projContent.replace('Build.0 = Debug|Any CPU', 'Build.0 = Debug|x64');
projContent = projContent.replace('Deploy.0 = Debug|Any CPU', 'Deploy.0 = Debug|x64');
write(projFile, projContent);
}
if ('windows8' != wscript_shell.ExpandEnvironmentStrings("%CORDOVA_PLATFORMS%")) {
Log('Platform is not windows8, skip..');
} else {
var root = WScript.ScriptFullName.split('\\hooks\\before_build\\lib\\cordova-plugin-websql.js').join('');
var projRoot = root + '\\platforms\\windows8';
// not required anymore since plugman now provides <lib-file/>
//patchProject(projRoot);
patchSolution(projRoot);
}

Двоичные данные
src/wp/Community.CsharpSqlite.WinPhone.dll Normal file

Двоичный файл не отображается.

3060
src/wp/SQLite.cs Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

150
src/wp/WebSql.cs Normal file
Просмотреть файл

@ -0,0 +1,150 @@
/*
* Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
*/
using System;
using System.Linq;
using System.Runtime.Serialization;
using System.Collections.Generic;
using SQLite;
using WPCordovaClassLib.Cordova;
using WPCordovaClassLib.Cordova.Commands;
using WPCordovaClassLib.Cordova.JSON;
using System.Text.RegularExpressions;
namespace Cordova.Extension.Commands
{
/// <summary>
/// Apache Cordova plugin for WebSql
/// </summary>
public class WebSql : BaseCommand
{
public class QueryRow : List<QueryColumn> {}
public class SqlResultSetRowList : List<QueryRow> {}
[DataContract]
public class SqlResultSet
{
[DataMember(Name = "insertId")]
public long InsertId;
[DataMember(Name = "rowsAffected")]
public long RowsAffected;
[DataMember(Name = "rows")]
public SqlResultSetRowList Rows = new SqlResultSetRowList();
};
[DataContract]
public class QueryColumn
{
[DataMember]
public string Key;
[DataMember]
public object Value;
public QueryColumn(string key, object value)
{
Key = key;
Value = value;
}
}
/// <summary>
/// Represents database path.
/// </summary>
private string _dbName = "";
/// <summary>
/// Represents database connection instance.
/// </summary>
private SQLiteConnection _db;
/// <summary>
/// Opens existing database or creates a new one with the file name specified.
/// We don't test connection to the database here, we just save database name for further access.
/// </summary>
/// <param name="options"></param>
public void open(string options)
{
try
{
var args = JsonHelper.Deserialize<List<string>>(options);
String dbName = args[0];
if (string.IsNullOrEmpty(dbName))
{
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, "No database name provided"));
return;
}
_dbName = dbName;
}
catch (Exception ex)
{
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ex.Message));
}
}
/// <summary>
/// Closes connection to database.
/// </summary>
/// <param name="options"></param>
public void close(string options)
{
if (_db != null)
{
_db.Dispose();
_db = null;
}
DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
}
/// <summary>
/// Executes SQL query.
/// </summary>
/// <param name="options"></param>
public void executeSql(string options)
{
var args = JsonHelper.Deserialize<List<string>>(options);
try
{
if (_db == null)
_db = new SQLiteConnection(_dbName);
var query = args[0];
var queryParams = string.IsNullOrEmpty(args[1])
? new object[0]
: JsonHelper.Deserialize<object[]>(args[1]);
_db.RunInTransaction(() =>
{
if (query.IndexOf("DROP TABLE", StringComparison.OrdinalIgnoreCase) >= 0)
{
//-- bug where drop tabe does not work
query = Regex.Replace(query, "DROP TABLE IF EXISTS", "DELETE FROM", RegexOptions.IgnoreCase);
query = Regex.Replace(query, "DROP TABLE", "DELETE FROM", RegexOptions.IgnoreCase);
}
var resultSet = new SqlResultSet();
foreach (var row in _db.Query2(query, queryParams))
{
var resultRow = new QueryRow();
resultRow.AddRange(row.column.Select(column => new QueryColumn(column.Key, column.Value)));
resultSet.Rows.Add(resultRow);
}
DispatchCommandResult(new PluginResult(PluginResult.Status.OK, resultSet));
});
}
catch (Exception ex)
{
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ex.Message));
}
}
}
}

120
test/css/index.css Normal file
Просмотреть файл

@ -0,0 +1,120 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
* {
-webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */
}
body {
-webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */
-webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */
-webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */
background-color:#E4E4E4;
background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%);
background-image:-webkit-gradient(
linear,
left top,
left bottom,
color-stop(0, #A7A7A7),
color-stop(0.51, #E4E4E4)
);
background-attachment:fixed;
font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif;
font-size:12px;
height:100%;
margin:0px;
padding:0px;
text-transform:uppercase;
width:100%;
}
/* Portrait layout (default) */
.app {
background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */
position:absolute; /* position in the center of the screen */
left:50%;
top:50%;
height:50px; /* text area height */
width:225px; /* text area width */
text-align:center;
padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */
margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */
/* offset horizontal: half of text area width */
}
/* Landscape layout (with min-width) */
@media screen and (min-aspect-ratio: 1/1) and (min-width:400px) {
.app {
background-position:left center;
padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */
margin:-90px 0px 0px -198px; /* offset vertical: half of image height */
/* offset horizontal: half of image width and text area width */
}
}
h1 {
font-size:24px;
font-weight:normal;
margin:0px;
overflow:visible;
padding:0px;
text-align:center;
}
.event {
border-radius:4px;
-webkit-border-radius:4px;
color:#FFFFFF;
font-size:12px;
margin:0px 30px;
padding:2px 0px;
}
.event.listening {
background-color:#333333;
display:block;
}
.event.received {
background-color:#4B946A;
display:none;
}
@keyframes fade {
from { opacity: 1.0; }
50% { opacity: 0.4; }
to { opacity: 1.0; }
}
@-webkit-keyframes fade {
from { opacity: 1.0; }
50% { opacity: 0.4; }
to { opacity: 1.0; }
}
.blink {
animation:fade 3000ms infinite;
-webkit-animation:fade 3000ms infinite;
}
input, button {
margin: 4px;
width: 70%;
}

Двоичные данные
test/img/logo.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 21 KiB

39
test/index.html Normal file
Просмотреть файл

@ -0,0 +1,39 @@
<!DOCTYPE html>
<!--
Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-->
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<!-- WARNING: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 -->
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
<title>Hello World</title>
<script type="text/javascript">
window.onerror = function(msg) {
console.log('Err: ' + msg);
}
</script>
</head>
<body>
<div class="app">
<h1>Apache Cordova</h1>
<div id="deviceready" class="blink">
<p class="event listening">Connecting to Device</p>
<p class="event received">Device is Ready</p>
</div>
<button id="btnOpenDb">Open Database</button>
<button id="btnCreateTable">Create/Open Table</button>
<input type='text' id="lblTodoText" value="Sample item"/>
<button id="btnAddItem">Add item</button>
<p id="lblInfo"></p>
</div>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript">
app.initialize();
</script>
</body>
</html>

109
test/js/index.js Normal file
Просмотреть файл

@ -0,0 +1,109 @@
/*
* Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
*/
var app = {
// based on http://www.html5rocks.com/en/tutorials/webdatabase/todo/ sample by Paul Kinlan
// Application Constructor
initialize: function () {
this.db = null;
this.bindEvents();
window.onError = this.onError;
},
onError: function (msg) {
console.log('Error: ' + msg);
document.getElementById("lblInfo").innerHTML = 'ERROR: ' + msg;
},
onSuccess: function (msg) {
console.log('Operation completed successfully');
app.getAllTodoItems();
},
openDatabase: function () {
var dbSize = 5 * 1024 * 1024; // 5MB
// open database
app.db = openDatabase("Todo", "", "Todo manager", dbSize, function() {
console.log('db successfully opened or created');
});
},
createTable: function () {
app.db.transaction(function (tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS todo(ID INTEGER PRIMARY KEY ASC, todo TEXT, added_on DATETIME)", [],
app.onSuccess, app.onError);
});
},
addTodo: function (text) {
app.db.transaction(function (tx) {
var ts = new Date();
tx.executeSql("INSERT INTO todo(todo, added_on) VALUES (?,?)", [text, ts], app.onSuccess, app.onError);
});
},
getAllTodoItems: function () {
app.db.transaction(function (tx) {
tx.executeSql("SELECT * FROM todo", [], app.loadTodoItems, app.onError);
});
},
deleteTodo: function (id) {
console.log('Delete item: ' + id);
app.db.transaction(function (tx) {
tx.executeSql("DELETE FROM todo WHERE ID=?", [id], app.onSuccess, app.onError);
});
},
loadTodoItems: function (tx, rs) {
var rowOutput = "",
todoItems = document.getElementById("lblInfo"),
row;
for (var i = 0; i < rs.rows.length; i++) {
row = rs.rows.item(i);
rowOutput += "<li>" + row.todo + " [<a href='javascript:void(0);' onclick=\'app.deleteTodo(" +
row.ID + ");\'>Delete</a>]</li>";
}
if (typeof window.MSApp != 'undefined') {
MSApp.execUnsafeLocalFunction(function () {
todoItems.innerHTML = rowOutput;
});
} else {
todoItems.innerHTML = rowOutput;
}
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function () {
document.addEventListener('deviceready', this.onDeviceReady, false);
document.getElementById('btnOpenDb').addEventListener('click', this.openDatabase);
document.getElementById('btnCreateTable').addEventListener('click', this.createTable);
document.getElementById('btnAddItem').addEventListener('click', function () {
var text = document.getElementById('lblTodoText').value;
app.addTodo(text);
});
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicity call 'app.receivedEvent(...);'
onDeviceReady: function () {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function (id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};

32
www/Database.js Normal file
Просмотреть файл

@ -0,0 +1,32 @@
/*
* Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
*/
var exec = require('cordova/exec');
SqlTransaction = require('./SqlTransaction');
var Database = function (name, version, displayName, estimatedSize, creationCallback) {
// // Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback
// TODO: duplicate native error messages
if (!name) {
throw new Error('Database name can\'t be null or empty');
}
this.name = name;
this.version = version; // not supported
this.displayName = displayName; // not supported
this.estimatedSize = estimatedSize; // not supported
exec(creationCallback, null, "WebSql", "open", [this.name]);
};
Database.prototype.transaction = function (cb) {
var tx = new SqlTransaction();
setTimeout(function () {
cb(tx);
}, 0);
};
Database.prototype.readTransaction = Database.prototype.transaction;
module.exports = Database;

48
www/SqlTransaction.js Normal file
Просмотреть файл

@ -0,0 +1,48 @@
/*
* Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
*/
var exec = require('cordova/exec');
// http://www.w3.org/TR/webdatabase/#sqltransaction
var SqlTransaction = function() {
};
SqlTransaction.prototype.executeSql = function(sql, params, onSuccess, onError) {
if (!sql) {
throw new Error('sql query can\'t be null or empty');
}
var me = this;
this.sql = sql;
this.params = params;
this.successCallback = function (res) {
// add missing .item() method as per http://www.w3.org/TR/webdatabase/#sqlresultset
res.rows.item = function(index) {
if (index < 0 || index >= res.rows.length) {
return null;
}
return res.rows[index];
};
for (idxRow = 0; idxRow < res.rows.length; idxRow++) {
var row = res.rows[idxRow];
for (idxColumn = 0; idxColumn < row.length; idxColumn++) {
row[row[idxColumn].Key] = row[idxColumn].Value;
}
}
onSuccess(me, res);
};
this.errorCallback = onError;
try {
exec(this.successCallback, this.errorCallback, "WebSql", "executeSql", [this.sql, this.params]);
} catch(ex) {
errorCallback(ex);
}
};
module.exports = SqlTransaction;

16
www/WebSql.js Normal file
Просмотреть файл

@ -0,0 +1,16 @@
/*
* Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
*/
var Database = require('./Database');
// http://www.w3.org/TR/webdatabase/
var WebSQL = {};
// Database openDatabase(in DOMString name, in DOMString version, in DOMString displayName, in unsigned long estimatedSize, in optional DatabaseCallback creationCallback
// http://www.w3.org/TR/webdatabase/#databases
WebSQL.openDatabase = function (name, version, displayName, estimatedSize, creationCallback) {
return new Database(name, version, displayName, estimatedSize, creationCallback);
};
module.exports = WebSQL;