Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Merge branch 'ThreeOneOneRestart'

  • Loading branch information...
commit 17afda145ce771004bf45c8d20c00c08cda14ba0 2 parents 2a1b96f + 656a4b3
authored September 03, 2012

Showing 44 changed files with 1,256 additions and 247 deletions. Show diff stats Hide diff stats

  1. 2  examples/cpp/DatabaseTest/.mosyncproject
  2. 202  examples/cpp/DatabaseTest/main.cpp
  3. 4  examples/cpp/PurchaseExample/.mosyncproject
  4. 6  examples/html5/WormholeDemo/LocalFiles/index.html
  5. 31  examples/html5/WormholeDemo/LocalFiles/phonegapSensors.js
  6. 57  examples/html5/WormholeDemo/LocalFiles/w3csensors.js
  7. 11  libs/MAStd/api_areas.h
  8. 4  libs/NativeUI/Widget.cpp
  9. 5  libs/Wormhole/WebAppMoblet.h
  10. 2  libs/Wormhole/jslib/mosync-nativeui.js
  11. 1  platforms/iOS/profile.xml
  12. 34  runtimes/cpp/platforms/android/IOCtl.cpp
  13. 11  runtimes/cpp/platforms/android/IOCtl.h
  14. 19  runtimes/cpp/platforms/android/SyscallImpl.cpp
  15. 6  runtimes/cpp/platforms/iphone/Classes/UI/Widgets/IWidget.mm
  16. 11  runtimes/cpp/platforms/iphone/Classes/impl/SyscallImpl.mm
  17. 2  runtimes/cpp/platforms/symbian/src/SyscallImpl.cpp
  18. 14  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/MoSyncCameraModule.cs
  19. 7  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/MoSyncNativeUIModule.cs
  20. 4  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/NativeUI/MoSyncCameraPreview.cs
  21. 11  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/NativeUI/MoSyncHorizontalLayout.cs
  22. 8  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/NativeUI/MoSyncPanoramaView.cs
  23. 11  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/NativeUI/MoSyncVerticalLayout.cs
  24. 3  runtimes/java/platforms/androidJNI/AndroidProject/src/com/mosync/internal/android/MoSyncAudio.java
  25. 311  runtimes/java/platforms/androidJNI/AndroidProject/src/com/mosync/internal/android/MoSyncDB.java
  26. 366  runtimes/java/platforms/androidJNI/AndroidProject/src/com/mosync/internal/android/MoSyncSound.java
  27. 16  runtimes/java/platforms/androidJNI/AndroidProject/src/com/mosync/internal/android/MoSyncThread.java
  28. 24  templates/C NativeUI Project/main.c
  29. 2  testPrograms/DBTest/main.cpp
  30. 17  testPrograms/SoundPlay/.cproject
  31. 16  testPrograms/SoundPlay/.mosyncproject
  32. 30  testPrograms/SoundPlay/.project
  33. 3  testPrograms/SoundPlay/.settings/org.eclipse.core.resources.prefs
  34. BIN  testPrograms/SoundPlay/ColorWhite.wav
  35. BIN  testPrograms/SoundPlay/SoundMystic.mp3
  36. BIN  testPrograms/SoundPlay/SoundMystic.wav
  37. 180  testPrograms/SoundPlay/main.cpp
  38. 8  testPrograms/SoundPlay/resources.lst
  39. 10  testPrograms/native_ui_lib/WidgetTest/.mosyncproject
  40. 14  tools/ReleasePackageBuild/build_package_tools/osx_bin/ImageMagick/convert
  41. 7  tools/ReleasePackageBuild/mac_package_resources/MoSync-Installer/postflight.sh
  42. 17  tools/idl2/maapi.idl
  43. 1  tools/package/android.cpp
  44. 15  tools/winphone-builder/main.cpp
2  examples/cpp/DatabaseTest/.mosyncproject
... ...
@@ -1,5 +1,5 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2  
-<project supports-build-configs="true" version="1.2">
  2
+<project supports-build-configs="true" version="1.4">
3 3
 <build.cfg id="Debug" types="Debug"/>
4 4
 <build.cfg id="Release" types="Release"/>
5 5
 <properties>
202  examples/cpp/DatabaseTest/main.cpp
@@ -172,6 +172,8 @@ class DBTest
172 172
 
173 173
 		MAHandle db = openDatabase();
174 174
 		createTable(db);
  175
+		deleteRow(db);
  176
+		updateRow(db);
175 177
 		countRows(db);
176 178
 		queryRows(db);
177 179
 
@@ -216,12 +218,40 @@ class DBTest
216 218
 		SHOULD_HOLD(MA_DB_OK == result, "INSERT failed 1");
217 219
 		result = maDBExecSQL(db, "INSERT INTO pet VALUES ('Sporty', 4, 0.99)");
218 220
 		SHOULD_HOLD(MA_DB_OK == result, "INSERT failed 2");
219  
-		result = maDBExecSQL(db, "INSERT INTO pet VALUES (NULL, NULL, NULL)");
  221
+		result = maDBExecSQL(db, "INSERT INTO pet VALUES ('Rookie', 0, 0.0)");
220 222
 		SHOULD_HOLD(MA_DB_OK == result, "INSERT failed 3");
  223
+		result = maDBExecSQL(db, "INSERT INTO pet VALUES (NULL, NULL, NULL)");
  224
+		SHOULD_HOLD(MA_DB_OK == result, "INSERT failed 4");
221 225
 
222 226
 		printf("Create table success\n");
223 227
 	}
224 228
 
  229
+	void updateRow(MAHandle db)
  230
+	{
  231
+		int result;
  232
+
  233
+		printf("Update row\n");
  234
+
  235
+		// Update a row in the table.
  236
+		result = maDBExecSQL(db, "UPDATE pet SET name='Snoopy' WHERE name='Sporty'");
  237
+		SHOULD_HOLD(MA_DB_OK == result, "UPDATE failed");
  238
+
  239
+		printf("Update row success\n");
  240
+	}
  241
+
  242
+	void deleteRow(MAHandle db)
  243
+	{
  244
+		int result;
  245
+
  246
+		printf("Delete row\n");
  247
+
  248
+		// Delete a row in the table.
  249
+		result = maDBExecSQL(db, "DELETE FROM pet WHERE name='Rookie'");
  250
+		SHOULD_HOLD(MA_DB_OK == result, "DELETE failed");
  251
+
  252
+		printf("Delete row success\n");
  253
+	}
  254
+
225 255
 	void countRows(MAHandle db)
226 256
 	{
227 257
 		int result;
@@ -256,8 +286,17 @@ class DBTest
256 286
 	{
257 287
 		printf("Query rows\n");
258 288
 
  289
+		// Check that query that returns no rows works.
  290
+		MAHandle cursor = maDBExecSQL(
  291
+			db,
  292
+			"SELECT * FROM pet WHERE name='NameThatDoesNotExist'");
  293
+		SHOULD_HOLD(0 < cursor, "SELECT did not return cursor");
  294
+		int result = maDBCursorNext(cursor);
  295
+		SHOULD_HOLD(MA_DB_NO_ROW == result, "MA_DB_NO_ROW failed");
  296
+		maDBCursorDestroy(cursor);
  297
+
259 298
 		// Query all rows.
260  
-		MAHandle cursor = maDBExecSQL(db, "SELECT * FROM pet");
  299
+		cursor = maDBExecSQL(db, "SELECT * FROM pet");
261 300
 		SHOULD_HOLD(cursor > 0, "SELECT * failed");
262 301
 
263 302
 		// Here follows variables that hold field values,
@@ -309,9 +348,9 @@ class DBTest
309 348
 			}
310 349
 			else if (2 == row)
311 350
 			{
312  
-				SHOULD_HOLD(name == "Sporty", "Sporty not equal to name");
313  
-				SHOULD_HOLD(name == name2, "Sporty not equal to name2");
314  
-				SHOULD_HOLD(4 == age, "Sporty age failed");
  351
+				SHOULD_HOLD(name == "Snoopy", "Snoopy not equal to name");
  352
+				SHOULD_HOLD(name == name2, "Snoopy not equal to name2");
  353
+				SHOULD_HOLD(4 == age, "Snoopy age failed");
315 354
 				// Double comparisons are tricky...
316 355
 				SHOULD_HOLD(0.989 < curiosity && 0.991 > curiosity,
317 356
 					"curiosity failed");
@@ -325,7 +364,7 @@ class DBTest
325 364
 			}
326 365
 		}
327 366
 
328  
-		int result = maDBCursorDestroy(cursor);
  367
+		result = maDBCursorDestroy(cursor);
329 368
 		SHOULD_HOLD(MA_DB_OK == result, "maDBCursorDestroy failed");
330 369
 
331 370
 		result = maDBClose(db);
@@ -333,8 +372,145 @@ class DBTest
333 372
 
334 373
 		printf("Query rows success\n");
335 374
 	}
  375
+
  376
+	void testParameters()
  377
+	{
  378
+		// Used for the result from maDB* function calls.
  379
+		int result;
  380
+
  381
+		printf("Param test started\n");
  382
+
  383
+		// Open the database (will create it if it does not exist).
  384
+		MAUtil::String path = DBUtil::getLocalPath();
  385
+		path += "MikiDB";
  386
+		printf("Database path: %s\n", path.c_str());
  387
+		MAHandle db = maDBOpen(path.c_str());
  388
+		SHOULD_HOLD(db > 0, "maDBOpen failed");
  389
+
  390
+		// Create a new table, first drop the table if it exists.
  391
+		result = maDBExecSQL(db, "DROP TABLE IF EXISTS paramtest");
  392
+		SHOULD_HOLD(MA_DB_OK == result, "DROP TABLE IF EXISTS failed");
  393
+
  394
+		// Create table.
  395
+		result = maDBExecSQL(db,
  396
+			"CREATE TABLE paramtest (textValue TEXT(50), "
  397
+			"intValue INTEGER, doubleValue DOUBLE, "
  398
+			"blobValue BLOB, dataValue BLOB, nullValue BLOB)");
  399
+		SHOULD_HOLD(MA_DB_OK == result, "CREATE TABLE failed");
  400
+
  401
+		// Insert values into the table using a parameter array
  402
+		// of type MADBValue.
  403
+		MADBValue params[6];
  404
+
  405
+		params[0].type = MA_DB_TYPE_TEXT;
  406
+		params[0].text.addr = (char*)"some text";
  407
+		params[0].text.length = 9;
  408
+
  409
+		params[1].type = MA_DB_TYPE_INT;
  410
+		params[1].i = 42;
  411
+
  412
+		params[2].type = MA_DB_TYPE_DOUBLE;
  413
+		params[2].d = 3.14;
  414
+
  415
+		params[3].type = MA_DB_TYPE_BLOB;
  416
+		params[3].blob.data = (void*)"blob data";
  417
+		params[3].blob.size = 9;
  418
+
  419
+		params[4].type = MA_DB_TYPE_DATA;
  420
+		params[4].dataHandle = maCreatePlaceholder();
  421
+		maCreateData(params[4].dataHandle, 14);
  422
+		maWriteData(params[4].dataHandle, "more blob data", 0, 14);
  423
+
  424
+		params[5].type = MA_DB_TYPE_NULL;
  425
+
  426
+		result = maDBExecSQLParams(
  427
+			db,
  428
+			"INSERT INTO paramtest VALUES (?, ?, ?, ?, ?, ?)",
  429
+			params,
  430
+			6);
  431
+		SHOULD_HOLD(MA_DB_OK == result, "INSERT failed");
  432
+
  433
+		// Count rows, there should be one row.
  434
+		MAHandle cursor = maDBExecSQL(
  435
+			db,
  436
+			"SELECT COUNT(*) FROM (SELECT * FROM paramtest)");
  437
+		SHOULD_HOLD(0 < cursor, "SELECT 1 did not return cursor");
  438
+		maDBCursorNext(cursor);
  439
+		int numberOfRows;
  440
+		maDBCursorGetColumnInt(cursor, 0, &numberOfRows);
  441
+	    maDBCursorDestroy(cursor);
  442
+		SHOULD_HOLD(1 == numberOfRows, "Wrong number of rows");
  443
+
  444
+		// Check that query that returns no rows works.
  445
+		cursor = maDBExecSQLParams(
  446
+			db,
  447
+			"SELECT * FROM paramtest WHERE "
  448
+			"nullValue IS NOT NULL",
  449
+			params,
  450
+			0
  451
+			);
  452
+		SHOULD_HOLD(0 < cursor, "SELECT 2 did not return cursor");
  453
+		result = maDBCursorNext(cursor);
  454
+		SHOULD_HOLD(MA_DB_NO_ROW == result, "MA_DB_NO_ROW failed");
  455
+		maDBCursorDestroy(cursor);
  456
+
  457
+		// Query all rows and check that column data is correct.
  458
+		// Note: To use blob fields in a WHERE clause is not supported.
  459
+		cursor = maDBExecSQLParams(
  460
+			db,
  461
+			"SELECT * FROM paramtest WHERE "
  462
+			"textValue=? AND "
  463
+			"intValue=? AND "
  464
+			"doubleValue=? AND "
  465
+			"nullValue IS NULL",
  466
+			params,
  467
+			3
  468
+			);
  469
+		SHOULD_HOLD(0 < cursor, "SELECT 3 did not return cursor");
  470
+		result = maDBCursorNext(cursor);
  471
+		SHOULD_HOLD(MA_DB_OK == result, "maDBCursorNext failed");
  472
+
  473
+		String text;
  474
+		result = DBUtil::getColumnString(cursor, 0, text);
  475
+		SHOULD_HOLD(result >= 0, "Could not get value of column 1");
  476
+		SHOULD_HOLD(strcmp(text.c_str(), "some text") == 0, "text");
  477
+
  478
+		int i;
  479
+		result = maDBCursorGetColumnInt(cursor, 1, &i);
  480
+		SHOULD_HOLD(MA_DB_OK == result, "Could not get value of column 2");
  481
+		SHOULD_HOLD(i == 42, "int");
  482
+
  483
+		double d;
  484
+		result = maDBCursorGetColumnDouble(cursor, 2, &d);
  485
+		SHOULD_HOLD(MA_DB_OK == result, "Could not get value of column 3");
  486
+		SHOULD_HOLD(d > 3.13999 && d < 3.14001, "double");
  487
+
  488
+		result = DBUtil::getColumnDataAsString(cursor, 3, text);
  489
+		SHOULD_HOLD(MA_DB_OK == result, "Could not get value of column 4");
  490
+		SHOULD_HOLD(memcmp(text.c_str(), "blob data", 9) == 0, "blob");
  491
+
  492
+		result = DBUtil::getColumnDataAsString(cursor, 4, text);
  493
+		SHOULD_HOLD(MA_DB_OK == result, "Could not get value of column 5");
  494
+		SHOULD_HOLD(memcmp(text.c_str(), "more blob data", 14) == 0, "data");
  495
+
  496
+		result = DBUtil::getColumnDataAsString(cursor, 5, text);
  497
+		SHOULD_HOLD(MA_DB_NULL == result, "Column 6 is not NULL");
  498
+
  499
+		// There should be no more rows.
  500
+		result = maDBCursorNext(cursor);
  501
+		SHOULD_HOLD(MA_DB_NO_ROW == result, "MA_DB_NO_ROW failed");
  502
+
  503
+		result = maDBCursorDestroy(cursor);
  504
+		SHOULD_HOLD(MA_DB_OK == result, "maDBCursorDestroy failed");
  505
+
  506
+		result = maDBClose(db);
  507
+		SHOULD_HOLD(MA_DB_OK == result, "maDBClose failed");
  508
+
  509
+		printf("Param test passed successfully\n");
  510
+	}
336 511
 };
337 512
 
  513
+
338 514
 /**
339 515
  * Moblet that runs the database tests.
340 516
  */
@@ -346,7 +522,13 @@ class DBTestMoblet : public Moblet
346 522
 	 */
347 523
 	DBTestMoblet()
348 524
 	{
349  
-		printf("Touch screen to run database test\n");
  525
+		printf("Database test\n");
  526
+
  527
+		DBTest test;
  528
+		test.runTest();
  529
+		test.testParameters();
  530
+
  531
+		printf("Touch screen to run test 1000 times\n");
350 532
 		printf("Press zero or back (on Android) to exit\n");
351 533
 	}
352 534
 
@@ -368,7 +550,11 @@ class DBTestMoblet : public Moblet
368 550
 	void pointerPressEvent(MAPoint2d point)
369 551
 	{
370 552
 		DBTest test;
371  
-		test.runTest();
  553
+		for (int i = 0; i < 1000; ++i)
  554
+		{
  555
+			test.runTest();
  556
+			test.testParameters();
  557
+		}
372 558
 	}
373 559
 };
374 560
 
4  examples/cpp/PurchaseExample/.mosyncproject
@@ -4,7 +4,7 @@
4 4
 <build.cfg id="Release" types="Release"/>
5 5
 <criteria>
6 6
 <filter type="com.mobilesorcery.sdk.capabilities.devices.elementfactory">
7  
-<capabilities optional="" required="NativeUI"/>
  7
+<capabilities optional="" required="In-App\ Purchase NativeUI"/>
8 8
 </filter>
9 9
 </criteria>
10 10
 <properties>
@@ -35,4 +35,4 @@
35 35
 <property key="profile.mgr.type" value="0"/>
36 36
 <property key="template.id" value="project.nativeui"/>
37 37
 </properties>
38  
-</project>
  38
+</project>
6  examples/html5/WormholeDemo/LocalFiles/index.html
@@ -131,6 +131,8 @@
131 131
 					}
132 132
 					else
133 133
 					{
  134
+						stopAllW3CSensors();
  135
+						stopAllPhonegapSensors();
134 136
 						// Same action as software back button.
135 137
 						jQT.goBack();
136 138
 					}
@@ -193,7 +195,7 @@ <h1 id="InfoTitle">Device Information</h1>
193 195
 		<div id="PhoneGapSensors">
194 196
 			<div class="toolbar">
195 197
 				<h1 id="InfoTitle">Phonegap Sensors</h1>
196  
-				<a class="button back" onclick="jQT.goBack()" id="backButton">Back</a>
  198
+				<a class="button back" onclick="stopAllPhonegapSensors();jQT.goBack()" id="backButton">Back</a>
197 199
 			</div>
198 200
 
199 201
 			<ul id="Accelerometer" class="rounded">
@@ -228,7 +230,7 @@ <h1 id="InfoTitle">Phonegap Sensors</h1>
228 230
 		<div id="W3cSensors">
229 231
 			<div class="toolbar">
230 232
 				<h1 id="InfoTitle">Sensors 2</h1>
231  
-				<a class="button back" onclick="jQT.goBack()" id="backButton">Back</a>
  233
+				<a class="button back" onclick="stopAllW3CSensors();jQT.goBack()" id="backButton">Back</a>
232 234
 			</div>
233 235
 
234 236
 			<ul id="Accelerometer" class="rounded">
31  examples/html5/WormholeDemo/LocalFiles/phonegapSensors.js
@@ -138,3 +138,34 @@ function updateCompass(result) {
138 138
 function errorCompass(error) {
139 139
 	document.getElementById('CompassHeading').innerHTML = "n/a";
140 140
 }
  141
+
  142
+function stopAllPhonegapSensors()
  143
+{
  144
+	if (accelPhonegapWatch !== null) {
  145
+		navigator.accelerometer.clearWatch(accelPhonegapWatch);
  146
+		updateAccelPhonegap({
  147
+			x : "&nbsp;",
  148
+			y : "&nbsp;",
  149
+			z : "&nbsp;"
  150
+		});
  151
+		accelPhonegapWatch = null;
  152
+	}
  153
+
  154
+	if (geolocationWatch !== null) {
  155
+		navigator.geolocation.clearWatch(geolocationWatch);
  156
+		updateGeolocation({ coords: {
  157
+			latitude : "&nbsp;",
  158
+			longitude : "&nbsp;",
  159
+			altitude : "&nbsp;"
  160
+		}});
  161
+		geolocationWatch = null;
  162
+	}
  163
+
  164
+	if (compassWatch !== null) {
  165
+		navigator.compass.clearWatch(compassWatch);
  166
+		updateCompass({
  167
+			magneticHeading : "&nbsp;"
  168
+		});
  169
+		compassWatch = null;
  170
+	}
  171
+}
57  examples/html5/WormholeDemo/LocalFiles/w3csensors.js
@@ -204,3 +204,60 @@ function toggleProximityW3C()
204 204
 		}});
205 205
 	}
206 206
 }
  207
+
  208
+/**
  209
+ * This function stops all the sensors. It's called when the
  210
+ * user leaves the page.
  211
+ */
  212
+function stopAllW3CSensors()
  213
+{
  214
+	if (accelerometer.status == "watching")
  215
+	{
  216
+		accelerometer.endWatch();
  217
+		updateAccelW3C({data:{
  218
+			x: "&nbsp;",
  219
+			y: "&nbsp;",
  220
+			z: "&nbsp;"
  221
+		}});
  222
+	}
  223
+
  224
+	if (magneticField.status == "watching")
  225
+	{
  226
+		magneticField.endWatch();
  227
+		updateMagDataW3C({data:{
  228
+			x: "&nbsp;",
  229
+			y: "&nbsp;",
  230
+			z: "&nbsp;"
  231
+		}});
  232
+	}
  233
+
  234
+	if (orientationSensor.status == "watching")
  235
+	{
  236
+		orientationSensor.endWatch();
  237
+		updateOrientDataW3C({data:{
  238
+			x: "&nbsp;",
  239
+			y: "&nbsp;",
  240
+			z: "&nbsp;"
  241
+		}});
  242
+	}
  243
+
  244
+	if (gyroscope.status == "watching")
  245
+	{
  246
+		gyroscope.endWatch();
  247
+		updateGyroDataW3C({data:{
  248
+			x: "&nbsp;",
  249
+			y: "&nbsp;",
  250
+			z: "&nbsp;"
  251
+		}});
  252
+	}
  253
+
  254
+	if (proximity.status == "watching")
  255
+	{
  256
+		proximity.endWatch();
  257
+		updateProxDataW3C({data:{
  258
+			x: "&nbsp;",
  259
+			y: "&nbsp;",
  260
+			z: "&nbsp;"
  261
+		}});
  262
+	}
  263
+}
11  libs/MAStd/api_areas.h
@@ -36,7 +36,16 @@
36 36
 </td>
37 37
 <td><a href="http://www.mosync.com/documentation/manualpages/how-communicate-between-javascript-and-c-mosync"  target="_blank"> Communication between JavaScript and C++</a></td>
38 38
 <td>
39  
-Wormhole::WebAppMoblet, Wormhole::WebViewMessage, Wormhole::FileUtil
  39
+Wormhole::Encoder,
  40
+Wormhole::FileUtil,
  41
+Wormhole::HighLevelBinaryDownloader,
  42
+Wormhole::HighLevelHttpConnection,
  43
+Wormhole::HighLevelImageDownloader,
  44
+Wormhole::HighLevelTextDownloader,
  45
+Wormhole::MessageProtocol,
  46
+Wormhole::MessageStream,
  47
+Wormhole::MessageStreamJSON,
  48
+Wormhole::WebAppMoblet
40 49
 </td>
41 50
 <td>
42 51
 \ref 	WormHoleGroup
4  libs/NativeUI/Widget.cpp
@@ -409,8 +409,8 @@ namespace NativeUI
409 409
      * Remove a child widget from its parent (but does not destroy it).
410 410
      * Removing a currently visible top-level widget causes the MoSync view
411 411
      * to become visible.
412  
-     * When the parent widget will be destroyed, the child widget will not
413  
-     * be deleted.
  412
+     * When the parent widget will be destroyed, the removed child widget will not
  413
+     * be deleted (this responsibility is left to the developer).
414 414
      * @param widget The widget to be removed.
415 415
      * @return Any of the following result codes:
416 416
      * - #MAW_RES_OK if the child could be removed from the parent.
5  libs/Wormhole/WebAppMoblet.h
@@ -51,7 +51,10 @@ namespace Wormhole
51 51
 	class WebAppMoblet_WebViewListener;
52 52
 
53 53
 	/**
54  
-	 * \brief A web view is a widget used to render web pages.
  54
+	 * \brief A Moblet with additional functionality that allows easier interaction with
  55
+	 * JavaScript code. It provides a wormhole-enabled WebView, methods to extract and load
  56
+	 * your HTML files and JavaScript code, and a structure for communicating with your JS
  57
+	 * code.
55 58
 	 */
56 59
 	class WebAppMoblet : public MAUtil::Moblet
57 60
 	{
2  libs/Wormhole/jslib/mosync-nativeui.js
@@ -867,7 +867,7 @@ mosync.nativeui.NativeWidgetElement = function(widgetType, widgetID, params,
867 867
 				{
868 868
 					if(self.childList[index] ==  childID)
869 869
 					{
870  
-						self.childList.splic(index,1);
  870
+						self.childList.splice(index,1);
871 871
 					}
872 872
 				}
873 873
 				mosync.nativeui.maWidgetRemoveChild(childID, successCallback,
1  platforms/iOS/profile.xml
@@ -2,4 +2,5 @@
2 2
   <capability name="OpenGL ES 1.0" state="SUPPORTED"/>
3 3
   <capability name="OpenGL ES 2.0" state="SUPPORTED"/>
4 4
   <capability name="Bluetooth" state="UNSUPPORTED"/>
  5
+  <capability name="In-App Purchase" state="SUPPORTED"/>
5 6
 </platform>
34  runtimes/cpp/platforms/android/IOCtl.cpp
@@ -3650,6 +3650,40 @@ namespace Base
3650 3650
 	}
3651 3651
 
3652 3652
 	/**
  3653
+	 * Invoke maDBExecSQLParams.
  3654
+	 */
  3655
+	int _maDBExecSQLParams(
  3656
+		MAHandle databaseHandle,
  3657
+		const char* sql,
  3658
+		int paramsAddress,
  3659
+		int paramCount,
  3660
+		JNIEnv* jNIEnv,
  3661
+		jobject jThis)
  3662
+	{
  3663
+		jstring jstrSql = jNIEnv->NewStringUTF(sql);
  3664
+		jclass cls = jNIEnv->GetObjectClass(jThis);
  3665
+		jmethodID methodID = jNIEnv->GetMethodID(
  3666
+			cls,
  3667
+			"maDBExecSQLParams",
  3668
+			"(ILjava/lang/String;II)I");
  3669
+		if (methodID == 0)
  3670
+		{
  3671
+			// Method not found.
  3672
+			return -1;
  3673
+		}
  3674
+		jint result = jNIEnv->CallIntMethod(
  3675
+			jThis,
  3676
+			methodID,
  3677
+			databaseHandle,
  3678
+			jstrSql,
  3679
+			paramsAddress,
  3680
+			paramCount);
  3681
+		jNIEnv->DeleteLocalRef(cls);
  3682
+		jNIEnv->DeleteLocalRef(jstrSql);
  3683
+		return (int)result;
  3684
+	}
  3685
+
  3686
+	/**
3653 3687
 	 * Destroys a cursor. You must call this function
3654 3688
 	 * when you are done with the cursor to release
3655 3689
 	 * its resources.
11  runtimes/cpp/platforms/android/IOCtl.h
@@ -970,6 +970,17 @@ namespace Base
970 970
 		jobject jThis);
971 971
 
972 972
 	/**
  973
+	 * Invoke maDBExecSQLParams.
  974
+	 */
  975
+	int _maDBExecSQLParams(
  976
+		MAHandle databaseHandle,
  977
+		const char* sql,
  978
+		int paramsAddress,
  979
+		int paramCount,
  980
+		JNIEnv* jNIEnv,
  981
+		jobject jThis);
  982
+
  983
+	/**
973 984
 	 * Destroys a cursor. You must call this function
974 985
 	 * when you are done with the cursor to release
975 986
 	 * its resources.
19  runtimes/cpp/platforms/android/SyscallImpl.cpp
@@ -3021,6 +3021,25 @@ namespace Base
3021 3021
 				mJNIEnv,
3022 3022
 				mJThis);
3023 3023
 
  3024
+		case maIOCtl_maDBExecSQLParams:
  3025
+		{
  3026
+			// Get fourth parameter.
  3027
+			int d = SYSCALL_THIS->GetValidatedStackValue(0);
  3028
+			return _maDBExecSQLParams(
  3029
+				// Database handle
  3030
+				a,
  3031
+				// SQL string
  3032
+				SYSCALL_THIS->GetValidatedStr(b),
  3033
+				// Params address
  3034
+				//(int)SYSCALL_THIS->GetValidatedMemRange(c, sizeof(MADBValue) * d)
  3035
+				//	- (int)gCore->mem_ds,
  3036
+				c,
  3037
+				// Param count.
  3038
+				d,
  3039
+				mJNIEnv,
  3040
+				mJThis);
  3041
+		}
  3042
+
3024 3043
 		case maIOCtl_maDBCursorDestroy:
3025 3044
 			return _maDBCursorDestroy(
3026 3045
 				a,
6  runtimes/cpp/platforms/iphone/Classes/UI/Widgets/IWidget.mm
@@ -187,7 +187,11 @@ - (void)removeChild: (IWidget*)child fromSuperview:(bool)removeFromSuperview {
187 187
 }
188 188
 
189 189
 - (int)remove {
190  
-	//if(!parent) return MAW_RES_REMOVED_ROOT;
  190
+	if(parent == nil) return MAW_RES_REMOVED_ROOT;
  191
+    for (IWidget *child in children)
  192
+	{
  193
+        [child removeChild:self];//remove all children
  194
+    }
191 195
 	[parent removeChild: self];
192 196
 	return MAW_RES_OK;
193 197
 }
11  runtimes/cpp/platforms/iphone/Classes/impl/SyscallImpl.mm
@@ -36,6 +36,8 @@
36 36
 #include "PimSyscall.h"
37 37
 #include "OptionsDialogView.h"
38 38
 #include <CoreMedia/CoreMedia.h>
  39
+#include <sys/types.h> //
  40
+#include <sys/sysctl.h>//to retrieve device model
39 41
 
40 42
 #include <helpers/CPP_IX_GUIDO.h>
41 43
 //#include <helpers/CPP_IX_ACCELEROMETER.h>
@@ -1282,6 +1284,15 @@ int maGetSystemProperty(const char *key, char *buf, int size) {
1282 1284
 		} else if (strcmp(key, "mosync.device.OS.version") == 0) {
1283 1285
 			[[[UIDevice currentDevice] systemVersion] getCString:buf maxLength:size encoding:NSASCIIStringEncoding];
1284 1286
 			res = size;
  1287
+		} else if (strcmp(key, "mosync.device") == 0) {
  1288
+			size_t responseSz;
  1289
+			sysctlbyname("hw.machine", NULL, &responseSz, NULL, 0);
  1290
+			char *machine = (char*)malloc(responseSz);
  1291
+			sysctlbyname("hw.machine", machine, &responseSz, NULL, 0);
  1292
+			NSString *platform = [NSString stringWithCString:machine encoding:NSASCIIStringEncoding];
  1293
+			[platform getCString:buf maxLength:size encoding:NSASCIIStringEncoding];
  1294
+			free(machine);
  1295
+			res = size;
1285 1296
 		} else if (strcmp(key, "mosync.network.type") == 0) {
1286 1297
 			NSString* networkType;
1287 1298
 			//Use Apples Reachability sample class for detecting the network type
2  runtimes/cpp/platforms/symbian/src/SyscallImpl.cpp
@@ -302,7 +302,7 @@ void Syscall::ConstructL(VMCore* aCore) {
302 302
 	LHEL(gKeyLock.Connect());
303 303
 	//gKeyLock.EnableSoftNotifications(EFalse);
304 304
 
305  
-	LHEL(gSocketServ.Connect());
  305
+	LHEL(gSocketServ.Connect(CONN_MAX));
306 306
 	ConstructNetworkingL();
307 307
 	ConstructBluetoothL();
308 308
 
14  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/MoSyncCameraModule.cs
@@ -219,6 +219,7 @@ public void Init(Ioctls ioctls, Core core, Runtime runtime)
219 219
                             if (currentPage.Orientation == PageOrientation.PortraitUp)
220 220
                             {
221 221
                                 rotateAngle = 90;
  222
+
222 223
                             }
223 224
                             else if (currentPage.Orientation == PageOrientation.LandscapeRight)
224 225
                             {
@@ -428,11 +429,18 @@ private void SetInitialCameraOrientation(PhoneApplicationPage page)
428 429
             if (page.Orientation == PageOrientation.LandscapeLeft)
429 430
             {
430 431
                 rotation -= 90;
  432
+                mVideoBrush.Stretch = Stretch.Uniform;
431 433
             }
432 434
             else if (page.Orientation == PageOrientation.LandscapeRight)
433 435
             {
434 436
                 rotation += 90;
  437
+                mVideoBrush.Stretch = Stretch.Uniform;
  438
+            }
  439
+            else
  440
+            {
  441
+                mVideoBrush.Stretch = Stretch.Fill;
435 442
             }
  443
+
436 444
             mVideoBrush.RelativeTransform = new CompositeTransform()
437 445
             {
438 446
                 CenterX = 0.5,
@@ -455,10 +463,16 @@ private void HandleDeviceOrientation(PhoneApplicationPage page)
455 463
                     if (args.Orientation == PageOrientation.LandscapeLeft)
456 464
                     {
457 465
                         rotation -= 90;
  466
+                        mVideoBrush.Stretch = Stretch.Uniform;
458 467
                     }
459 468
                     else if (args.Orientation == PageOrientation.LandscapeRight)
460 469
                     {
461 470
                         rotation += 90;
  471
+                        mVideoBrush.Stretch = Stretch.Uniform;
  472
+                    }
  473
+                    else
  474
+                    {
  475
+                        mVideoBrush.Stretch = Stretch.Fill;
462 476
                     }
463 477
 
464 478
                     mVideoBrush.RelativeTransform = new CompositeTransform()
7  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/MoSyncNativeUIModule.cs
@@ -61,8 +61,11 @@ public void Init(Ioctls ioctls, Core core, Runtime runtime)
61 61
 				if (_widget < 0 || _widget >= mWidgets.Count)
62 62
 					return MoSync.Constants.MAW_RES_INVALID_HANDLE;
63 63
                 IWidget widget = mWidgets[_widget];
64  
-                widget.RemoveFromParent();
65  
-                mWidgets[_widget] = null;
  64
+                if (widget != null)
  65
+                {
  66
+                    widget.RemoveFromParent();
  67
+                    mWidgets[_widget] = null;
  68
+                }
66 69
                 return MoSync.Constants.MAW_RES_OK;
67 70
             };
68 71
 
4  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/NativeUI/MoSyncCameraPreview.cs
@@ -55,10 +55,10 @@ public CameraPreview()
55 55
                 mViewFinder = new System.Windows.Controls.Canvas();
56 56
                 mViewFinder.Opacity = 0.0;
57 57
 
58  
-                Grid.SetRow(mViewFinder, 0);
59  
-
60 58
                 mLayout.Children.Add(mViewFinder);
61 59
 
  60
+                Grid.SetRow(mViewFinder, 0);
  61
+
62 62
                 View = mLayout;
63 63
             }
64 64
 
11  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/NativeUI/MoSyncHorizontalLayout.cs
@@ -204,10 +204,13 @@ public override void RemoveChild(IWidget child)
204 204
                 {
205 205
                     WidgetBaseWindowsPhone widget = (child as WidgetBaseWindowsPhone);
206 206
                     int x = Grid.GetColumn((widget.View) as System.Windows.FrameworkElement);
207  
-                    mGrid.ColumnDefinitions.RemoveAt(x + 1);
208  
-                    mGrid.ColumnDefinitions.RemoveAt(x);
209  
-                    mGrid.ColumnDefinitions.RemoveAt(x - 1);
210  
-                    mGrid.Children.Remove((child as WidgetBaseWindowsPhone).View);
  207
+                    if ((x + 1) < mGrid.ColumnDefinitions.Count)
  208
+                    {
  209
+                        mGrid.ColumnDefinitions.RemoveAt(x + 1);
  210
+                        mGrid.ColumnDefinitions.RemoveAt(x);
  211
+                        mGrid.ColumnDefinitions.RemoveAt(x - 1);
  212
+                        mGrid.Children.Remove((child as WidgetBaseWindowsPhone).View);
  213
+                    }
211 214
                 });
212 215
                 base.RemoveChild(child);
213 216
             }
8  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/NativeUI/MoSyncPanoramaView.cs
@@ -41,6 +41,8 @@ namespace NativeUI
41 41
         public class PanoramaView : Screen
42 42
         {
43 43
             protected Microsoft.Phone.Controls.Panorama mPanorama;
  44
+            private int mCurrentScreenIndex = 0;
  45
+
44 46
             /**
45 47
              * The constructor
46 48
              */
@@ -55,7 +57,7 @@ public PanoramaView()
55 57
                 mPanorama.Loaded += new RoutedEventHandler(
56 58
                     delegate(object from, RoutedEventArgs args)
57 59
                     {
58  
-                        SetApplicationBarVisibility(0);
  60
+                        SetApplicationBarVisibility(mCurrentScreenIndex);
59 61
                     });
60 62
 
61 63
                 //The application bar is chanded at the SelectionChanged event occurence.
@@ -63,6 +65,7 @@ public PanoramaView()
63 65
                 mPanorama.SelectionChanged += new EventHandler<SelectionChangedEventArgs>(
64 66
                     delegate(object from, SelectionChangedEventArgs target)
65 67
                     {
  68
+                        mCurrentScreenIndex = (from as Microsoft.Phone.Controls.Panorama).SelectedIndex;
66 69
                         SetApplicationBarVisibility((from as Microsoft.Phone.Controls.Panorama).SelectedIndex);
67 70
                     });
68 71
             }
@@ -189,7 +192,10 @@ public int CurrentScreen
189 192
                 set
190 193
                 {
191 194
                     if (-1 < value && mPanorama.Items.Count > value)
  195
+                    {
192 196
                         mPanorama.DefaultItem = mPanorama.Items[value];
  197
+                        mCurrentScreenIndex = value;
  198
+                    }
193 199
                     else throw new InvalidPropertyValueException();
194 200
                 }
195 201
                 get
11  runtimes/csharp/windowsphone/mosync/mosyncRuntime/Source/Modules/NativeUI/MoSyncVerticalLayout.cs
@@ -208,10 +208,13 @@ public override void RemoveChild(IWidget child)
208 208
                 {
209 209
                     WidgetBaseWindowsPhone widget = (child as WidgetBaseWindowsPhone);
210 210
                     int x = Grid.GetRow((widget.View) as System.Windows.FrameworkElement);
211  
-                    mGrid.RowDefinitions.RemoveAt(x + 1);
212  
-                    mGrid.RowDefinitions.RemoveAt(x);
213  
-                    mGrid.RowDefinitions.RemoveAt(x - 1);
214  
-                    mGrid.Children.Remove((child as WidgetBaseWindowsPhone).View);
  211
+                    if ((x + 1) < mGrid.RowDefinitions.Count)
  212
+                    {
  213
+                        mGrid.RowDefinitions.RemoveAt(x + 1);
  214
+                        mGrid.RowDefinitions.RemoveAt(x);
  215
+                        mGrid.RowDefinitions.RemoveAt(x - 1);
  216
+                        mGrid.Children.Remove((child as WidgetBaseWindowsPhone).View);
  217
+                    }
215 218
                 });
216 219
                 base.RemoveChild(child);
217 220
             }
3  runtimes/java/platforms/androidJNI/AndroidProject/src/com/mosync/internal/android/MoSyncAudio.java
@@ -311,7 +311,8 @@ int maAudioDataCreateFromResource(
311 311
 			int flags)
312 312
 	{
313 313
 
314  
-		AudioStore audioStore = mMoSyncThread.mMoSyncSound.obtainAudioStoreObject(data);
  314
+		AudioStore audioStore = mMoSyncThread.mMoSyncSound.
  315
+			obtainAudioStoreObject(data, offset);
315 316
 
316 317
 		if(audioStore != null)
317 318
 			return maAudioDataCreateFromURL(mime,
311  runtimes/java/platforms/androidJNI/AndroidProject/src/com/mosync/internal/android/MoSyncDB.java
... ...
@@ -1,5 +1,6 @@
1 1
 package com.mosync.internal.android;
2 2
 
  3
+import java.io.UnsupportedEncodingException;
3 4
 import java.nio.ByteBuffer;
4 5
 import java.util.HashMap;
5 6
 
@@ -8,6 +9,8 @@
8 9
 import android.database.SQLException;
9 10
 import android.database.sqlite.SQLiteDatabase;
10 11
 import android.database.sqlite.SQLiteException;
  12
+import android.database.sqlite.SQLiteStatement;
  13
+import android.util.Log;
11 14
 import static com.mosync.internal.generated.MAAPI_consts.*;
12 15
 
13 16
 /**
@@ -95,6 +98,151 @@ public int maDBClose(int databaseHandle)
95 98
 	 */
96 99
 	public int maDBExecSQL(int databaseHandle, String sql)
97 100
 	{
  101
+		return execSQLHelper(databaseHandle, sql, null);
  102
+	}
  103
+
  104
+	/**
  105
+	 * Executes an SQL statement with parameters.
  106
+	 * @param databaseHandle Handle to the database.
  107
+	 * @param sql The SQL statement.
  108
+	 * @param paramsAddress Address of first MADBValue struct.
  109
+	 * @param paramCount Number of MADBValue structs passed.
  110
+	 * @return MA_DB_ERROR on error, MA_DB_OK on success,
  111
+	 * > 0 if there is a cursor to a query result, in this
  112
+	 * case the return value is the cursor handle.
  113
+	 */
  114
+	public int maDBExecSQLParams(
  115
+		int databaseHandle,
  116
+		String sql,
  117
+		int paramsAddress,
  118
+		int paramCount,
  119
+		MoSyncThread mosync)
  120
+	{
  121
+
  122
+		// Execute query.
  123
+		Object[] params = extractExecParams(
  124
+			paramsAddress,
  125
+			paramCount,
  126
+			mosync);
  127
+		return execSQLHelper(databaseHandle, sql, params);
  128
+	}
  129
+
  130
+	Object[] extractExecParams(
  131
+		int paramsAddress,
  132
+		int paramCount,
  133
+		MoSyncThread mosync)
  134
+	{
  135
+		Object[] params = new Object[paramCount];
  136
+
  137
+		// sizeof(MADBValue) is 12 bytes, 8 byte data, 4 byte type.
  138
+		int sizeofMADBValue = 8 + 4;
  139
+
  140
+		// Get parameter array.
  141
+		ByteBuffer buffer = mosync.getMemorySlice(
  142
+			paramsAddress,
  143
+			paramCount * sizeofMADBValue
  144
+			);
  145
+
  146
+		// Set parameter values.
  147
+		// http://stackoverflow.com/questions/9558657/binding-ints-longs-and-blobs-byte-to-android-sql
  148
+		for (int i = 0; i < paramCount; ++i)
  149
+		{
  150
+			// Get param type.
  151
+			buffer.position((i * sizeofMADBValue) + 8);
  152
+			int type = buffer.getInt();
  153
+
  154
+			// Move to start of data in current MADBValue struct.
  155
+			buffer.position(i * sizeofMADBValue);
  156
+
  157
+			if (MA_DB_TYPE_INT == type)
  158
+			{
  159
+				int value = buffer.getInt();
  160
+				params[i] = new Integer(value);
  161
+				//Log.i("@@@@@", "MA_DB_TYPE_INT params[i]: " + params[i]);
  162
+			}
  163
+			else
  164
+			if (MA_DB_TYPE_INT64 == type)
  165
+			{
  166
+				long value = buffer.getLong();
  167
+				params[i] = new Long(value);
  168
+				//Log.i("@@@@@", "MA_DB_TYPE_INT64 params[i]: " + params[i]);
  169
+			}
  170
+			else
  171
+			if (MA_DB_TYPE_DOUBLE == type)
  172
+			{
  173
+				double value = buffer.getDouble();
  174
+				params[i] = new Double(value);
  175
+				//Log.i("@@@@@", "MA_DB_TYPE_DOUBLE params[i]: " + params[i]);
  176
+			}
  177
+			else
  178
+			if (MA_DB_TYPE_NULL == type)
  179
+			{
  180
+				params[i] = null;
  181
+			}
  182
+			else
  183
+			if (MA_DB_TYPE_DATA == type)
  184
+			{
  185
+				// Read data from handle.
  186
+				int handle = buffer.getInt();
  187
+				ByteBuffer buf = mosync.getBinaryResource(handle);
  188
+				byte[] bytes = new byte[buf.capacity()];
  189
+				buf.get(bytes, 0, buf.capacity());
  190
+				params[i] = ByteBuffer.wrap(bytes);
  191
+				//Log.i("@@@@@", "MA_DB_TYPE_DATA params[i]: " + new String(bytes));
  192
+			}
  193
+			else
  194
+			if (MA_DB_TYPE_TEXT == type)
  195
+			{
  196
+				// Read data from struct MADBText.
  197
+				int dataAddress = buffer.getInt();
  198
+				int dataSize = buffer.getInt();
  199
+				ByteBuffer dataBuffer = mosync.getMemorySlice(
  200
+					dataAddress,
  201
+					dataSize
  202
+					);
  203
+				byte[] bytes = new byte[dataSize];
  204
+				dataBuffer.get(bytes, 0, dataSize);
  205
+				params[i] = new String(bytes);
  206
+				//Log.i("@@@@@", "MA_DB_TYPE_TEXT params[i]: " + params[i]);
  207
+			}
  208
+			else
  209
+			if (MA_DB_TYPE_BLOB == type)
  210
+			{
  211
+				// Read data from struct MADBBlob.
  212
+				int dataAddress = buffer.getInt();
  213
+				int dataSize = buffer.getInt();
  214
+				ByteBuffer dataBuffer = mosync.getMemorySlice(
  215
+					dataAddress,
  216
+					dataSize
  217
+					);
  218
+				byte[] bytes = new byte[dataSize];
  219
+				dataBuffer.get(bytes, 0, dataSize);
  220
+				params[i] = ByteBuffer.wrap(bytes);
  221
+				//Log.i("@@@@@", "MA_DB_TYPE_BLOB params[i]: " + new String(bytes));
  222
+			}
  223
+			else
  224
+			{
  225
+				// TODO: ERROR handling?
  226
+				Log.e("@@@@@@@", "maDBExecSQLParams - unknown data type: " + type);
  227
+			}
  228
+		}
  229
+
  230
+		return params;
  231
+	}
  232
+
  233
+	/**
  234
+	 * Helper function for making SQL queries, used both for
  235
+	 * parameterized and non-parameterized queries.
  236
+	 * @param databaseHandle
  237
+	 * @param sql
  238
+	 * @param params
  239
+	 * @return Success or error code.
  240
+	 */
  241
+	protected int execSQLHelper(
  242
+		int databaseHandle,
  243
+		String sql,
  244
+		Object[] params)
  245
+	{
98 246
 		if (!hasDatabase(databaseHandle))
99 247
 		{
100 248
 			return MA_DB_ERROR;
@@ -104,31 +252,24 @@ public int maDBExecSQL(int databaseHandle, String sql)
104 252
 
105 253
 		try
106 254
 		{
107  
-			// SELECT statements return values and are handled differently than
108  
-			// other statements.
109  
-			// See: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String)
110  
-			if (sql.toLowerCase().contains("select"))
  255
+			//Log.i("@@@@@", "execSQLHelper query: " + sql);
  256
+			MoCursor cursor = database.execQuery(sql, params);
  257
+			if (null != cursor)
111 258
 			{
112  
-				MoCursor cursor = database.execQuery(sql);
113  
-				if (null != cursor)
114  
-				{
115  
-					++mCursorCounter;
116  
-					addCursor(mCursorCounter, cursor);
117  
-					return mCursorCounter;
118  
-				}
119  
-				else
120  
-				{
121  
-					return MA_DB_ERROR;
122  
-				}
  259
+				++mCursorCounter;
  260
+				addCursor(mCursorCounter, cursor);
  261
+				return mCursorCounter;
123 262
 			}
124 263
 			else
125 264
 			{
126  
-				database.execSQL(sql);
127 265
 				return MA_DB_OK;
128 266
 			}
129 267
 		}
130 268
 		catch (SQLiteException ex)
131 269
 		{
  270
+			Log.e("@@@@@", "execSQLHelper exception: " + ex);
  271
+			ex.printStackTrace();
  272
+
132 273
 			logStackTrace(ex);
133 274
 			return MA_DB_ERROR;
134 275
 		}
@@ -495,18 +636,138 @@ public void close()
495 636
 			}
496 637
 		}
497 638
 
498  
-		public MoCursor execQuery(String sql)
  639
+		public MoCursor execQuery(String sql, Object[] params)
499 640
 			throws SQLException
500 641
 		{
501  
-			Cursor cursor = mDB.rawQuery(sql, null);
502  
-			// TODO: Check null return value?
503  
-			return new MoCursor(cursor);
504  
-		}
  642
+			Cursor cursor = null;
505 643
 
506  
-		public void execSQL(String sql)