Tag: cws_src680_sqlite User: aklitzing Date: 2006/08/29 15:22:25 Modified: dba/connectivity/source/drivers/sqlite3/sqPrepare.cpp dba/connectivity/source/drivers/sqlite3/sqPrepare.h
Log: * Changed it to have a clean interface for derived classes * added some documentation * added some features * optimized File Changes: Directory: /dba/connectivity/source/drivers/sqlite3/ ==================================================== File [changed]: sqPrepare.cpp Url: http://dba.openoffice.org/source/browse/dba/connectivity/source/drivers/sqlite3/sqPrepare.cpp?r1=1.1.2.1&r2=1.1.2.2 Delta lines: +44 -29 --------------------- --- sqPrepare.cpp 28 Aug 2006 23:16:26 -0000 1.1.2.1 +++ sqPrepare.cpp 29 Aug 2006 22:22:22 -0000 1.1.2.2 @@ -2,9 +2,9 @@ * * $RCSfile: sqPrepare.cpp,v $ * - * $Revision: 1.1.2.1 $ + * $Revision: 1.1.2.2 $ * - * last change: $Author: aklitzing $ $Date: 2006/08/28 23:16:26 $ + * last change: $Author: aklitzing $ $Date: 2006/08/29 22:22:22 $ * * Original author: André Klitzing * @@ -38,18 +38,20 @@ // ---------------------------------------------------------------------- // CTor, DTor, Operators +// ---------------------------------------------------------------------- -sqPrepare::sqPrepare(const char* _string, bool _copyString) +sqPrepare::sqPrepare(const char* _string, bool _copyString, const char _wildcard) : m_paramBind(0) , m_paramPos(0) , m_paramCount(0) , m_copyString(_copyString) + , m_wildcard(_wildcard) { m_string = m_copyString ? copyString(_string) : _string; - parser(m_string, m_paramCount); + if(_wildcard != '\0') // only derived classes should use that! + parser(); } - sqPrepare::sqPrepare(const sqPrepare& _cpy) { copy(_cpy); @@ -71,8 +73,12 @@ } + + // ---------------------------------------------------------------------- // public +// ---------------------------------------------------------------------- + const char* sqPrepare::getOriginStr() const { return m_string; @@ -95,7 +101,7 @@ } -bool sqPrepare::isCopiedString() +bool sqPrepare::isCopiedString() const { return m_copyString; } @@ -105,7 +111,6 @@ { int length = getFullLength(); // give us the length of the new string char* newStr = new char[length+1]; // + NULL-Termination - newStr[length] = '\0'; int oldStrPos=0; // current position in the old m_string int newStrPos=0; // current position in the new newStr @@ -120,6 +125,7 @@ while(newStrPos < length) // if you don't have a ? at the end, you need to copy the rest of the old string newStr[newStrPos++] = m_string[oldStrPos++]; + newStr[length] = '\0'; return newStr; } @@ -148,7 +154,7 @@ else { int len = strlen(_value); - newValue = new char[len+3]; // 1 byte for NULL-Termination and 2 bytes for " at both sides + newValue = new char[len+3]; // 1 byte for NULL-Termination and 2 bytes for _quote at both sides strncpy(newValue+1, _value, len); // copy only the string and reserve space for the quotes newValue[0] = _quote; // set the first quote @@ -179,6 +185,8 @@ // ---------------------------------------------------------------------- // protected +// ---------------------------------------------------------------------- + void sqPrepare::writeBindStr(char* _newStr, int& _newStrPos, int& _oldStrPos, const char* _fromBind) const { ++_oldStrPos; // we only need to jump ONE (the ?) char... but derived classes needs maybe a higher jump @@ -203,44 +211,51 @@ { int fullLength = strlen(m_string) - m_paramCount; // size without '?'-parameters for(int i=0; i < m_paramCount; ++i) - fullLength += (m_paramBind[i] == 0) ? 4 : strlen(m_paramBind[i]); // 4 chars for 'NULL' + fullLength += (m_paramBind[i] == 0) ? 4 : strlen(m_paramBind[i]); // 4 chars for 'NULL' from writeBindStr() + + return fullLength; // size without NULL-Termination +} - return fullLength; +void sqPrepare::setParamCount(unsigned short _count) // if you call this function more than once, you will have a memory leak +{ + m_paramCount = _count; + m_paramBind = new char*[m_paramCount]; + m_paramPos = new unsigned short[m_paramCount]; +} + +void sqPrepare::setParamPos(unsigned short _paramNumber, unsigned short _posInString) +{ + m_paramBind[_paramNumber] = 0; // initialize it + m_paramPos[_paramNumber] = _posInString; } + // ---------------------------------------------------------------------- // private +// ---------------------------------------------------------------------- -void sqPrepare::parser(const char* _string, unsigned short& _count, unsigned short _pos) +void sqPrepare::parser(unsigned short _paramNumber, unsigned short _posInString) { - unsigned short PosInCount = _count; // this is the position in our array for current ? - - for(bool isParam=true; _string[_pos] != '\0'; ++_pos) + for(bool isParam=true; m_string[_posInString] != '\0'; ++_posInString) { - if(_string[_pos] == '\'' || _string[_pos] == '"') // don't take ? if it is in quotes + if(m_string[_posInString] == '\'' || m_string[_posInString] == '"') // don't take ? if it is in quotes isParam = !isParam; - if(isParam && _string[_pos] == '?') // yeah... we found a param + if(isParam && m_string[_posInString] == m_wildcard) // yeah... we found a param { - parser(_string, ++_count, _pos+1); // RECURSION... I love it ;-) + parser(_paramNumber+1, _posInString+1); // RECURSION... I love it ;-) break; } } - if(_count > 0) // if we don't have any ? in this string, we don't need to create space for bindings - { - if(m_paramBind == 0) // m_paramPos is 0, too! - it's needed for recursion - { - m_paramBind = new char*[_count]; - m_paramPos = new unsigned short[_count]; - } - else // the last char ('\0') shouldn't be added + if(_paramNumber > 0 || _paramNumber == 0 && m_string[_posInString] != '\0') { - m_paramBind[PosInCount] = 0; - m_paramPos[PosInCount] = _pos; - } + if(m_string[_posInString] == '\0') // the last char ('\0') shouldn't be added + setParamCount(_paramNumber); + else + setParamPos(_paramNumber, _posInString); } } File [changed]: sqPrepare.h Url: http://dba.openoffice.org/source/browse/dba/connectivity/source/drivers/sqlite3/sqPrepare.h?r1=1.1.2.1&r2=1.1.2.2 Delta lines: +73 -11 --------------------- --- sqPrepare.h 28 Aug 2006 23:16:27 -0000 1.1.2.1 +++ sqPrepare.h 29 Aug 2006 22:22:22 -0000 1.1.2.2 @@ -2,9 +2,9 @@ * * $RCSfile: sqPrepare.h,v $ * - * $Revision: 1.1.2.1 $ + * $Revision: 1.1.2.2 $ * - * last change: $Author: aklitzing $ $Date: 2006/08/28 23:16:27 $ + * last change: $Author: aklitzing $ $Date: 2006/08/29 22:22:22 $ * * Original author: André Klitzing * @@ -42,10 +42,15 @@ You can set the second constructor-parameter to 'false', if the object should use the given pointer directly. Be aware that the copy-constructor and assignment-operator will observe this decision. - DO NOT delete[] the string from getOriginStr() - that is the copy for this class to build the string for getStr()! - You MUST delete[] the string from getStr() yourself - this class will create a NEW string with given parameters! - + Do NOT delete[] the string from getOriginXXX() - that is the copy for this object to build the string with getStr()! + You MUST delete[] the string from getStr() yourself - this object will create a NEW string with given parameters! Every unset parameter will be NULL as string if you get the new string from getStr(). + + + If you want to derive from this class, read this documentation carefully or you will have segfaults and memory leaks! + I know that isn't really pretty but checks to avoid it would decrease performance. + + You can write your own parser and overwrite writeBindStr() to have another behaviour in your parameters. */ class sqPrepare { @@ -53,18 +58,74 @@ char** m_paramBind; //!< the strings that will be set with setXXX() unsigned short* m_paramPos; //!< the positions of the ?-parameters, will be used in getStr() unsigned short m_paramCount; //!< will have the number of ?-parameters - bool m_copyString; //!< the flag if the object should copy given strings or not + bool m_copyString; //!< the flag if the object should copy given m_string or not const char* m_string; //!< the copied string from constructor + char m_wildcard; //!< the wildcard that will mark the prepared position in m_string (default: ?) + //! \brief it will deletes every used memory... will be called from assignment-operator and destructor + //! \return nothing void clearAll(); + + //! \brief it will copy the given object to this object - will be called from assignment-operator and copy-constructor + //! \return nothing void copy(const sqPrepare& _cpy); - void parser(const char* _string, unsigned short& _count, unsigned short _pos=0); + + //! \brief it will parse the m_string for m_wildcards and save every found position in m_paramPos + /*! + If you derive from this class and want to implement your own parser, you MUST set _wildcard in + the constructor to '\0' or you will have memory leaks (checks would decrease performance). + You must call setParamCount() and SetParamPos() in your derived class or you will get an empty string. + + This is a recursive function - you don't need to worry about the two parameters. + */ + //! \param _paramNumber the 'position' in m_paramPos + //! \param _posInString the 'position' in m_string of the m_wildcard + void parser(unsigned short _paramNumber=0, unsigned short _posInString=0); + + protected: - int getFullLength() const; + //! \brief it will copy the given string and returns a pointer to it (only a service function) + //! \param _string the string you want to copy + //! \return the copy of your given string. You have the ownership! char* copyString(const char* _string); + + //! \brief it will set m_paramCount and create space for the bindings + /*! + Do NOT call this function more than once or you will have memory leaks. + Checks aren't implemented because of performance reasons in parser(). + */ + //! \param _count the number of found parameters + //! \return nothing + inline void setParamCount(unsigned short _count); + + //! \brief it will initialize the m_paramBind and set the position in m_string to m_paramPos + /*! + Do NOT call this function more than once per _paramNumber or you will have memory leaks. + Checks aren't implemented because of performance reasons in parser(). + + You MUST set every _paramNumber of your m_paramPos or you will have segfaults later. + */ + inline void setParamPos(unsigned short _paramNumber, unsigned short _posInString); + + //! \brief it will return the full length of the NEW string without NULL-Termination + /*! + Maybe you want to change something in your derived class that will cause a wrong length. + You should overwrite it then because getStr() will use it. ;-) + */ + //! \return length of the new string without '\0' + virtual int getFullLength() const; + + //! \brief getStr() will call it to write the binded string + //! \param _newStr the new string that you need to complete + //! \param _newStrPos the current position in _newStr - you should only start writing at that position + //! \param _oldStrPos the current position in the old m_string - you only need to increment it with the size you want to jump on old string + //! \param _fromBind the binded string of the current parameter + //! \return nothing virtual void writeBindStr(char* _newStr, int& _newStrPos, int& _oldStrPos, const char* _fromBind) const; + + public: //! \brief constructor - will initialize the object, copy the given string and call parse() with it /*! @@ -76,7 +137,8 @@ */ //! \param _string a prepared string with parameters //! \param _copyString true if the object should copy the given string, or false if you want to use the pointer - sqPrepare(const char* _string, bool _copyString=true); + //! \param _wildcard the wildcard that will used for marked parameters. Default is ? + sqPrepare(const char* _string, bool _copyString=true, const char _wildcard='?'); //! \brief copy-constructor /*! @@ -113,7 +175,7 @@ //! \brief it checks if the given string was copied or if the object uses the pointer //! \return true if the string was copied, otherwise false - bool isCopiedString(); + bool isCopiedString() const; //! \brief it will create a NEW string with the given bindings /*! --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
