1 /******************************************************************************
2  * $Id
3  *
4  * Project:  CartoDB Translator
5  * Purpose:  Implements OGRCARTODBResultLayer class.
6  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
7  *
8  ******************************************************************************
9  * Copyright (c) 2013, Even Rouault <even dot rouault at mines-paris dot org>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  ****************************************************************************/
29 
30 #include "ogr_cartodb.h"
31 
32 CPL_CVSID("$Id");
33 
34 /************************************************************************/
35 /*                          OGRCARTODBResultLayer()                     */
36 /************************************************************************/
37 
OGRCARTODBResultLayer(OGRCARTODBDataSource * poDS,const char * pszRawQueryIn)38 OGRCARTODBResultLayer::OGRCARTODBResultLayer( OGRCARTODBDataSource* poDS,
39                                               const char * pszRawQueryIn ) :
40                                               OGRCARTODBLayer(poDS)
41 {
42     osBaseSQL = pszRawQueryIn;
43     SetDescription( "result" );
44     poFirstFeature = NULL;
45 }
46 
47 /************************************************************************/
48 /*                       ~OGRCARTODBResultLayer()                       */
49 /************************************************************************/
50 
~OGRCARTODBResultLayer()51 OGRCARTODBResultLayer::~OGRCARTODBResultLayer()
52 
53 {
54     delete poFirstFeature;
55 }
56 
57 /************************************************************************/
58 /*                          GetLayerDefnInternal()                      */
59 /************************************************************************/
60 
GetLayerDefnInternal(json_object * poObjIn)61 OGRFeatureDefn * OGRCARTODBResultLayer::GetLayerDefnInternal(json_object* poObjIn)
62 {
63     if( poFeatureDefn != NULL )
64         return poFeatureDefn;
65 
66     EstablishLayerDefn("result", poObjIn);
67 
68     return poFeatureDefn;
69 }
70 
71 /************************************************************************/
72 /*                           GetNextRawFeature()                        */
73 /************************************************************************/
74 
GetNextRawFeature()75 OGRFeature  *OGRCARTODBResultLayer::GetNextRawFeature()
76 {
77     if( poFirstFeature )
78     {
79         OGRFeature* poRet = poFirstFeature;
80         poFirstFeature = NULL;
81         return poRet;
82     }
83     else
84         return OGRCARTODBLayer::GetNextRawFeature();
85 }
86 
87 /************************************************************************/
88 /*                                IsOK()                                */
89 /************************************************************************/
90 
IsOK()91 int  OGRCARTODBResultLayer::IsOK()
92 {
93     CPLErrorReset();
94     poFirstFeature = GetNextFeature();
95     return CPLGetLastErrorType() == 0;
96 }
97 
98 /************************************************************************/
99 /*                             GetSRS_SQL()                             */
100 /************************************************************************/
101 
GetSRS_SQL(const char * pszGeomCol)102 CPLString OGRCARTODBResultLayer::GetSRS_SQL(const char* pszGeomCol)
103 {
104     CPLString osSQL;
105     CPLString osLimitedSQL;
106 
107     size_t nPos = osBaseSQL.ifind(" LIMIT ");
108     if( nPos != std::string::npos )
109     {
110         osLimitedSQL = osBaseSQL;
111         size_t nSize = osLimitedSQL.size();
112         for(size_t i = nPos + strlen(" LIMIT "); i < nSize; i++)
113         {
114             if( osLimitedSQL[i] == ' ' && osLimitedSQL[i-1] == '0')
115             {
116                 osLimitedSQL[i-1] = '1';
117                 break;
118             }
119             osLimitedSQL[i] = '0';
120         }
121     }
122     else
123         osLimitedSQL.Printf("%s LIMIT 1", osBaseSQL.c_str());
124 
125     /* Assuming that the SRID of the first non-NULL geometry applies */
126     /* to geometries of all rows. */
127     osSQL.Printf("SELECT srid, srtext FROM spatial_ref_sys WHERE srid IN "
128                 "(SELECT ST_SRID(%s) FROM (%s) ogr_subselect)",
129                 OGRCARTODBEscapeIdentifier(pszGeomCol).c_str(),
130                 osLimitedSQL.c_str());
131 
132     return osSQL;
133 }
134