1 /******************************************************************************
2  *
3  * Project:  CouchDB Translator
4  * Purpose:  Implements OGRCouchDBRowsLayer class.
5  * Author:   Even Rouault, <even dot rouault at spatialys.com>
6  *
7  ******************************************************************************
8  * Copyright (c) 2011, Even Rouault <even dot rouault at spatialys.com>
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a
11  * copy of this software and associated documentation files (the "Software"),
12  * to deal in the Software without restriction, including without limitation
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  * and/or sell copies of the Software, and to permit persons to whom the
15  * Software is furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included
18  * in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  * DEALINGS IN THE SOFTWARE.
27  ****************************************************************************/
28 
29 #include "ogr_couchdb.h"
30 
31 CPL_CVSID("$Id: ogrcouchdbrowslayer.cpp 355b41831cd2685c85d1aabe5b95665a2c6e99b7 2019-06-19 17:07:04 +0200 Even Rouault $")
32 
33 /************************************************************************/
34 /*                         OGRCouchDBRowsLayer()                        */
35 /************************************************************************/
36 
OGRCouchDBRowsLayer(OGRCouchDBDataSource * poDSIn)37 OGRCouchDBRowsLayer::OGRCouchDBRowsLayer(OGRCouchDBDataSource* poDSIn) :
38     OGRCouchDBLayer(poDSIn),
39     bAllInOne(false)
40 {
41     poFeatureDefn = new OGRFeatureDefn( "rows" );
42     poFeatureDefn->Reference();
43 
44     OGRFieldDefn oFieldId("_id", OFTString);
45     poFeatureDefn->AddFieldDefn(&oFieldId);
46 
47     OGRFieldDefn oFieldRev("_rev", OFTString);
48     poFeatureDefn->AddFieldDefn(&oFieldRev);
49 
50     SetDescription( poFeatureDefn->GetName() );
51 }
52 
53 /************************************************************************/
54 /*                        ~OGRCouchDBRowsLayer()                        */
55 /************************************************************************/
56 
~OGRCouchDBRowsLayer()57 OGRCouchDBRowsLayer::~OGRCouchDBRowsLayer() {}
58 
59 /************************************************************************/
60 /*                            ResetReading()                            */
61 /************************************************************************/
62 
ResetReading()63 void OGRCouchDBRowsLayer::ResetReading()
64 
65 {
66     OGRCouchDBLayer::ResetReading();
67 
68     if( !bAllInOne )
69     {
70         json_object_put(poFeatures);
71         poFeatures = nullptr;
72         aoFeatures.resize(0);
73     }
74 }
75 
76 /************************************************************************/
77 /*                           FetchNextRows()                            */
78 /************************************************************************/
79 
FetchNextRows()80 bool OGRCouchDBRowsLayer::FetchNextRows()
81 {
82     if( bAllInOne )
83         return false;
84 
85     json_object_put(poFeatures);
86     poFeatures = nullptr;
87     aoFeatures.resize(0);
88 
89     bool bHasEsperluet = strstr(poDS->GetURL(), "?") != nullptr;
90 
91     CPLString osURI;
92     if (strstr(poDS->GetURL(), "limit=") == nullptr &&
93         strstr(poDS->GetURL(), "skip=") == nullptr)
94     {
95         if (!bHasEsperluet)
96         {
97             bHasEsperluet = true;
98             osURI += "?";
99         }
100 
101         osURI += CPLSPrintf("&limit=%d&skip=%d",
102                             GetFeaturesToFetch(), nOffset);
103     }
104     if (strstr(poDS->GetURL(), "reduce=") == nullptr)
105     {
106         if( !bHasEsperluet )
107         {
108             // bHasEsperluet = true;
109             osURI += "?";
110         }
111 
112         osURI += "&reduce=false";
113     }
114     json_object* poAnswerObj = poDS->GET(osURI);
115     return FetchNextRowsAnalyseDocs(poAnswerObj);
116 }
117 
118 /************************************************************************/
119 /*                         BuildFeatureDefn()                           */
120 /************************************************************************/
121 
BuildFeatureDefn()122 bool OGRCouchDBRowsLayer::BuildFeatureDefn()
123 {
124     bool bRet = FetchNextRows();
125     if (!bRet)
126         return false;
127 
128     bRet = BuildFeatureDefnFromRows(poFeatures);
129     if (!bRet)
130         return false;
131 
132     if( bEOF )
133         bAllInOne = true;
134 
135     return true;
136 }
137