Permalink
Browse files

WFS: implements SortBy

  • Loading branch information...
rouault committed Nov 13, 2013
1 parent 8131096 commit df08e5be2b9c04ecddc0d5036ecf2cf97f50943e
Showing with 520 additions and 240 deletions.
  1. +7 −0 mapfile.c
  2. +60 −0 maplayer.c
  3. +50 −2 mapogr.cpp
  4. +19 −1 mappostgis.c
  5. +26 −1 mapserver.h
  6. +339 −227 mapwfs.c
  7. +18 −8 mapwfs20.c
  8. +1 −1 msautotest
View
@@ -3805,6 +3805,9 @@ int initLayer(layerObj *layer, mapObj *map)
layer->utfitemindex = -1;
layer->encoding = NULL;
layer->sortBy.nProperties = 0;
layer->sortBy.properties = NULL;
return(0);
}
@@ -3923,6 +3926,10 @@ int freeLayer(layerObj *layer)
freeExpression(&(layer->utfdata));
msFree(layer->utfitem);
for(i=0;i<layer->sortBy.nProperties;i++)
msFree(layer->sortBy.properties[i].item);
msFree(layer->sortBy.properties);
return MS_SUCCESS;
}
View
@@ -1412,6 +1412,66 @@ int msLayerSupportsPaging(layerObj *layer)
return MS_FALSE;
}
/*
* msLayerSupportsSorting()
*
* Returns MS_TRUE if the layer supports sorting/ordering.
*/
int msLayerSupportsSorting(layerObj *layer)
{
if (layer &&
((layer->connectiontype == MS_OGR) ||
(layer->connectiontype == MS_POSTGIS)) )
return MS_TRUE;
return MS_FALSE;
}
/*
* msLayerSetSort()
*
* Copy the sortBy clause passed as an argument into the layer sortBy member.
*/
void msLayerSetSort(layerObj *layer, const sortByClause* sortBy)
{
int i;
for(i=0;i<layer->sortBy.nProperties;i++)
msFree(layer->sortBy.properties[i].item);
msFree(layer->sortBy.properties);
layer->sortBy.nProperties = sortBy->nProperties;
layer->sortBy.properties = (sortByProperties*) msSmallMalloc(
sortBy->nProperties * sizeof(sortByProperties) );
for(i=0;i<layer->sortBy.nProperties;i++) {
layer->sortBy.properties[i].item = msStrdup(sortBy->properties[i].item);
layer->sortBy.properties[i].sortOrder = sortBy->properties[i].sortOrder;
}
}
/*
* msLayerBuildSQLOrderBy()
*
* Returns the content of a SQL ORDER BY clause from the sortBy member of
* the layer. The string does not contain the "ORDER BY" keywords itself.
*/
char* msLayerBuildSQLOrderBy(layerObj *layer)
{
char* strOrderBy = NULL;
if( layer->sortBy.nProperties > 0 ) {
int i;
for(i=0;i<layer->sortBy.nProperties;i++) {
char* escaped = msLayerEscapePropertyName(layer, layer->sortBy.properties[i].item);
if( i > 0 )
strOrderBy = msStringConcatenate(strOrderBy, ", ");
strOrderBy = msStringConcatenate(strOrderBy, escaped);
if( layer->sortBy.properties[i].sortOrder == SORT_DESC )
strOrderBy = msStringConcatenate(strOrderBy, " DESC");
msFree(escaped);
}
}
return strOrderBy;
}
int
msLayerApplyPlainFilterToLayer(FilterEncodingNode *psNode, mapObj *map,
int iLayerIndex)
View
@@ -51,6 +51,7 @@
typedef struct ms_ogr_file_info_t {
char *pszFname;
char *pszLayerDef;
int nLayerIndex;
OGRDataSourceH hDS;
OGRLayerH hLayer;
@@ -1196,14 +1197,13 @@ msOGRFileOpen(layerObj *layer, const char *connection )
return NULL;
}
CPLFree( pszLayerDef );
/* ------------------------------------------------------------------
* OK... open succeded... alloc and fill msOGRFileInfo inside layer obj
* ------------------------------------------------------------------ */
msOGRFileInfo *psInfo =(msOGRFileInfo*)CPLCalloc(1,sizeof(msOGRFileInfo));
psInfo->pszFname = CPLStrdup(OGR_DS_GetName( hDS ));
psInfo->pszLayerDef = pszLayerDef;
psInfo->nLayerIndex = nLayerIndex;
psInfo->hDS = hDS;
psInfo->hLayer = hLayer;
@@ -1247,6 +1247,7 @@ static int msOGRFileClose(layerObj *layer, msOGRFileInfo *psInfo )
psInfo->pszFname, psInfo->nLayerIndex);
CPLFree(psInfo->pszFname);
CPLFree(psInfo->pszLayerDef);
ACQUIRE_OGR_LOCK;
if (psInfo->hLastFeature)
@@ -1361,6 +1362,53 @@ static int msOGRFileWhichShapes(layerObj *layer, rectObj rect,
return(MS_FAILURE);
}
/* Apply sortBy */
if( layer->sortBy.nProperties > 0 ) {
char* strOrderBy;
char* pszLayerDef = NULL;
strOrderBy = msLayerBuildSQLOrderBy(layer);
if( psInfo->nLayerIndex == -1 )
{
pszLayerDef = msStrdup(psInfo->pszLayerDef);
if( strcasestr(psInfo->pszLayerDef, " ORDER BY ") == NULL )
pszLayerDef = msStringConcatenate(pszLayerDef, " ORDER BY ");
else
pszLayerDef = msStringConcatenate(pszLayerDef, ", ");
}
else
{
pszLayerDef = msStringConcatenate(pszLayerDef, "SELECT * FROM \"");
pszLayerDef = msStringConcatenate(pszLayerDef, OGR_FD_GetName(OGR_L_GetLayerDefn(psInfo->hLayer)));
pszLayerDef = msStringConcatenate(pszLayerDef, "\" ORDER BY ");
}
pszLayerDef = msStringConcatenate(pszLayerDef, strOrderBy);
msFree(strOrderBy);
strOrderBy = NULL;
if( layer->debug )
msDebug("msOGRFileWhichShapes: SQL = %s.\n", pszLayerDef);
/* If nLayerIndex == -1 then the layer is an SQL result ... free it */
if( psInfo->nLayerIndex == -1 )
OGR_DS_ReleaseResultSet( psInfo->hDS, psInfo->hLayer );
psInfo->nLayerIndex = -1;
ACQUIRE_OGR_LOCK;
psInfo->hLayer = OGR_DS_ExecuteSQL( psInfo->hDS, pszLayerDef, NULL, NULL );
msFree(pszLayerDef);
RELEASE_OGR_LOCK;
if( psInfo->hLayer == NULL ) {
msSetError(MS_OGRERR,
"ExecuteSQL(%s) failed.\n%s",
"msOGRFileWhichShapes()",
pszLayerDef, CPLGetLastErrorMsg() );
return MS_FAILURE;
}
}
/* ------------------------------------------------------------------
* Set Spatial filter... this may result in no features being returned
* if layer does not overlap current view.
View
@@ -1870,11 +1870,13 @@ char *msPostGISBuildSQLWhere(layerObj *layer, rectObj *rect, long *uid)
char *strFilter = 0;
char *strUid = 0;
char *strWhere = 0;
char *strOrderBy = 0;
char *strLimit = 0;
char *strOffset = 0;
size_t strRectLength = 0;
size_t strFilterLength = 0;
size_t strUidLength = 0;
size_t strOrderByLength = 0;
size_t strLimitLength = 0;
size_t strOffsetLength = 0;
size_t bufferSize = 0;
@@ -1954,8 +1956,17 @@ char *msPostGISBuildSQLWhere(layerObj *layer, rectObj *rect, long *uid)
strUidLength = strlen(strUid);
}
/* Populate strOrderBy, if necessary */
if( layer->sortBy.nProperties > 0 ) {
char* pszTmp = msLayerBuildSQLOrderBy(layer);
strOrderBy = msStringConcatenate(strOrderBy, " ORDER BY ");
strOrderBy = msStringConcatenate(strOrderBy, pszTmp);
msFree(pszTmp);
strOrderByLength = strlen(strOrderBy);
}
bufferSize = strRectLength + 5 + strFilterLength + 5 + strUidLength
+ strLimitLength + strOffsetLength;
+ strLimitLength + strOffsetLength + strOrderByLength;
strWhere = (char*)msSmallMalloc(bufferSize);
*strWhere = '\0';
if ( strRect ) {
@@ -1979,6 +1990,12 @@ char *msPostGISBuildSQLWhere(layerObj *layer, rectObj *rect, long *uid)
free(strUid);
insert_and++;
}
if ( strOrderBy ) {
strlcat(strWhere, strOrderBy, bufferSize);
free(strOrderBy);
}
if ( strLimit ) {
strlcat(strWhere, strLimit, bufferSize);
free(strLimit);
@@ -2046,6 +2063,7 @@ char *msPostGISBuildSQL(layerObj *layer, rectObj *rect, long *uid)
strSQL = msSmallMalloc(strlen(strSQLTemplate) + strlen(strFrom) + strlen(strItems) + strlen(strWhere));
sprintf(strSQL, strSQLTemplate, strItems, strFrom, strWhere);
if (strItems) free(strItems);
if (strFrom) free(strFrom);
if (strWhere) free(strWhere);
View
@@ -1487,7 +1487,24 @@ extern "C" {
int n_entries;
scaleTokenEntryObj *tokens;
} scaleTokenObj;
#ifndef SWIG
typedef enum {
SORT_ASC,
SORT_DESC
} sortOrderEnum;
typedef struct {
char* item;
sortOrderEnum sortOrder;
} sortByProperties;
typedef struct {
int nProperties;
sortByProperties* properties;
} sortByClause;
#endif
struct layerObj {
char *classitem; /* .DBF item to be used for symbol lookup */
@@ -1674,6 +1691,10 @@ extern "C" {
char *utfitem;
int utfitemindex;
expressionObj utfdata;
#ifndef SWIG
sortByClause sortBy;
#endif
};
@@ -2366,6 +2387,10 @@ void msPopulateTextSymbolForLabelAndString(textSymbolObj *ts, labelObj *l, char
MS_DLL_EXPORT char *msLayerEscapeSQLParam(layerObj *layer, const char* pszString);
MS_DLL_EXPORT char *msLayerEscapePropertyName(layerObj *layer, const char* pszString);
int msLayerSupportsSorting(layerObj *layer);
void msLayerSetSort(layerObj *layer, const sortByClause* sortBy);
char* msLayerBuildSQLOrderBy(layerObj *layer);
/* These are special because SWF is using these */
int msOGRLayerNextShape(layerObj *layer, shapeObj *shape);
int msOGRLayerGetItems(layerObj *layer);
Oops, something went wrong.

0 comments on commit df08e5b

Please sign in to comment.