基于macro 仿写一个简单的ecto schema dsl

ecto 的schema macro 是一个很方便的功能,可以用来定义表的schema 信息,以下是一个简单的仿写(只是行像,但是功能不一样)

项目代码

  • macro 定义
    e.ex
 
defmodule E do
   # 方便use 使用
  defmacro __using__(_options) do
    quote do
      import E
      # 通过属性存储信息
      Module.register_attribute(__MODULE__, :fields, accumulate: true)
    end
  end
  # schema macro 定义,与ecto 的类型,一个是schema 名称,一个是里边的代码定义(schema 的字段信息)
  defmacro schema(name,do: block) do
     # 调用一个内部的私有方法,返回macro,macro 方法然后使用
     schema(name,:dalong,block)
  end
  # filed macro, 进行schema 字段配置
  defmacro filed(name,type) do
    quote do
      name = unquote(name)
      type = unquote(type)
      # 存储到模块的属性中
      Module.put_attribute(__MODULE__, :fields, {name,type})
      # 为了方便测试,输出
      IO.inspect(Module.get_attribute(__MODULE__, :fields))
    end
  end
 
  defp schema(name,source,block) do
    quote  do
      source = unquote(source)
      name = unquote(name)
      # 类型ecto name 必须是一个binary  (string)
      unless is_binary(name) do
        raise "name must be a string"
      end
      IO.puts("source: #{source} name: #{name}")
      unquote(block)
   end
  end
end
  • 使用
    f.ex 与ecto 的基本类似
 
defmodule F do
  use E
  schema "dalong" do
    filed :name, :string
    filed :age, :ineteger
    filed :version, :string
  end
end
  • 测试效果
iex -S mix

说明

elixir 的元编程在不少框架中都有频繁的使用,学习好macro 很重要

参考资料

https://hexdocs.pm/ecto/Ecto.html#module-schema

posted on   荣锋亮  阅读(5)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2023-01-05 dremio PrivilegeCatalog 接口简单说明
2023-01-05 dremio SourceCatalog 服务说明
2023-01-05 dremio ManagedStoragePlugin 简单说明
2021-01-05 Data-Prepper opendistro 开源的基于es 的trace 分析工具
2021-01-05 使用babel-standalone 让浏览器支持es6特性
2021-01-05 tempo grafana 团队开源的分布式追踪框架
2021-01-05 grafana/agent grafana 团队开源的兼容prometheus 的agent

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示