javascript - 如何正确创建新的Producer?

标签 javascript sql local-storage producer codefluent

我正在使用驱动对象模型工具CodeFluentEntities以便将模型部署到数据库引擎。

我正在考虑使用 localStorage 数据库引擎(例如 IndexedDB 或 Web SQL)来存储无需服务器的 Web 应用程序的数据。

我查看了 documentation但在我看来有点差...我想我理解了基本原理,比如注入(inject)点 Produce()Terminate() 但是目标呢实际制作的目录?

就我而言,这是 Javascript 源代码文件,我如何正确(以引用的方式)指定在哪里生成它们?它是否必须位于外部项目中,或者我可以只填充其他项目中的目录(例如,我的 web 应用程序的 .vsproj)?

文档是否可以集成有关这方面的代码示例,或者有人可以将我重定向到适合我需要的文章?

最佳答案

模板方法

根据您的需求,由于部署原因等原因,我建议您使用模板而不是开发自定义 Producer。使用模板生成器(随 CodeFluent Entities 一起提供),您可以利用 CodeFluent Entities 元模型快速轻松地创建复杂的脚本。

该生成器基于 CodeFluent Entities 的模板引擎,允许您在生成时生成文本文件(在您的情况下为 JavaScript)。 提醒一下,模板只是文本 block 和可以生成输出文件的控制逻辑的混合

该生成器负责所有常见操作:更新项目 (.XXproj) 以添加生成的文件、添加缺少的引用等。 此后您可以找到一个基于 CodeFluent 实体模型生成 IndexDB 脚本文件的示例(仅用于演示目的)。这是模板源文件:

[%@ reference name="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Core.dll" %]
[%@ namespace name="System" %]
[%@ namespace name="System.Linq" %]
[%@ namespace name="CodeFluent.Model" %]

var context = {};
context.indexedDB = {};
context.indexedDB.db = null;

context.indexedDB.open = function () {
    var version = 11;
    var request = indexedDB.open([%=Producer.Project.DefaultNamespace%], version);

    request.onupgradeneeded = function (e) {
        var db = e.target.result;
        e.target.transaction.onerror = context.indexedDB.onerror;
        [%foreach(Entity entity in Producer.Project.Entities){
            string properties = String.Join(", ", entity.Properties.Where(p => !p.IsPersistenceIdentity).Select(p => "\"" + p.Name + "\""));
        %]
        if (db.objectStoreNames.contains("[%=entity.Name%]")) {
            db.deleteObjectStore("[%=entity.Name%]"); 
        }

        var store = db.createObjectStore("[%=entity.Name%]",
          { keyPath: "id", autoIncrement: true });

        store.createIndex([%=properties %], { unique: false });[%}%]
    };

    request.onsuccess = function (e) {
        context.indexedDB.db = e.target.result;
    };

    request.onerror = context.indexedDB.onerror;
};
    [%foreach(Entity entity in Producer.Project.Entities){
        string parameters = String.Join(", ", entity.Properties.Where(p => !p.IsPersistenceIdentity).Select(p => p.Name));%]
context.indexedDB.[%=entity.Name%] = {}

    context.indexedDB.[%=entity.Name%].add = function ([%= parameters %]) {
    var db = context.indexedDB.db;
    var trans = db.transaction(["[%=entity.Name%]"], "readwrite");
    var store = trans.objectStore("[%=entity.Name%]");
    var request = store.put({
    [% 
        foreach (Property property in entity.Properties.Where(p => !p.IsPersistenceIdentity)) {%]
        "[%=property.Name%]": [%=property.Name%], [%}%]
        "timeStamp": new Date().getTime()
    });

    request.onsuccess = function (e) {
        console.log(e.value);
    };

    request.onerror = function (e) {
        console.log(e.value);
    };
};

context.indexedDB.[%=entity.Name%].delete = function (id) {
    var db = context.indexedDB.db;
    var trans = db.transaction(["[%=entity.Name%]"], "readwrite");
    var store = trans.objectStore("[%=entity.Name%]");

    var request = store.delete(id);

    request.onsuccess = function (e) {
        console.log(e);
    };

    request.onerror = function (e) {
        console.log(e);
    };
};

context.indexedDB.[%=entity.Name%].loadAll = function () {
    var db = context.indexedDB.db;
    var trans = db.transaction(["[%=entity.Name%]"], "readwrite");
    var store = trans.objectStore("[%=entity.Name%]");

    var keyRange = IDBKeyRange.lowerBound(0);
    var cursorRequest = store.openCursor(keyRange);

    request.onsuccess = function (e) {
        // not implemented
    };

    request.onerror = function (e) {
        console.log(e);
    };
};
[%}%]

function init() {
    context.indexedDB.open(); // initialize the IndexDB context.
}

window.addEventListener("DOMContentLoaded", init, false);

然后,您需要通过添加模板生成器来配置您的 CodeFluent 实体项目,并将上面的模板定义为源文件。

如果您考虑以下模型:

只需构建它以在目标项目(例如 Web 应用程序)中生成 IndexDB 脚本文件,您就可以像这样操作生成的 API:

context.indexedDB.Contact.add("Peter", "Boby")
context.indexedDB.Product.add("Tablet")
context.indexedDB.Product.add("Computer")
context.indexedDB.Contact.delete(1)
context.indexedDB.Product.loadAll()

自定义生产者方法

尽管如此,如果您需要针对 CodeFluent Entities 本身不支持的技术或平台,您可以通过实现 IProducer 接口(interface)来创建自己的自定义生成器:

public interface IProducer
{
    event Producer.OnProductionEventHandler Production;

    void Initialize(Project project, Producer producer);
    void Produce();
    void Terminate();
}

首先,您需要了解CodeFluent Entitie Build引擎会一一调用您配置的每个生产者来生成您的代码。

首先,CodeFluent Entities 为每个生产者调用 Initialize 方法。它将 CodeFluent Entities 项目的实例和当前生产者作为参数。 然后,它按照相同的过程调用 Product 方法。这是实现生成逻辑的正确位置。 最后,您可以在 Terminate 方法中实现终结逻辑。

CodeFluent 提供了一些实现 IProducer 接口(interface)的基类,例如位于 CodeFluent.Producers.CodeDom 程序集中的 BaseProducer,它提供“添加缺少的引用”或“更新 Visual Studio 项目 (.XXproj)”等行为。

此外,这里还有一个blog post这可以帮助您将自定义生成器集成到建模器中。

子生产者方法

另一种方法可能是开发 custom Sub-Producer但是,在我看来,它不适合您的需求。

关于javascript - 如何正确创建新的Producer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21028847/

相关文章:

sql - 如何在 Rails 3/4 中批量运行更新?

javascript - 无法在 dom 元素中看到 append 文本

javascript - 构建模块以在没有模块的环境中使用它

php - MySQL数据未插入数据库

mysql - 如何在MySQL中获得 "subtract"权限

javascript - 向 JSON 解析对象添加方法

javascript - React 应用程序本地存储未设置

用于离线网站的 HTML5 localStorage

javascript - 为整个域而不是特定页面设置 cookie(使用 JS)

javascript - 使用 Javascript 获取下一个和上一个 MongoDB