C ++コードからのDBクエリの構築を容易にするoperator ,
ために、ヘルパーオブジェクトの小さなセットを作成しようとしています。私の考えはoperator ,
、DB呼び出しに似た命令を作成するためにを利用することです。ヘルパーオブジェクトは次のとおりです。
class Fields
{
public:
Fields &operator ,(const std::string &s)
{
SQL.append(s).append(1, ',');
return *this;
}
Fields &operator ,(const Fields &f)
{
std::string Result = f;
SQL.append(Result);
return *this;
}
virtual operator std::string() const = 0;
protected:
std::string SQL;
};
template <const char *INSTRUCTION> struct Instruction : public Fields
{
operator std::string() const
{
std::string Result(INSTRUCTION);
return Result.append(SQL);
}
};
次に、正しいtypedef
sと値を使用して、このアプローチにより次のことが可能になります。
extern const char SQL_SELECT[] = "SELECT ";
extern const char SQL_FROM[] = "FROM ";
extern const char SQL_WHERE[] = "WHERE ";
extern const char SQL_ORDER_BY[] = "ORDER BY ";
typedef Instruction<SQL_SELECT> SELECT;
typedef Instruction<SQL_FROM> FROM;
typedef Instruction<SQL_WHERE> WHERE;
typedef Instruction<SQL_ORDER_BY> ORDER_BY;
std::string Query = ((SELECT(), "a", "b", "c"),
(FROM(), "A", "B"),
(WHERE(), "a = b AND c <> b"),
(ORDER_BY(), "a", "c"));
std::cout << Query;
これはこの出力を生成します:(SELECT a,b,c,FROM A,B,WHERE a = b AND c <> b,ORDER_BY a,c,
私のバージョンでは末尾のコンマを処理しています。例を短くするためにこの部分は省略されています)、ここにコードがあります。
問題は命令ORDER BY
です。operator ,
この命令は、順序付けの動作を変更する最後のオペランドを取ることができます。列挙値をstruct Instruction
インスタンスに(通過させて)渡したいと思います。
enum ORDER
{
ASC,
DESC,
};
std::string OrderBy = (ORDER_BY(), "a", "c", DESC); // <---- Note the 'DESC' value.
ただし、インスタンスに対してこの演算子を有効にしたいだけInstruction<SQL_ORDER_BY>
なので、テンプレートを特殊化しようとしました。
template <> struct Instruction<SQL_ORDER_BY> : public Fields
{
Instruction() : order(ASC) {}
Fields &operator ,(const ORDER o)
{
order = o;
return *this;
}
operator std::string() const
{
std::string Result(SQL_ORDER_BY);
Result.append(SQL);
Result.append(order == ASC? "ASC": "DESC");
return Result;
}
private:
ORDER order;
};
このスペシャライゼーションには、次の3つのoperator ,
オーバーロードが必要です。
Fields &operator ,(const Fields &)
。Fields &operator ,(const std::string &)
。Fields &operator ,(const ORDER)
。
ただし、特殊化を作成した後、クエリ文字列は次のようになります。
std::string Query = ((SELECT(), "a", "b", "c"),
(FROM(), "A", "B"),
(WHERE(), "a = b AND c <> b"),
(ORDER_BY(), "a", "c"));
値を持つことを終了します:SELECT a,b,c,FROM A,B,WHERE a = b AND c <> b,c,
。これは、無視された場合と同様であり、値ORDER_BY
を追加するとコンパイルエラーが発生します。DESC
std::string Query = ((SELECT(), "a", "b", "c"),
(FROM(), "A", "B"),
(WHERE(), "a = b AND c <> b"),
(ORDER_BY(), "a", "c", DESC)); // <-- cannot convert 'ORDER' to 'string'
ORDER
スペシャライゼーションに値が入力されていないようですがoperator ,
、同じ名前空間にfree演算子を追加すると、コンパイルエラーが修正されます。
std::string operator ,(const std::string &left, const ORDER right)
{
std::string Result(left);
return Result.append(1, ',').append(right == ASC? "ASC": "DESC");
}
しかし、私は本当にそれFields &Instruction<SQL_ORDER_BY>::operator ,(const ORDER)
が呼ばれるだろうと思ったので、私は今いくつかのアドバイスを求めています:
Instruction<SQL_ORDER_BY>
テンプレートを特殊化した後、インスタンスがクエリ文字列に追加されないのはなぜですか?- 値がスペシャライゼーションによって提供されたもの
ORDER
を呼び出さない理由。Fields &operator ,(const ORDER)
- インスタンス
operator ,
はいくつありますか?Instruction<SQL_ORDER_BY>
PS:この努力はすべて独学の目的であり、このコードのほぼゼロ行が本番コードになってしまうので、ライブラリの使用やコードの有用性についてのコメントは避けてください。
ありがとう。
編集:
彼の答えを削除した誰かが、専門分野に行を追加するようにアドバイスしました。それを行うと、無視の問題が修正されusing Fields::operator std::string;
ました。using Fields::operator,;
ORDER_BY