ব্যাসিকস

এক্টো হলো এলিক্সিরের অফিশিয়াল ডাটাবেস র‍্যাপার এবং ইন্টিগ্রেটেড কুয়েরী ল্যাংগুয়েজ। এক্টো এর সাহায্যে আমরা মাইগ্রেশান তৈরি করা, স্কিমা তৈরি করা, রেকর্ড ইনসার্ট এবং আপডেট, এবং কুয়েরী করতে পারি।

এডাপ্টারস

এক্টো এডাপ্টারস এর সাহায্যে বিভিন্ন ডাটাবেস সাপোর্ট করে থাকে। নিম্নে কিছু এডাপ্টার উদাহরণস্বরূপ দেয়া হলোঃ

এই অধ্যায়ে আমরা,পোস্টগ্রেএসকিউএল এডাপ্টার ব্যবহারের জন্যে এক্টো কনফিগার করবো।

শুরু করা যাক

এই অধ্যায়ে, আমরা এক্টো এর তিনটি অংশ আলোচনা করবোঃ

শুরুতেই, আমরা একটা সুপারভিশন ট্রিসহ এপ্লিকেশান তৈরি করবো।

$ mix new friends --sup
$ cd friends

এবার, mix.exs ফাইলে এক্টো এবং পোস্টগ্রেক্স প্যাকেজ ডিপেন্ডেসীগুলো যোগ করবোঃ

  defp deps do
    [
      {:ecto_sql, "~> 3.2"},
      {:postgrex, "~> 0.15"}
    ]
  end

ডিপেন্ডেন্সীগুলো ইন্সটল করবোঃ

$ mix deps.get

রিপোজিটরী তৈরি

এক্টো এর রিপোজটিরী বিভিন্ন ডাটাবেস এর সাথেই ম্যাপ করে থাকে, যেমন আমাদের পোস্টগ্রেস ডাটাবেস। রিপোজিটরী এর সাহায্যে সব ধরণের ডাটাবেস কমিউনিকেশান করা হবে।

রিপোজিটরী সেটআপ করতে রান করিঃ

$ mix ecto.gen.repo -r Friends.Repo

এই কমান্ডের মাধ্যমে, config/config.exs এ ডাটাবেস কানেক্ট করা ও কোন এডাপ্টার ব্যবহার করা হবে তা উল্লেখ করার কনফিগারেশান জেনারেট হবে। Friends এপ্লিকেশান এর কনফিগারেশান ফাইলটি নিম্নরূপঃ

config :friends, Friends.Repo,
  database: "friends_repo",
  username: "postgres",
  password: "",
  hostname: "localhost"

লক্ষ্যণীয়, এক্টো কিভাবে ডাটাবেস এর সাথে কানেক্ট হবে তা এই কনফিগারেশানে উল্লেখ করা থাকে, তাই আপনাকে হয়তো আপনার ডাটাবেস এর ম্যাচিং ক্রিডেনশাল ব্যবহার করতে হতে পারে।

এটা Friends.Repo মডিউলও তৈরি করে lib/friends/repo.ex এর ভিতরে।

defmodule Friends.Repo do
  use Ecto.Repo, 
    otp_app: :friends,
    adapter: Ecto.Adapters.Postgres
end

আমরা Friends.Repo মডিউল ব্যবহার করে, ডাটাবেস এ কুয়েরী করবো। আমরা এই মডিউলকে কিভাবে :friends এলিক্সির এপ্লিকেশানে ডাটাবেস কনফিগারেশান ইনফোরমেশান পেতে হবে তাও উল্লেখ করে দিয়েছি এবং এ ছাড়াও আমরা Ecto.Adapters.Postgres এডাপ্টারটি পছন্দ করেছি।

পরবর্তীতে, আমরা Friends.Repo কে আমাদের এপ্লিকেশানের সুপারভিশান ট্রি lib/friends/application.ex তে সুপারভিসর হিসেবে সেটআপ করবো। এর ফলে, যখন আমাদের এপ্লিকশান রান হবে তখন এটি এক্টো প্রসেসটিকেও চালু করবে।

  def start(_type, _args) do
    # List all child processes to be supervised
    children = [
      Friends.Repo,
    ]

  ...

এর পরে, আমাদেরকে config/config.exs ফাইলে নিচের লাইনটি যোগ করতে হবেঃ

config :friends, ecto_repos: [Friends.Repo]

এর ফলে, আমাদের এপ্লিকেশানটি এক্টো এর মিক্স কমান্ডগুলো কমান্ডলাইন থেকে রান করতে সক্ষম হবে।

এরই মাধ্যমে, আমাদের রিপজিটরী কনফিগারেশান শেষ হলো! এবার আমরা, পোস্টগ্রেসে আমাদের ডাটাবেসটি তৈরি করতে পারি নিচের কমান্ডের সাহায্যেঃ

$ mix ecto.create

এক্টো config/config.exs ফাইলের ইনফোরমেশান ব্যবহার করে জানতে পারবে কিভাবে পোস্টগ্রেস এর সাথে কানেক্ট হতে হবে, এবং ডাটাবেসকে কি নামে ডাকা হবে।

যদি আপনি কোনো এরর এর সম্মুখীন হন, তবে কনফিগারেশানের ইনফোরমেশান গুলো সঠিক কি না তা আরেকবার চেক করে দেখুন এবং আপনার পোস্টগ্রেস ইন্সট্যান্স রানিং আছে কি না তা ও দেখুন।

মাইগ্রেশান

পোস্টগ্রেস ডাটাবেসে টেবিল তৈরি ও পরিবর্তন করতে এক্টোর আছে মাইগ্রেশান। প্রতিটা মাইগ্রেশানে কিছু একশান উল্লেখ করা থাকে, যা আমাদের ডাটাবেসে সংঘটিত হবে, যেমন কোন টেবিল তৈরি বা আপডেট করা হবে।

যেহেতু, এখনো আমাদের ডাটাবেসে কোন টেবিল নাই, তাই আমাদের টেবিল তৈরি করতে কিছু মাইগ্রেশান লিখতে হবে। এক্টোর রীতি হলো টেবিল নাম বহুবচনে লেখা, তাই আমাদের এপ্লিকেশানে আমাদের একটি people টেবিল তৈরি করা লাগবে, চলুন তবে এর মাধ্যমে মাইগ্রেশান তৈরি করা শুরু করা যাক। মাইগ্রেশান তৈরির উত্তম পন্থা হলো মিক্সের ecto.gen.migration <name> টাস্ক ব্যবহার করা, আমাদের এ ক্ষেত্রে ব্যবহার করতে হবেঃ

$ mix ecto.gen.migration create_people

এর ফলে, priv/repo/migrations ফোল্ডারে টাইমস্ট্যাম্প আছে এমন নামের একটা নতুন ফাইল তৈরি হবে। ঐ ফোল্ডারে গিয়ে আমরা যদি ফাইলটি ওপেন করি, তবে নিচের মতো কিছু দেখতে পাবোঃ

defmodule Friends.Repo.Migrations.CreatePeople do
  use Ecto.Migration

  def change do

  end
end

শুরুতে, change/0 ফাংশনটি পরিবর্তন করে, আমরা name এবং age সম্বলিত একটা নতুন টেবিল people তৈরি করবোঃ

defmodule Friends.Repo.Migrations.CreatePeople do
  use Ecto.Migration

  def change do
    create table(:people) do
      add :name, :string, null: false
      add :age, :integer, default: 0
    end
  end
end

উপরে দেখতে পাবেন, আমরা কলামগুলোর ডাটা টাইপও উল্লেখ করেছি। এবং এছাড়াও আমরা null: false এবং default: 0 অপশন হিসেবে যুক্ত করেছি।

চলুন তবে, শেলে গিয়ে মাইগ্রেশান রান করা যাকঃ

$ mix ecto.migrate

স্কিমা

টেবিলতো তৈরি হলো এবার আমাদের এক্টোকে এর সম্পর্কে বিস্তারিত জানাতে হবে, স্কিমার মাধ্যমে আমরা এর কিছু অংশ করতে পারি। স্কিমা একটি মডিউল যেটা অন্তর্নিহিত ডাটাবেস টেবিলের ফিল্ডগুলোর ম্যাপিং বর্ণনা করে।

যদিও ডাটাবেস টেবিলের নামের জন্যে এক্টো বহুবচন পছন্দ করে, তবে স্কিমা সাধারণত একবচনের হয়ে থাকে, তাই আমরা আমাদের টেবিলের জন্যে যে স্কিমা তৈরি করবো তার নাম দিবো Person। চলুন, lib/friends/person.ex এখানে, নতুন স্কিমাটি তৈরি করা যাকঃ

defmodule Friends.Person do
  use Ecto.Schema

  schema "people" do
    field :name, :string
    field :age, :integer, default: 0
  end
end

আমরা দেখতে পাচ্ছি, Friends.Person মডিউল এক্টোকে বলে দিচ্ছে এই স্কিমাটি people টেবিল সম্পর্কিত এবং আমাদের দুটি কলাম আছেঃ name যেটা একটা স্ট্রিং এবং age, একটা ইন্টেজার যার ডিফল্ট ভ্যালু 0

চলুন তবে, নতুন একটা পার্সন তৈরি করে স্কিমা দেখা যাক, এর জন্যে iex -S mix ওপেন করিঃ

iex> %Friends.Person{}
%Friends.Person{age: 0, name: nil}

অনুমিত ভাবেই, একটি নতুন Person পেলাম যার age এ ডিফল্ট ভ্যালু এপ্লাই করা আছে। এবার, “সত্যিকার” মানুষ তৈরি করা যাকঃ

iex> person = %Friends.Person{name: "Tom", age: 11}
%Friends.Person{age: 11, name: "Tom"}

যেহেতু, স্কিমাগুলো হলো স্ট্রাক্ট, তাই আমরা সাধারণত যেভাবে করি ঠিক একই উপায়ে ডাটাগুলোর সাথে ইন্টারেক্ট করতে পারিঃ

iex> person.name
"Tom"
iex> Map.get(person, :name)
"Tom"
iex> %{name: name} = person
%Friends.Person{age: 11, name: "Tom"}
iex> name
"Tom"

একই ভাবে, আমরা স্কিমাগুলোকে আপডেট ও করতে পারি, ঠিক যেভাবে আমরা এলিক্সিরে অন্যান্য ম্যাপ অথবা স্ট্রাক্ট এর ক্ষেত্রে করে থাকিঃ

iex> %{person | age: 18}
%Friends.Person{age: 18, name: "Tom"}
iex> Map.put(person, :name, "Jerry")
%Friends.Person{age: 18, name: "Jerry"}

পরবর্তী অধ্যায় চেইঞ্জসেট আলোচনা করা হবে, আমরা দেখবো কিভাবে আমরা ডাটা চেইঞ্জ গুলো নিরীক্ষা করতে পারি, এবং সবশেষে কিভাবে ডাটাবেসে সেগুলো রাখতে পারি।

Caught a mistake or want to contribute to the lesson? Edit this lesson on GitHub!