C ++ - 使用迁移的数据库模式

时间:2015-12-16 20:22:18

标签: c++ lambda

我正在处理需要使用数据库的应用程序。我们目前正在使用迁移文件,但是,这只是原始的sql,可能会变得非常混乱和混乱,尤其是每个人都添加它并且保持最新状态变得更加困难。

我一直在考虑在应用程序中使用迁移类型功能,我们为每个迁移创建一个类,然后定义表和列等。使用lambdas。但是,我所提出的并不能起作用。这是一个到目前为止的例子:

class Schema {
     public:

          Schema() { } // construct 

          template<typename T>
          void static create(std::string name, T t)
          {
               cout << "Create is started.."; 
               // This is where all the logic will go 
          } 

          void static integer(std::string column_name)
          { 
              std::cout << "Column integer is called";
              // put SQL here for integer value
          }
};

然后迁移文件将起作用:

class CreateUserTable {

    public:
       CreateUserTable() {

            Schema::create("users", []()
            {
                Schema::integer("id");
            }); 
       }


}; 

我的想法是,当我调用这些迁移文件时,基本上它会产生一系列格式良好的sql语句,我可以用它来进行迁移。

问题:

使用Lambdas(实际上),在完全执行create function之前,如何调用列的每个函数调用?

编辑:

为了清理,基本上,在lambda函数的主体中,只要我调用:

Schema::integer("COLUM_NAME");

它将为最终的SQL语句添加另一个层。所以,让我们说我做了以下事情:

Schema::create("users", []()
{
      Schema::integer("id");
      Schema::integer("number"); 
}); 

它将创建以下字符串:

CREATE TABLE `users` (
  id INT NOT NULL AUTO_INCREMENT, 
  number INT NOT NOW AUTO_INCREMENT

)

但是,通过创建&#34; CreateUserTable&#34;的新对象。输出的唯一内容是:cout << "Create is started..";而我需要在它之前调用std::cout << "Column integer is called"; ..它看起来不像是在做什么功能吗?

2 个答案:

答案 0 :(得分:2)

您只需要调用lambda来实际执行任务

class Schema {
     public:

          Schema() { } // construct 

          template<typename T>
          void static create(std::string name, T const & t) // pass reference to avoid copy
          {
               cout << "Create is started.."; 
               t(); // call the lambda to do the actual work
               cout << "Create is ended."; // you can run generated sql query now
          } 

          void static integer(std::string column_name)
          { 
              std::cout << "Column integer is called";
              // put SQL here for integer value
          }
};

请注意,此代码不是线程安全的。如果同时调用多个Schema::create,则会产生意外结果。您可以将模式构建器对象传递给lambda,并使用它来构建查询以解决此问题。

答案 1 :(得分:1)

这可能为时已晚,我建议你使用构建器模式来构建你的sql语句很容易; 你的代码看起来应该是这样的

class Schama{
    public:
    static void create(std::string table, void (*callback)(Builder &*builder)){

        //then use the builder class to build your class
        Builder *builder = new Builder(table);
        if(callback)callback(builder)
           if(builder)
          {
             Table *table = builder->build();
             table->create();
          }
    }
    Scheme::drop(std::string tablename){/* build your delete statement
    }
};

然后,Builder类可以具有以下

class Builder
{
   public:
       Builder * String(std::string);
       Builder  *Integer(std::string);
       Builder  *Primary(std::string);
       Builder  *Auto();
       Builder  *Foreign(std::string parent, std::string colname);
       Builder  *Unique();
       Builder   *Blob(std::string columname)
       Table     *  build();
};
code here

这就是laravel框架模式类处理它的方式,它非常简单易用。