OpenLayers OpenLayers

Ticket #1699: patch-1699-r7917-B0.diff

File patch-1699-r7917-B0.diff, 41.9 kB (added by elemoine, 2 years ago)
  • build/license.txt

    old new  
    5252 * You may obtain a copy of the License at 
    5353 * http://www.apache.org/licenses/LICENSE-2.0 
    5454 */ 
     55 
     56/** 
     57 * Contains portions of Gears <http://code.google.com/apis/gears/> 
     58 * 
     59 * Copyright 2007, Google Inc. 
     60 * 
     61 * Redistribution and use in source and binary forms, with or without 
     62 * modification, are permitted provided that the following conditions are met: 
     63 * 
     64 *  1. Redistributions of source code must retain the above copyright notice, 
     65 *     this list of conditions and the following disclaimer. 
     66 *  2. Redistributions in binary form must reproduce the above copyright notice, 
     67 *     this list of conditions and the following disclaimer in the documentation 
     68 *     and/or other materials provided with the distribution. 
     69 *  3. Neither the name of Google Inc. nor the names of its contributors may be 
     70 *     used to endorse or promote products derived from this software without 
     71 *     specific prior written permission. 
     72 * 
     73 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
     74 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
     75 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 
     76 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
     77 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
     78 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
     79 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
     80 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
     81 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
     82 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     83 * 
     84 * Sets up google.gears.*, which is *the only* supported way to access Gears. 
     85 * 
     86 * Circumvent this file at your own risk! 
     87 * 
     88 * In the future, Gears may automatically define google.gears.* without this 
     89 * file. Gears may use these objects to transparently fix bugs and compatibility 
     90 * issues. Applications that use the code below will continue to work seamlessly 
     91 * when that happens. 
     92 */ 
  • tests/Protocol/SQL/Gears.html

    old new  
     1<html> 
     2<head> 
     3  <script src="../../../lib/OpenLayers.js"></script> 
     4  <script type="text/javascript"> 
     5 
     6    function test_initialize(t) { 
     7        var protocol = new OpenLayers.Protocol.SQL.Gears(); 
     8        if (!protocol.supported()) { 
     9            t.plan(0); 
     10            return; 
     11        } 
     12 
     13        t.plan(5); 
     14 
     15        t.eq(protocol.CLASS_NAME, "OpenLayers.Protocol.SQL.Gears", 
     16             "ctor returns correct value"); 
     17 
     18        t.eq(protocol.jsonParser.CLASS_NAME, 
     19             "OpenLayers.Format.JSON", 
     20             "ctor creates a JSON parser"); 
     21 
     22        t.eq(protocol.wktParser.CLASS_NAME, 
     23             "OpenLayers.Format.WKT", 
     24             "ctor creates a WKT parser"); 
     25 
     26        var str = protocol.FID_PREFIX + "foo_bar"; 
     27        t.ok(str.match(protocol.fidRegExp), 
     28             "ctor creates correct regexp"); 
     29 
     30        t.ok(typeof protocol.db == "object", 
     31             "ctor creates a db object"); 
     32 
     33        protocol.clear(); 
     34        protocol.destroy(); 
     35    } 
     36 
     37    function test_destroy(t) { 
     38        var protocol = new OpenLayers.Protocol.SQL.Gears(); 
     39        if (!protocol.supported()) { 
     40            t.plan(0); 
     41            return; 
     42        } 
     43 
     44        t.plan(3); 
     45 
     46        protocol.destroy(); 
     47 
     48        t.eq(protocol.db, null, 
     49             "destroy nullifies db"); 
     50        t.eq(protocol.jsonParser, null, 
     51             "destroy nullifies jsonParser"); 
     52        t.eq(protocol.wktParser, null, 
     53             "destroy nullifies wktParser"); 
     54     } 
     55 
     56    function test_read(t) { 
     57        var protocolCallback, readCallback; 
     58        var protocolOptions = {callback: protocolCallback}; 
     59        var readOptions = {callback: readCallback}; 
     60 
     61        var protocol = new OpenLayers.Protocol.SQL.Gears(protocolOptions); 
     62        if (!protocol.supported()) { 
     63            t.plan(0); 
     64            return; 
     65        } 
     66 
     67        function okCallback(resp) { 
     68            t.eq(resp.CLASS_NAME, "OpenLayers.Protocol.Response", 
     69                 "read calls correct callback with a response object"); 
     70        } 
     71 
     72        function failCallback(resp) { 
     73            t.fail("read calls incorrect callback"); 
     74        } 
     75 
     76        t.plan(4); 
     77 
     78        var resp; 
     79 
     80        // 2 tests 
     81        protocolOptions.callback = okCallback; 
     82        readOptions.callback = failCallback; 
     83        resp = protocol.read(); 
     84        t.eq(resp.CLASS_NAME, "OpenLayers.Protocol.Response", 
     85             "read returns a response object"); 
     86 
     87        // 2 test 
     88        protocolOptions.callback = failCallback; 
     89        readOptions.callback = okCallback; 
     90        resp = protocol.read(readOptions); 
     91        t.eq(resp.CLASS_NAME, "OpenLayers.Protocol.Response", 
     92             "read returns a response object"); 
     93 
     94        protocol.clear(); 
     95        protocol.destroy(); 
     96    } 
     97 
     98    function test_unfreezeFeature(t) { 
     99        var protocol = new OpenLayers.Protocol.SQL.Gears(); 
     100        if (!protocol.supported()) { 
     101            t.plan(0); 
     102            return; 
     103        } 
     104 
     105        t.plan(10); 
     106 
     107        var feature; 
     108        var wkt, json, fid, state; 
     109 
     110        json = "{\"fake\":\"properties\"}"; 
     111        fid = "1000"; 
     112        state = OpenLayers.State.INSERT; 
     113 
     114        var row = { 
     115            fieldByName: function(str) { 
     116                if (str == "geometry") { 
     117                    return wkt; 
     118                } 
     119                if (str == "properties") { 
     120                    return json; 
     121                } 
     122                if (str == "fid") { 
     123                    return fid; 
     124                } 
     125                if (str == "state") { 
     126                    return state; 
     127                } 
     128            } 
     129        }; 
     130 
     131        // 5 tests 
     132        wkt = "POINT(1 2)"; 
     133        feature = protocol.unfreezeFeature(row); 
     134        t.eq(feature.CLASS_NAME, "OpenLayers.Feature.Vector", 
     135             "unfreezeFeature returns an OpenLayers.Feature.Vector"); 
     136        t.ok(feature.geometry.x == 1 && feature.geometry.y == 2, 
     137             "unfreezeFeature returns a feature with correct geometry"); 
     138        t.eq(feature.attributes.fake, "properties", 
     139             "unfreezeFeature returns a feature with correct attributes"); 
     140        t.eq(feature.fid, fid, 
     141             "unfreezeFeature returns a feature with fid"); 
     142        t.eq(feature.state, state, 
     143             "unfreezeFeature returns a feature with state"); 
     144 
     145        // 5 tests 
     146        wkt = protocol.NULL_GEOMETRY; 
     147        state = protocol.NULL_FEATURE_STATE; 
     148        feature = protocol.unfreezeFeature(row); 
     149        t.eq(feature.CLASS_NAME, "OpenLayers.Feature.Vector", 
     150             "unfreezeFeature returns an OpenLayers.Feature.Vector"); 
     151        t.eq(feature.geometry, null, 
     152             "unfreezeFeature returns a feature with correct geometry"); 
     153        t.eq(feature.attributes.fake, "properties", 
     154             "unfreezeFeature returns a feature with correct attributes"); 
     155        t.eq(feature.fid, fid, 
     156             "unfreezeFeature returns a feature with fid"); 
     157        t.eq(feature.state, null, 
     158             "unfreezeFeature returns a feature with state"); 
     159 
     160        protocol.clear(); 
     161        protocol.destroy(); 
     162    } 
     163 
     164    function test_extractFidFromField(t) { 
     165        var protocol = new OpenLayers.Protocol.SQL.Gears(); 
     166        if (!protocol.supported()) { 
     167            t.plan(0); 
     168            return; 
     169        } 
     170 
     171        t.plan(4); 
     172 
     173        var field, fid; 
     174 
     175        // fid is a string, field is not prefixed with FID_PREFIX 
     176        // 1 test 
     177        field = "10"; 
     178        res = protocol.extractFidFromField(field); 
     179        t.eq(res, "10", 
     180             "extractFidFromField returns expected string"); 
     181 
     182        // fid is a string, field is prefixed with FID_PREFIX 
     183        // 1 test 
     184        field = protocol.FIX_PREFIX + "10"; 
     185        res = protocol.extractFidFromField(field); 
     186        t.eq(res, protocol.FIX_PREFIX + "10", 
     187             "extractFidFromField returns expected prefixed string"); 
     188 
     189        // fid is a number, field is not prefixed with FIX_PREFIX 
     190        // 1 test 
     191        protocol.typeOfFid = "number"; 
     192        field = "10"; 
     193        res = protocol.extractFidFromField(field); 
     194        t.eq(res, 10, 
     195             "extractFidFromField returns expected number"); 
     196 
     197        // fid is a number, field is prefixed with FIX_PREFIX 
     198        // 1 test 
     199        protocol.typeOfFid = "number"; 
     200        field = protocol.FID_PREFIX + "10"; 
     201        res = protocol.extractFidFromField(field); 
     202        t.eq(res, protocol.FID_PREFIX + "10", 
     203             "extractFidFromField returns expected prefixed string"); 
     204    } 
     205 
     206    function test_freezeFeature(t) { 
     207        var protocol = new OpenLayers.Protocol.SQL.Gears(); 
     208        if (!protocol.supported()) { 
     209            t.plan(0); 
     210            return; 
     211        } 
     212 
     213        t.plan(8); 
     214 
     215        var feature, res; 
     216 
     217        // 4 tests 
     218        feature = new OpenLayers.Feature.Vector(); 
     219        feature.geometry = new OpenLayers.Geometry.Point(1, 2); 
     220        feature.attributes.fake = "properties"; 
     221        feature.fid = "1000"; 
     222        feature.state = OpenLayers.State.INSERT; 
     223        res = protocol.freezeFeature(feature); 
     224        t.eq(res[0], feature.fid, 
     225             "freezeFeature returns correct fid"); 
     226        t.eq(res[1], "POINT(1 2)", 
     227             "freezeFeature returns correct WKT"); 
     228        t.eq(res[2], "{\"fake\":\"properties\"}", 
     229             "freezeFeature returns correct JSON"); 
     230        t.eq(res[3], feature.state, 
     231             "freezeFeature returns correct feature state"); 
     232 
     233        // 4 tests 
     234        protocol.saveFeatureState = false; 
     235        feature = new OpenLayers.Feature.Vector(); 
     236        feature.attributes.fake = "properties"; 
     237        feature.fid = "1000"; 
     238        feature.state = OpenLayers.State.INSERT; 
     239        res = protocol.freezeFeature(feature); 
     240        t.eq(res[0], feature.fid, 
     241             "freezeFeature returns correct fid"); 
     242        t.eq(res[1], protocol.NULL_GEOMETRY, 
     243             "freezeFeature returns expected null geom string"); 
     244        t.eq(res[2], "{\"fake\":\"properties\"}", 
     245             "freezeFeature returns correct JSON"); 
     246        t.eq(res[3], protocol.NULL_FEATURE_STATE, 
     247             "freezeFeature returns expected null feature state string"); 
     248 
     249        protocol.clear(); 
     250        protocol.destroy(); 
     251     } 
     252 
     253     function test_create(t) { 
     254        var protocol = new OpenLayers.Protocol.SQL.Gears(); 
     255        if (!protocol.supported()) { 
     256            t.plan(0); 
     257            return; 
     258        } 
     259 
     260        t.plan(8); 
     261 
     262        var resp; 
     263        var scope = {"fake": "scope"}; 
     264 
     265        var options = { 
     266            callback: function(resp) { 
     267                t.eq(resp.CLASS_NAME, "OpenLayers.Protocol.Response", 
     268                     "user callback is passed a response"); 
     269                t.eq(resp.requestType, "create", 
     270                     "user callback is passed correct request type in resp"); 
     271                t.ok(this == scope, 
     272                     "user callback called with correct scope"); 
     273            }, 
     274            scope: scope 
     275        }; 
     276 
     277        // 4 tests 
     278        var feature = new OpenLayers.Feature.Vector(); 
     279        feature.fid = "1000"; 
     280        feature.attributes.fake = "properties"; 
     281        feature.state = OpenLayers.State.INSERT; 
     282        resp = protocol.create([feature], options); 
     283        t.eq(resp.CLASS_NAME, "OpenLayers.Protocol.Response", 
     284             "create returns a response"); 
     285 
     286        // check what we have in the DB 
     287        // 4 tests 
     288        resp = protocol.read({"noFeatureStateReset": true}); 
     289        t.eq(resp.features.length, 1, 
     290             "create inserts feature in the DB"); 
     291        t.eq(resp.features[0].fid, feature.fid, 
     292             "create inserts feature with correct fid"); 
     293        t.eq(resp.features[0].attributes.fake, feature.attributes.fake, 
     294             "create inserts feature with correct attributes"); 
     295        t.eq(resp.features[0].state, feature.state, 
     296             "create inserts feature with correct state"); 
     297 
     298        protocol.clear(); 
     299        protocol.destroy(); 
     300    } 
     301 
     302     function test_createOrUpdate(t) { 
     303        var protocol = new OpenLayers.Protocol.SQL.Gears(); 
     304        if (!protocol.supported()) { 
     305            t.plan(0); 
     306            return; 
     307        } 
     308 
     309        t.plan(5); 
     310 
     311        // 1 test 
     312        var feature = new OpenLayers.Feature.Vector(); 
     313        feature.fid = "1000"; 
     314        feature.attributes.fake = "properties"; 
     315        feature.state = OpenLayers.State.INSERT; 
     316        resp = protocol.createOrUpdate([feature]); 
     317        t.eq(resp.CLASS_NAME, "OpenLayers.Protocol.Response", 
     318             "createOrUpdate returns a response"); 
     319 
     320        // check what we have in the DB 
     321        // 4 tests 
     322        resp = protocol.read({"noFeatureStateReset": true}); 
     323        t.eq(resp.features.length, 1, 
     324             "createOrUpdate inserts feature in the DB"); 
     325        t.eq(resp.features[0].fid, feature.fid, 
     326             "createOrUpdate inserts feature with correct fid"); 
     327        t.eq(resp.features[0].attributes.fake, feature.attributes.fake, 
     328             "createOrUpdate inserts feature with correct attributes"); 
     329        t.eq(resp.features[0].state, feature.state, 
     330             "createOrUpdate inserts feature with correct state"); 
     331 
     332        protocol.clear(); 
     333        protocol.destroy(); 
     334    } 
     335 
     336    function test_delete(t) { 
     337        var protocol = new OpenLayers.Protocol.SQL.Gears(); 
     338        if (!protocol.supported()) { 
     339            t.plan(0); 
     340            return; 
     341        } 
     342 
     343        t.plan(4); 
     344 
     345        function createOneAndDeleteOne(fid, deleteOptions) { 
     346            var feature = new OpenLayers.Feature.Vector(); 
     347            feature.fid = fid; 
     348            feature.attributes.fake = "properties"; 
     349            feature.state = OpenLayers.State.INSERT; 
     350            var r = protocol.create([feature]); 
     351            protocol["delete"](r.reqFeatures, deleteOptions); 
     352        } 
     353 
     354        var resp, fid; 
     355 
     356        // 1 test 
     357        fid = 1000; 
     358        protocol.saveFeatureState = false; 
     359        createOneAndDeleteOne(fid) 
     360        resp = protocol.read(); 
     361        t.eq(resp.features.length, 0, 
     362             "delete deletes feature if saveFeatureState is false"); 
     363        protocol.clear(); 
     364 
     365        // 1 test 
     366        fid = 1000; 
     367        protocol.saveFeatureState = true; 
     368        createOneAndDeleteOne(fid); 
     369        resp = protocol.read(); 
     370        t.eq(resp.features.length, 1, 
     371             "delete does not delete feature if saveFeatureState is true"); 
     372        protocol.clear(); 
     373 
     374        // 1 test 
     375        fid = "1000"; 
     376        protocol.saveFeatureState = true; 
     377        createOneAndDeleteOne(fid); 
     378        resp = protocol.read(); 
     379        t.eq(resp.features.length, 1, 
     380             "delete does not delete feature if saveFeatureState is true"); 
     381        protocol.clear(); 
     382 
     383        // 1 test 
     384        fid = protocol.FID_PREFIX + "1000"; 
     385        protocol.saveFeatureState = true; 
     386        createOneAndDeleteOne(fid, {dontDelete: true}); 
     387        resp = protocol.read(); 
     388        t.eq(resp.features.length, 0, 
     389             "delete deletes feature if saveFeatureState is true and fid is prefixed"); 
     390        protocol.clear(); 
     391 
     392        protocol.destroy(); 
     393    } 
     394 
     395    function test_callUserCallback(t) { 
     396        var protocol = new OpenLayers.Protocol.SQL.Gears(); 
     397        if (!protocol.supported()) { 
     398            t.plan(0); 
     399            return; 
     400        } 
     401 
     402        t.plan(6); 
     403 
     404        var options, resp; 
     405        var scope = {'fake': 'scope'}; 
     406 
     407        // test commit callback 
     408        // 1 tests 
     409        options = { 
     410            'callback': function() { 
     411                t.ok(this == scope, 'callback called with correct scope'); 
     412            }, 
     413            'scope': scope 
     414        }; 
     415        resp = {'requestType': 'create', 'last': true}; 
     416        protocol.callUserCallback(options, resp); 
     417        // 0 test 
     418        resp = {'requestType': 'create', 'last': false}; 
     419        protocol.callUserCallback(options, resp); 
     420 
     421        // test create callback 
     422        // 2 tests 
     423        options = { 
     424            'create': { 
     425                'callback': function(r) { 
     426                    t.ok(this == scope, 'callback called with correct scope'); 
     427                    t.ok(r == resp, 'callback called with correct response'); 
     428                }, 
     429                'scope': scope 
     430            } 
     431        }; 
     432        resp = {'requestType': 'create'}; 
     433        protocol.callUserCallback(options, resp); 
     434 
     435        // test with both callbacks set 
     436        // 3 tests 
     437        options = { 
     438            'create': { 
     439                'callback': function(r) { 
     440                    t.ok(this == scope, 'callback called with correct scope'); 
     441                    t.ok(r == resp, 'callback called with correct response'); 
     442                }, 
     443                'scope': scope 
     444            }, 
     445            'callback': function() { 
     446                t.ok(this == scope, 'callback called with correct scope'); 
     447            }, 
     448            'scope': scope 
     449        }; 
     450        resp = {'requestType': 'create', 'last': true}; 
     451        protocol.callUserCallback(options, resp); 
     452 
     453        // no callback set 
     454        // 0 test 
     455        options = { 
     456            'delete': { 
     457                'callback': function(resp) { 
     458                    t.fail('callback should not get called'); 
     459                } 
     460            } 
     461        }; 
     462        resp = {'requestType': 'create'}; 
     463        protocol.callUserCallback(options, resp); 
     464 
     465        // cleanup 
     466        protocol.destroy(); 
     467    } 
     468 
     469  </script> 
     470</head> 
     471<body> 
     472</body> 
     473</html> 
  • tests/Protocol/SQL.html

    old new  
     1<html> 
     2<head> 
     3  <script src="../../lib/OpenLayers.js"></script> 
     4  <script type="text/javascript"> 
     5 
     6    function test_initialize(t) { 
     7        t.plan(3); 
     8        var options = {tableName: 'my_features',  
     9                       databaseName: 'my_database_name'} 
     10        var protocol = new OpenLayers.Protocol.SQL(options); 
     11 
     12        t.ok(protocol instanceof OpenLayers.Protocol.SQL, 
     13             "new OpenLayers.Protocol.SQL returns object"); 
     14 
     15        t.eq(protocol.tableName, options.tableName, "tableName property is set"); 
     16        t.eq(protocol.databaseName, options.databaseName, "databaseName property is set"); 
     17    } 
     18     
     19  </script> 
     20</head> 
     21<body> 
     22</body> 
     23</html> 
  • tests/list-tests.html

    old new  
    113113    <li>Popup/FramedCloud.html</li> 
    114114    <li>Projection.html</li> 
    115115    <li>Protocol.html</li> 
     116    <li>Protocol/SQL.html</li> 
     117    <li>Protocol/SQL/Gears.html</li> 
    116118    <li>Renderer.html</li> 
    117119    <li>Renderer/Canvas.html</li> 
    118120    <li>Renderer/Elements.html</li> 
  • lib/OpenLayers/Protocol/SQL/Gears.js

    old new  
     1/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD 
     2 * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the 
     3 * full text of the license. */ 
     4 
     5/** 
     6 * @requires Gears/gears_init.js 
     7 * @requires OpenLayers/Protocol/SQL.js 
     8 * @requires OpenLayers/Format/JSON.js 
     9 * @requires OpenLayers/Format/WKT.js 
     10 */ 
     11 
     12/** 
     13 * Class: OpenLayers.Protocol.SQL.Gears 
     14 * This Protocol stores feature in the browser via the Gears Database module  
     15 * <http://code.google.com/apis/gears/api_database.html>. 
     16 * 
     17 * The main advantage is that all the read, create, update and delete operations  
     18 * can be done offline. 
     19 * 
     20 * Inherits from: 
     21 *  - <OpenLayers.Protocol.SQL> 
     22 */ 
     23OpenLayers.Protocol.SQL.Gears = OpenLayers.Class(OpenLayers.Protocol.SQL, { 
     24 
     25    /** 
     26     * Property: FID_PREFIX 
     27     * {String} 
     28     */ 
     29    FID_PREFIX: '__gears_fid__', 
     30 
     31    /** 
     32     * Property: NULL_GEOMETRY 
     33     * {String} 
     34     */ 
     35    NULL_GEOMETRY: '__gears_null_geometry__', 
     36 
     37    /** 
     38     * Property: NULL_FEATURE_STATE 
     39     * {String} 
     40     */ 
     41    NULL_FEATURE_STATE: '__gears_null_feature_state__', 
     42 
     43    /** 
     44     * Property: jsonParser 
     45     * {<OpenLayers.Format.JSON>} 
     46     */ 
     47    jsonParser: null, 
     48 
     49    /** 
     50     * Property: wktParser 
     51     * {<OpenLayers.Format.WKT>} 
     52     */ 
     53    wktParser: null, 
     54 
     55    /** 
     56     * Property: fidRegExp 
     57     * {RegExp} Regular expression to know whether a feature was 
     58     *      created in offline mode. 
     59     */ 
     60    fidRegExp: null, 
     61 
     62    /** 
     63     * Property: saveFeatureState 
     64     * {Boolean} Whether to save the feature state (<OpenLayers.State>) 
     65     *      into the database, defaults to true. 
     66     */     
     67    saveFeatureState: true, 
     68 
     69    /** 
     70     * Property: typeOfFid 
     71     * {String} The type of the feature identifier, either "number" or 
     72     *      "string", defaults to "string". 
     73     */ 
     74    typeOfFid: "string", 
     75 
     76    /** 
     77     * Property: db 
     78     * {GearsDatabase} 
     79     */ 
     80    db: null, 
     81 
     82    /** 
     83     * Constructor: OpenLayers.Protocol.SQL.Gears 
     84     */ 
     85    initialize: function(options) { 
     86        if (!this.supported()) { 
     87            return; 
     88        } 
     89        OpenLayers.Protocol.SQL.prototype.initialize.apply(this, [options]); 
     90        this.jsonParser = new OpenLayers.Format.JSON(); 
     91        this.wktParser = new OpenLayers.Format.WKT(); 
     92 
     93        this.fidRegExp = new RegExp('^' + this.FID_PREFIX); 
     94        this.initializeDatabase(); 
     95 
     96         
     97    }, 
     98 
     99    /** 
     100     * Method: initializeDatabase 
     101     */ 
     102    initializeDatabase: function() { 
     103        this.db = google.gears.factory.create('beta.database'); 
     104        this.db.open(this.databaseName); 
     105        this.db.execute( 
     106            "CREATE TABLE IF NOT EXISTS " + this.tableName + 
     107            " (fid TEXT UNIQUE, geometry TEXT, properties TEXT," + 
     108            "  state TEXT)"); 
     109   }, 
     110 
     111    /** 
     112     * APIMethod: destroy 
     113     * Clean up the protocol. 
     114     */ 
     115    destroy: function() { 
     116        this.db.close(); 
     117        this.db = null; 
     118 
     119        this.jsonParser = null; 
     120        this.wktParser = null; 
     121 
     122        OpenLayers.Protocol.SQL.prototype.destroy.apply(this); 
     123    }, 
     124 
     125    /** 
     126     * APIMethod: supported 
     127     * Determine whether a browser supports Gears 
     128     * 
     129     * Returns: 
     130     * {Boolean} The browser supports Gears 
     131     */ 
     132    supported: function() { 
     133        return !!(window.google && google.gears); 
     134    }, 
     135 
     136    /** 
     137     * Method: read 
     138     * Read all features from the database and return a 
     139     * <OpenLayers.Protocol.Response> instance. If the options parameter 
     140     * contains a callback attribute, the function is called with the response 
     141     * as a parameter. 
     142     * 
     143     * Parameters: 
     144     * options - {Object} Optional object for configuring the request; it 
     145     *      can have the {Boolean} property "noFeatureStateReset" which 
     146     *      specifies if the state of features read from the Gears 
     147     *      database must be reset to null, if "noFeatureStateReset" 
     148     *      is undefined or false then each feature's state is reset 
     149     *      to null, if "noFeatureStateReset" is true the feature state 
     150     *      is preserved. 
     151     * 
     152     * Returns: 
     153     * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response> 
     154     *      object. 
     155     */ 
     156    read: function(options) { 
     157        options = OpenLayers.Util.applyDefaults(options, this.options); 
     158 
     159        var feature, features = []; 
     160        var rs = this.db.execute("SELECT * FROM " + this.tableName); 
     161        while (rs.isValidRow()) { 
     162            feature = this.unfreezeFeature(rs); 
     163            if (!options.noFeatureStateReset) { 
     164                feature.state = null; 
     165            } 
     166            features.push(feature); 
     167            rs.next(); 
     168        } 
     169        rs.close(); 
     170 
     171        var resp = new OpenLayers.Protocol.Response({ 
     172            code: OpenLayers.Protocol.Response.SUCCESS, 
     173            requestType: "read", 
     174            features: features 
     175        }); 
     176 
     177        if (options && options.callback) { 
     178            options.callback.call(options.scope, resp); 
     179        } 
     180 
     181        return resp; 
     182    }, 
     183 
     184    /** 
     185     * Method: unfreezeFeature 
     186     * 
     187     * Parameters: 
     188     * row - {ResultSet} 
     189     * 
     190     * Returns: 
     191     * {<OpenLayers.Feature.Vector>} 
     192     */ 
     193    unfreezeFeature: function(row) { 
     194        var feature; 
     195        var wkt = row.fieldByName('geometry'); 
     196        if (wkt == this.NULL_GEOMETRY) { 
     197            feature = new OpenLayers.Feature.Vector(); 
     198        } else { 
     199            feature = this.wktParser.read(wkt); 
     200        } 
     201 
     202        feature.attributes = this.jsonParser.read( 
     203            row.fieldByName('properties')); 
     204 
     205        feature.fid = this.extractFidFromField(row.fieldByName('fid')); 
     206 
     207        var state = row.fieldByName('state'); 
     208        if (state == this.NULL_FEATURE_STATE) { 
     209            state = null; 
     210        } 
     211        feature.state = state; 
     212 
     213        return feature; 
     214    }, 
     215 
     216    /** 
     217     * Method: extractFidFromField 
     218     * 
     219     * Parameters: 
     220     * field - {String} 
     221     * 
     222     * Returns 
     223     * {String} or {Number} The fid. 
     224     */ 
     225    extractFidFromField: function(field) { 
     226        if (!field.match(this.fidRegExp) && this.typeOfFid == "number") { 
     227            field = parseFloat(field); 
     228        } 
     229        return field; 
     230    }, 
     231 
     232    /** 
     233     * Method: create 
     234     * Create new features into the database. 
     235     * 
     236     * Parameters: 
     237     * features - {Array({<OpenLayers.Feature.Vector>})} or 
     238     *            {<OpenLayers.Feature.Vector>} The features to create in 
     239     *            the database. 
     240     * options - {Object} Optional object for configuring the request. 
     241     * 
     242     * Returns: 
     243     *  {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response> 
     244     *          object. 
     245     */ 
     246    create: function(features, options) { 
     247        options = OpenLayers.Util.applyDefaults(options, this.options); 
     248 
     249        var resp = this.createOrUpdate(features); 
     250        resp.requestType = "create"; 
     251 
     252        if (options && options.callback) { 
     253            options.callback.call(options.scope, resp); 
     254        } 
     255 
     256        return resp; 
     257    }, 
     258 
     259    /** 
     260     * Method: update 
     261     * Construct a request updating modified feature. 
     262     * 
     263     * Parameters: 
     264     * features - {Array({<OpenLayers.Feature.Vector>})} or 
     265     *            {<OpenLayers.Feature.Vector>} The features to update in 
     266     *            the database. 
     267     * options - {Object} Optional object for configuring the request. 
     268     * 
     269     * Returns: 
     270     *  {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response> 
     271     *          object. 
     272     */ 
     273    update: function(features, options) { 
     274        options = OpenLayers.Util.applyDefaults(options, this.options); 
     275 
     276        var resp = this.createOrUpdate(features); 
     277        resp.requestType = "update"; 
     278 
     279        if (options && options.callback) { 
     280            options.callback.call(options.scope, resp); 
     281        } 
     282 
     283        return resp; 
     284    }, 
     285 
     286    /** 
     287     * Method: createOrUpdate 
     288     * Construct a request for updating or creating features in the 
     289     * database. 
     290     * 
     291     * Parameters: 
     292     * features - {Array({<OpenLayers.Feature.Vector>})} or 
     293     *      {<OpenLayers.Feature.Vector>} The feature to create or update 
     294     *      in the database. 
     295     * 
     296     * Returns: 
     297     *  {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response> 
     298     *          object. 
     299     */ 
     300    createOrUpdate: function(features) { 
     301        if (!(features instanceof Array)) { 
     302            features = [features]; 
     303        } 
     304 
     305        var i, len = features.length, feature; 
     306        var insertedFeatures = new Array(len); 
     307  
     308        for (i = 0; i < len; i++) { 
     309            feature = features[i]; 
     310            var params = this.freezeFeature(feature); 
     311            this.db.execute( 
     312                "REPLACE INTO " + this.tableName +  
     313                " (fid, geometry, properties, state)" +  
     314                " VALUES (?, ?, ?, ?)", 
     315                params); 
     316 
     317            var clone = feature.clone(); 
     318            clone.fid = this.extractFidFromField(params[0]); 
     319            insertedFeatures[i] = clone; 
     320        } 
     321 
     322        return new OpenLayers.Protocol.Response({ 
     323            code: OpenLayers.Protocol.Response.SUCCESS, 
     324            features: insertedFeatures, 
     325            reqFeatures: features 
     326        }); 
     327    }, 
     328 
     329    /** 
     330     * Method: freezeFeature 
     331     * 
     332     * Parameters: 
     333     * feature - {<OpenLayers.Feature.Vector>} 
     334     * state - {String} The feature state to store in the database. 
     335     * 
     336     * Returns: 
     337     * {Array} 
     338     */ 
     339    freezeFeature: function(feature) { 
     340        // 2 notes: 
     341        // - fid might not be a string 
     342        // - getFeatureStateForFreeze needs the feature fid to it's stored 
     343        //   in the feature here 
     344        feature.fid = feature.fid != null ? 
     345            "" + feature.fid : OpenLayers.Util.createUniqueID(this.FID_PREFIX); 
     346 
     347        var geometry = feature.geometry != null ? 
     348            feature.geometry.toString() : this.NULL_GEOMETRY; 
     349 
     350        var properties = this.jsonParser.write(feature.attributes); 
     351 
     352        var state = this.getFeatureStateForFreeze(feature); 
     353 
     354        return [feature.fid, geometry, properties, state]; 
     355    }, 
     356 
     357    /** 
     358     * Method: getFeatureStateForFreeze 
     359     * Get the state of the feature to store into the database. 
     360     * 
     361     * Parameters: 
     362     * feature - {<OpenLayers.Feature.Vector>} The feature. 
     363     * 
     364     * Returns 
     365     * {String} The state 
     366     */ 
     367    getFeatureStateForFreeze: function(feature) { 
     368        var state; 
     369        if (!this.saveFeatureState) { 
     370            state = this.NULL_FEATURE_STATE; 
     371        } else if (this.createdOffline(feature)) { 
     372            // if the feature was created in offline mode, its 
     373            // state must remain INSERT 
     374            state = OpenLayers.State.INSERT; 
     375        } else { 
     376            state = feature.state; 
     377        } 
     378        return state; 
     379    }, 
     380 
     381    /** 
     382     * Method: delete 
     383     * Delete features from the database. 
     384     * 
     385     * Parameters: 
     386     * features - {Array({<OpenLayers.Feature.Vector>})} or 
     387     *            {<OpenLayers.Feature.Vector>} 
     388     * options - {Object} Optional object for configuring the request. 
     389     *       This object is modified and should not be reused. 
     390     * 
     391     * Returns: 
     392     *  {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response> 
     393     *          object. 
     394     */ 
     395    "delete": function(features, options) { 
     396        if (!(features instanceof Array)) { 
     397            features = [features]; 
     398        } 
     399 
     400        options = OpenLayers.Util.applyDefaults(options, this.options); 
     401 
     402        var i, len, feature; 
     403        for (i = 0, len = features.length; i < len; i++) { 
     404            feature = features[i]; 
     405 
     406            // if saveFeatureState is set to true and if the feature wasn't created 
     407            // in offline mode we don't delete it in the database but just update  
     408            // it state column 
     409            if (this.saveFeatureState && !this.createdOffline(feature)) { 
     410                var toDelete = feature.clone(); 
     411                toDelete.fid = feature.fid; 
     412                if (toDelete.geometry) { 
     413                    toDelete.geometry.destroy(); 
     414                    toDelete.geometry = null; 
     415                } 
     416                toDelete.state = feature.state; 
     417                this.createOrUpdate(toDelete); 
     418            } else { 
     419                this.db.execute( 
     420                    "DELETE FROM " + this.tableName + 
     421                    " WHERE fid = ?", [feature.fid]); 
     422            } 
     423        } 
     424 
     425        var resp = new OpenLayers.Protocol.Response({ 
     426            code: OpenLayers.Protocol.Response.SUCCESS, 
     427            requestType: "delete", 
     428            reqFeatures: features 
     429        }); 
     430 
     431        if (options && options.callback) { 
     432            options.callback.call(options.scope, resp); 
     433        } 
     434 
     435        return resp; 
     436    }, 
     437 
     438    /** 
     439     * Method: createdOffline 
     440     * Returns true if the feature had a feature id when it was created in 
     441     *      the Gears database, false otherwise; this is determined by 
     442     *      checking the form of the feature's fid value. 
     443     * 
     444     * Parameters: 
     445     * feature - {<OpenLayers.Feature.Vector>} 
     446     * 
     447     * Returns: 
     448     * {Boolean} 
     449     */ 
     450    createdOffline: function(feature) { 
     451        return (typeof feature.fid == "string" && 
     452                !!(feature.fid.match(this.fidRegExp))); 
     453    }, 
     454 
     455    /** 
     456     * Method: commit 
     457     * Go over the features and for each take action 
     458     * based on the feature state. Possible actions are create, 
     459     * update and delete. 
     460     * 
     461     * Parameters: 
     462     * features - {Array({<OpenLayers.Feature.Vector>})} 
     463     * options - {Object} Object whose possible keys are "create", "update", 
     464     *      "delete", "callback" and "scope", the values referenced by the 
     465     *      first three are objects as passed to the "create", "update", and 
     466     *      "delete" methods, the value referenced by the "callback" key is 
     467     *      a function which is called when the commit operation is complete 
     468     *      using the scope referenced by the "scope" key. 
     469     * 
     470     * Returns: 
     471     * {Array({<OpenLayers.Protocol.Response>})} An array of 
     472     *       <OpenLayers.Protocol.Response> objects, one per request made 
     473     *       to the database. 
     474     */ 
     475    commit: function(features, options) { 
     476        var opt, resp = [], nRequests = 0, nResponses = 0; 
     477 
     478        function callback(resp) { 
     479            if (++nResponses < nRequests) { 
     480                resp.last = false; 
     481            } 
     482            this.callUserCallback(options, resp); 
     483        } 
     484 
     485        var feature, toCreate = [], toUpdate = [], toDelete = []; 
     486        for (var i = features.length - 1; i >= 0; i--) { 
     487            feature = features[i]; 
     488            switch (feature.state) { 
     489            case OpenLayers.State.INSERT: 
     490                toCreate.push(feature); 
     491                break; 
     492            case OpenLayers.State.UPDATE: 
     493                toUpdate.push(feature); 
     494                break; 
     495            case OpenLayers.State.DELETE: 
     496                toDelete.push(feature); 
     497                break; 
     498            } 
     499        } 
     500        if (toCreate.length > 0) { 
     501            nRequests++; 
     502            opt = OpenLayers.Util.applyDefaults( 
     503                {"callback": callback, "scope": this}, 
     504                options.create 
     505            ); 
     506            resp.push(this.create(toCreate, opt)); 
     507        } 
     508        if (toUpdate.length > 0) { 
     509            nRequests++; 
     510            opt = OpenLayers.Util.applyDefaults( 
     511                {"callback": callback, "scope": this}, 
     512                options.update 
     513            ); 
     514            resp.push(this.update(toUpdate, opt)); 
     515        } 
     516        if (toDelete.length > 0) { 
     517            nRequests++; 
     518            opt = OpenLayers.Util.applyDefaults( 
     519                {"callback": callback, "scope": this}, 
     520                options["delete"] 
     521            ); 
     522            resp.push(this["delete"](toDelete, opt)); 
     523        } 
     524 
     525        return resp; 
     526    }, 
     527 
     528    /** 
     529     * Method: clear 
     530     * Removes all rows of the table. 
     531     */ 
     532    clear: function() { 
     533        this.db.execute("DELETE FROM " + this.tableName); 
     534    }, 
     535 
     536    /** 
     537     * Method: callUserCallback 
     538     * This method is called from within commit each time a request is made 
     539     * to the database, it is responsible for calling the user-supplied 
     540     * callbacks. 
     541     * 
     542     * Parameters: 
     543     * options - {Object} The map of options passed to the commit call. 
     544     * resp - {<OpenLayers.Protocol.Response>} 
     545     */ 
     546    callUserCallback: function(options, resp) { 
     547        var opt = options[resp.requestType]; 
     548        if (opt && opt.callback) { 
     549            opt.callback.call(opt.scope, resp); 
     550        } 
     551        if (resp.last && options.callback) { 
     552            options.callback.call(options.scope); 
     553        } 
     554    }, 
     555 
     556    CLASS_NAME: "OpenLayers.Protocol.SQL.Gears" 
     557}); 
  • lib/OpenLayers/Protocol/SQL.js

    old new  
     1/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD 
     2 * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the 
     3 * full text of the license. */ 
     4 
     5/** 
     6 * @requires OpenLayers/Protocol.js 
     7 */ 
     8 
     9/** 
     10 * Class: OpenLayers.Protocol.SQL 
     11 * Abstract SQL protocol class.  Not to be instantiated directly.  Use 
     12 *     one of the SQL protocol subclasses instead. 
     13 * 
     14 * Inherits from: 
     15 *  - <OpenLayers.Protocol> 
     16 */ 
     17OpenLayers.Protocol.SQL = OpenLayers.Class(OpenLayers.Protocol, { 
     18 
     19    /** 
     20     * APIProperty: databaseName 
     21     * {String} 
     22     */ 
     23    databaseName: 'ol', 
     24 
     25    /** 
     26     * APIProperty: tableName 
     27     * Name of the database table into which Features should be saved. 
     28     */ 
     29    tableName: "ol_vector_features", 
     30 
     31    /** 
     32     * Constructor: OpenLayers.Protocol.SQL 
     33     */ 
     34    initialize: function(options) { 
     35        OpenLayers.Protocol.prototype.initialize.apply(this, [options]); 
     36    }, 
     37 
     38    /** 
     39     * APIMethod: destroy 
     40     * Clean up the protocol. 
     41     */ 
     42    destroy: function() { 
     43        OpenLayers.Protocol.prototype.destroy.apply(this); 
     44    }, 
     45 
     46    /** 
     47     * APIMethod: supported 
     48     * This should be overridden by specific subclasses 
     49     * 
     50     * Returns: 
     51     * {Boolean} Whether or not the browser supports the SQL backend 
     52     */ 
     53    supported: function() { 
     54        return false; 
     55    }, 
     56 
     57    CLASS_NAME: "OpenLayers.Protocol.SQL" 
     58}); 
  • lib/Gears/gears_init.js

    old new  
     1/* 
     2 * Copyright 2007, Google Inc. 
     3 * 
     4 * Redistribution and use in source and binary forms, with or without 
     5 * modification, are permitted provided that the following conditions are met: 
     6 * 
     7 *  1. Redistributions of source code must retain the above copyright notice, 
     8 *     this list of conditions and the following disclaimer. 
     9 *  2. Redistributions in binary form must reproduce the above copyright notice, 
     10 *     this list of conditions and the following disclaimer in the documentation 
     11 *     and/or other materials provided with the distribution. 
     12 *  3. Neither the name of Google Inc. nor the names of its contributors may be 
     13 *     used to endorse or promote products derived from this software without 
     14 *     specific prior written permission. 
     15 * 
     16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
     17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
     18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 
     19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
     20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
     21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
     22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
     23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
     24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
     25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     26 * 
     27 * Sets up google.gears.*, which is *the only* supported way to access Gears. 
     28 * 
     29 * Circumvent this file at your own risk! 
     30 * 
     31 * In the future, Gears may automatically define google.gears.* without this 
     32 * file. Gears may use these objects to transparently fix bugs and compatibility 
     33 * issues. Applications that use the code below will continue to work seamlessly 
     34 * when that happens. 
     35 */ 
     36 
     37(function() { 
     38  // We are already defined. Hooray! 
     39  if (window.google && google.gears) { 
     40    return; 
     41  } 
     42 
     43  var factory = null; 
     44 
     45  // Firefox 
     46  if (typeof GearsFactory != 'undefined') { 
     47    factory = new GearsFactory(); 
     48  } else { 
     49    // IE 
     50    try { 
     51      factory = new ActiveXObject('Gears.Factory'); 
     52      // privateSetGlobalObject is only required and supported on WinCE. 
     53      if (factory.getBuildInfo().indexOf('ie_mobile') != -1) { 
     54        factory.privateSetGlobalObject(this); 
     55      } 
     56    } catch (e) { 
     57      // Safari 
     58      if ((typeof navigator.mimeTypes != 'undefined') 
     59           && navigator.mimeTypes["application/x-googlegears"]) { 
     60        factory = document.createElement("object"); 
     61        factory.style.display = "none"; 
     62        factory.width = 0; 
     63        factory.height = 0; 
     64        factory.type = "application/x-googlegears"; 
     65        document.documentElement.appendChild(factory); 
     66      } 
     67    } 
     68  } 
     69 
     70  // *Do not* define any objects if Gears is not installed. This mimics the 
     71  // behavior of Gears defining the objects in the future. 
     72  if (!factory) { 
     73    return; 
     74  } 
     75 
     76  // Now set up the objects, being careful not to overwrite anything. 
     77  // 
     78  // Note: In Internet Explorer for Windows Mobile, you can't add properties to 
     79  // the window object. However, global objects are automatically added as 
     80  // properties of the window object in all browsers. 
     81  if (!window.google) { 
     82    google = {}; 
     83  } 
     84 
     85  if (!google.gears) { 
     86    google.gears = {factory: factory}; 
     87  } 
     88})(); 
  • lib/OpenLayers.js

    old new  
    8383            "OpenLayers/Tween.js", 
    8484            "Rico/Corner.js", 
    8585            "Rico/Color.js", 
     86            "Gears/gears_init.js", 
    8687            "OpenLayers/Ajax.js", 
    8788            "OpenLayers/Request.js", 
    8889            "OpenLayers/Request/XMLHttpRequest.js", 
     
    184185            "OpenLayers/Strategy.js", 
    185186            "OpenLayers/Strategy/Fixed.js", 
    186187            "OpenLayers/Protocol.js", 
     188            "OpenLayers/Protocol/SQL.js", 
     189            "OpenLayers/Protocol/SQL/Gears.js", 
    187190            "OpenLayers/Layer/PointTrack.js", 
    188191            "OpenLayers/Layer/GML.js", 
    189192            "OpenLayers/Style.js",