【问题标题】:What could make this dsl easier to type or read?什么可以使这个 dsl 更容易输入或阅读?
【发布时间】:2010-10-20 01:25:09
【问题描述】:

我编写了一个有效的语法来替换 scala 中的 dbunit,称为 ScalaDBTest。整个程序有效 - 只花了 2 天的时间来编写。我有很多抛光工作要做。

无论如何,我用于 DSL 将数据输入数据库的语法是可延展的,我希望得到一些反馈。

基本语法如下所示。很简单:

country:
- country_id: 1, name: "Canada"
- country_id: 2, name: "United States"

这肯定比 XML 或 SQL 插入语句好。

我辩论过使用“:”或“=”。前者看起来更好,但后者对我来说似乎是自动输入的。

还有一个概念,您可以在其中“标记”记录。从某种意义上说,上述语法是匿名记录。标签将是一项有趣的功能,因为您可以通过多种方式使用它们。

country:
    record: Canada -> country_id: 1, name: $label # produces "Canada"
    record: UnitedStates -> country_id: 2, name: $label.uncamel # produces "United States"

我不喜欢这种语法。有点啰嗦两句。使用“-”看起来不对,但如果我使用像“记录”这样的实际命令词,我需要用“->”将它们分开,否则看起来很糟糕(出于技术原因,这不是必需的)。

$label 将简单地重复标签,因此您可以最少使用标签作为重用字符串的方式。 $label.uncamel 会在看起来像驼峰格的地方添加空格。

标签背后的想法是为 API 提供一种无需记住 ID 即可访问记录的方法。如果您知道要获取的国家/地区对象是“加拿大”,那么您只需传递标签“加拿大”,它就会将其转换为唯一的 id 并将其从数据库中提取出来。

这是一个可以指定默认参数的示例:

province:
? country_id: 1, nice_weather: true
- province_id: 1, name: "British Columbia"
- province_id: 2, name: "Manitoba", nice_weather: false
- province_id: 3, name: "New York", country_id: 2

这是你看到的一些真正的力量。所有这 3 条“省”记录将有 4 列。由于有 2 个省份来自加拿大,因此它们自动继承自默认值。在第 3 种情况下,我们用 United States for New York 覆盖它。我们可以根据需要混合/匹配。

在实践中,这将节省大量的打字和认知负担,因为我们在实践中通常只关心几个值,其余的可能只是占位符,让数据库因缺少必填字段而关闭等等在。这也确实有助于测试多态对象。

这是另一个:

article:
? date_create: $now
- article_id: 1, title: "The Fed Sucks"
- article_id: 2, title: null

这个 sn-p 表明您实际上可以放置空值,而无需像在 dbUnit 中那样做任何技巧。在 DbUnit 中,您必须首先创建一个转换器,将自定义字符串(如“[NULL]”)转换为实际的 null 值。

事实上,我们可以更具表现力,并提供各种表达式和函数来帮助生成数据。例如,$now 返回格式正确的今天日期/时间的 sql 日期。我将扩展这些类型的功能,以帮助更轻松地编写测试数据。

无论如何,我正在寻求帮助以真正清理语法。我可以做出任何改变,而且由于它是新鲜的,我想从一开始就让它变得非常时髦,而不是以后再改变。

谢谢

【问题讨论】:

    标签: java database testing scala dbunit


    【解决方案1】:

    我会建议通过以下方式扩展标签的初始语法:

    1. 按列名划分/组标签。
      国家:[标签:名称]
      - country_id:1,名称:“加拿大”
      - country_id:2,名称:“美国”
    2. 按列索引对标签进行分段/分组,以尽量减少输入。
      国家:[标签:2]
      - country_id:1,名称:“加拿大”
      - country_id:2,名称:“美国”
    3. 单记录
      国家:
      -[label:2] country_id: 1, name: "加拿大"
      -[label:name] country_id: 2, name: "美国"

    如果您不想跟踪记录中的列数,可以消除基于索引的标签。

    如果您希望扩展该工具,您可以为记录组添加其他属性,例如并发性,例如使用 5 个线程创建 5K 行将是这样的:


    国家:[标签:名称] [并发:5]
    -[label:2] country_id: 1, name: "加拿大"
    -[label:name] country_id: 2, name: "美国"

    【讨论】:

    • 方括号看起来非常漂亮且一致。肯定比角度更容易打字。谢谢!
    【解决方案2】:

    我会考虑将它嵌入到 Scala 中,而不是创建外部 DSL。有用的特性是案例类、默认参数、编译器生成的复制方法。

    【讨论】:

    • 我正在使用 scala 的组合解析库。这是小菜一碟。
    【解决方案3】:

    虽然拥有易于理解和简洁的格式当然很重要,但恕我直言,在不寻找标准化替代方案的情况下编写自己的专有文件是不合理的。您是否考虑过使用轻量级和更易读的 XML 替代方案,例如 JSON 或 HAML?请注意,如果您只支持明确定义的子集,您仍然拥有工具支持和标准化的优势。

    【讨论】:

    • JSON 比我的格式更难编写和推理。数据库不需要像那样嵌套。这根本不适合这个问题。我对haml了解不多,但我认为这种格式仍然太复杂,而且它的目标比我在这里要做的更大和不同。这与演示无关——它与在数据库中创建测试数据有关。例如,您将如何进行默认列定义?会有点奇怪。
    【解决方案4】:

    这看起来很像YAML,所以我建议你看一下。以下是您所拥有的一些有效的 YAML 语法:

    country:
      - country_id: 1
        name: Canada
      - country_id: 2
        name: United States
    
    # country
    ---
    country_id: 1
    name: Canada
    ---
    country_id: 2
    name: United States
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-21
      • 2011-02-13
      相关资源
      最近更新 更多