STDMETHODIMP CSimplePointDatasetHelper::get_Bounds(IEnvelope **Bounds) { HRESULT hr; if (! Bounds) return E_POINTER; // Get an envelope for the extent of the dataset // We will have to calculate the extent by opening a cursor // on the dataset, and building up a minimum bounding rectangle // Prepare to open a cursor. // Make the fieldmap, with values of -1 (attributes do not need fetching) long lNumFields; IFieldsPtr ipFields; hr = get_Fields(0, &ipFields); if (FAILED(hr)) return hr; hr = ipFields->get_FieldCount(&lNumFields); if (FAILED(hr)) return hr; CComVariant vFieldMap; vFieldMap.vt = VT_ARRAY | VT_I4; vFieldMap.parray = ::SafeArrayCreateVector(VT_I4, 0, lNumFields); long HUGEP *pMap = 0; // raw pointer to array hr = SafeArrayAccessData(vFieldMap.parray, (void HUGEP **)&pMap); if (FAILED(hr)) return hr; long i; for (i=0; i < lNumFields; i++) pMap[i] = -1; SafeArrayUnaccessData(vFieldMap.parray); // Open the cursor IPlugInCursorHelperPtr ipPlugInCursor; hr = FetchAll(0, L"", vFieldMap, &ipPlugInCursor); if (FAILED(hr)) return hr; // loop through the data recording min/max X and Y values. double dxMin = 9999999; double dxMax = -9999999; double dyMin = 9999999; double dyMax = -9999999; double x,y; VARIANT_BOOL bEOF = VARIANT_FALSE; IGeometryPtr ipGeom; hr = ipGeom.CreateInstance(CLSID_Point); if (FAILED(hr)) return hr; IPointPtr ipPoint; long lNumRecords = 0; do { lNumRecords++; hr = ipPlugInCursor->QueryShape(ipGeom); if (FAILED(hr)) return hr; ipPoint = ipGeom; if (ipPoint == NULL) return E_FAIL; hr = ipPoint->QueryCoords(&x, &y); if (FAILED(hr)) return hr; if (x > dxMax) dxMax = x; if (x < dxMin) dxMin = x; if (y > dyMax) dyMax = y; if (y < dyMin) dyMin = y; hr = ipPlugInCursor->NextRecord(); if (hr != S_OK) { hr = ipPlugInCursor->IsFinished(&bEOF); if (FAILED(hr)) return hr; } } while (!bEOF); // Handle special case of single point in file // - add a small amount, so that we will end up with an envelope rather than a point if (lNumRecords == 1) { double dDelta = 0.01; if (dxMax != 0) dDelta = dxMax / 1000; dxMax += dDelta; dyMax += dDelta; } // Create the envelope object, setting the appropriate spatial reference IEnvelopePtr ipEnv; hr = ipEnv.CreateInstance(CLSID_Envelope); if (FAILED(hr)) return hr; ISpatialReferencePtr ipSR; hr = ipSR.CreateInstance(CLSID_UnknownCoordinateSystem); if (FAILED(hr)) return hr; hr = ipEnv->putref_SpatialReference(ipSR); if (FAILED(hr)) return hr; hr = ipEnv->PutCoords(dxMin, dyMin, dxMax, dyMax); if (FAILED(hr)) return hr; *Bounds = ipEnv.Detach(); // pass ownership of object to client return S_OK; }
bool ODBCConnection::Execute() { LLOG("Execute " << (void *)this << " " << (void *)session << " " << statement); if(session->hstmt == SQL_NULL_HANDLE) return false; session->FlushConnections(); last_insert_table.Clear(); number.Clear(); text.Clear(); time.Clear(); CParser p(statement); if((p.Id("insert") || p.Id("INSERT")) && (p.Id("into") || p.Id("INTO")) && p.IsId()) last_insert_table = p.ReadId(); String query; int pi = 0; const char *s = statement; while(s < statement.End()) if(*s == '\'' || *s == '\"') s = ODBCReadString(s, query); else { if(*s == '?') { if(pi >= param.GetCount()) { session->SetError("Invalid number of parameters", statement); return false; } Value v = param[pi++]; if(v.GetType() == 34) query.Cat(SqlCompile(MSSQL, ~SqlBinary(SqlRaw(v)))); else query.Cat(SqlCompile(MSSQL, ~SqlVal(v))); } else query.Cat(*s); s++; } param.Clear(); if(!IsOk(SQLPrepare(session->hstmt, (SQLCHAR *)~query, query.GetCount()))) return false; /* } else { if(!IsOk(SQLPrepare(session->hstmt, (SQLCHAR *)~statement, statement.GetCount()))) return false; parse = false; bparam = pick(param); param.Clear(); for(int i = 0; i < bparam.GetCount(); i++) { Param& p = bparam[i]; if(!IsOk(SQLBindParameter(session->hstmt, i + 1, SQL_PARAM_INPUT, p.ctype, p.sqltype, p.width, 0, (SQLPOINTER)~p.data, p.data.GetLength(), &p.li))) return false; } } */ SQLSMALLINT ncol; if(!IsOk(SQLExecute(session->hstmt)) || !IsOk(SQLNumResultCols(session->hstmt, &ncol))) { SQLFreeStmt(session->hstmt, SQL_CLOSE); return false; } info.Clear(); string_type.Clear(); for(int i = 1; i <= ncol; i++) { SQLCHAR ColumnName[256]; SQLSMALLINT NameLength; SQLSMALLINT DataType; SQLULEN ColumnSize; SQLSMALLINT DecimalDigits; SQLSMALLINT Nullable; if(!IsOk(SQLDescribeCol(session->hstmt, i, ColumnName, 255, &NameLength, &DataType, &ColumnSize, &DecimalDigits, &Nullable))) return false; string_type.Add(SQL_C_CHAR); SqlColumnInfo& f = info.Add(); f.nullable = Nullable != SQL_NO_NULLS; f.binary = false; f.precision = DecimalDigits; f.scale = 0; f.width = ColumnSize; f.name = (char *)ColumnName; switch(DataType) { case SQL_DECIMAL: case SQL_NUMERIC: case SQL_SMALLINT: case SQL_INTEGER: case SQL_REAL: case SQL_FLOAT: case SQL_DOUBLE: case SQL_BIT: case SQL_TINYINT: f.type = DOUBLE_V; break; case SQL_BIGINT: f.type = INT64_V; break; case SQL_TYPE_DATE: f.type = DATE_V; break; case SQL_TYPE_TIMESTAMP: f.type = TIME_V; break; case SQL_BINARY: case SQL_VARBINARY: case SQL_LONGVARBINARY: f.type = STRING_V; f.binary = true; string_type.Top() = SQL_C_BINARY; break; case SQL_WCHAR: case SQL_WVARCHAR: case SQL_WLONGVARCHAR: f.type = STRING_V; f.binary = true; string_type.Top() = SQL_C_WCHAR; break; default: f.type = STRING_V; break; } } SQLLEN rc; SQLRowCount(session->hstmt, &rc); rowsprocessed = rc; FetchAll(); return true; }