1. ent ٹول کا انسٹال کرنا

ent کوڈ جنریشن ٹول کو انسٹال کرنے کے لئے آپکو مندرجہ ذیل اقدامات کا مطابقت کرنا ہوگا:

سب سے پہلے یہ یقین کریں کہ آپکے سسٹم میں گو لینگوئیج کے ماحول کا انسٹال ہوا ہے۔ پھر مندرجہ ذیل کمانڈ چلائیں تاکہ آپ ent ٹول حاصل کر سکیں:

go get -d entgo.io/ent/cmd/ent

یہ کمانڈ ent ٹول کے لیے کوڈ ڈاؤن لوڈ کرے گی، مگر یہ فوراً کمپائل اور انسٹال نہیں ہوگا۔ اگر آپ چاہتے ہیں کہ آپ ent کو $GOPATH/bin ڈائریکٹری میں انسٹال کریں تاکہ آپ اسے ہر جگہ استعمال کر سکیں، تو آپکو مندرجہ ذیل کمانڈ بھی چلانی ہوگی:

go install entgo.io/ent/cmd/ent

انسٹالیشن مکمل ہونے کے بعد، آپ ent -h چلانے کے ذریعے چیک کرسکتے ہیں کہ کیا ent ٹول مناسب طریقے سے انسٹال ہوا ہے اور دستیاب کمانڈز اور ہدایات دیکھ سکتے ہیں۔

2. سکیما کی درستیابی

2.1 ent init کا استعمال کرکے ٹیمپلیٹ کی ابتدائیت

کوڈ جنریشن کے لیے ent کا استعمال کرنا شروع کرنے کا پہلا قدم ہے۔ آپ مندرجہ ذیل کمانڈ کو چلا کر سکیما ٹیمپلیٹ کی ابتدائیت کرسکتے ہیں:

go run -mod=mod entgo.io/ent/cmd/ent new User Pet

یہ کمانڈ دو نئے سکیما فائلیں بنائے گی: user.go اور pet.go، اور انہیں ent/schema ڈائریکٹری میں رکھ دے گی۔ اگر ent ڈائریکٹری موجود نہیں ہوتی تو یہ کمانڈ خود بخود اسے بنا دیتی ہے۔

پروجیکٹ کی روٹ ڈائریکٹری میں ent init کمانڈ چلانا ایک اچھی پریکٹس ہے، یہ انداز وضاحت اور روشنی کو محفوظ رکھنے میں مدد فراہم کرتا ہے۔

2.2 سکیما فائل کی ساختار

ent/schema ڈائریکٹری میں ہر سکیما ایک گو لینگوئیج سورس فائل کے مترادف ہوتی ہے۔ سکیما فائلیں ہیں جہاں آپ ڈیٹا بیس ماڈل کو تعین کرتے ہیں، جس میں فیلڈز اور ایجز (رشتے) شامل ہیں۔

مثال کے طور پر، user.go فائل میں آپ ایک یوزر ماڈل تعین کرسکتے ہیں، جس میں فیلڈز جیسے نام اور عمر شامل ہوتی ہیں، اور یوزر اور پیٹس کے درمیان رشتے کو تعین کرسکتے ہیں۔ اسی طرح، pet.go فائل میں آپ پیٹ ماڈل اور اس کے متعلقہ فیلڈز جیسے پالتو جانور کا نام، قسم، اور پیٹس اور یوزرز کے درمیان رشتے کو تعین کریں گے۔

یہ فائلیں آخر کار ent ٹول دوار کوڈ، دیٹا بیس عملیات اور CRUD (تخلیق، پڑھائی، ترمیم، حذف) عملیات کے لیے مناسب گو کوڈ تخلیق کرنے کے لئے استعمال ہوں گی۔

// ent/schema/user.go
package schema

import (
    "entgo.io/ent"
    "entgo.io/ent/schema/field"
)

// یوزر اینٹٹی کے لیے سکیما کی تعینات کرتا ہے۔
type User struct {
    ent.Schema
}

// فیلڈس تعینات کو تعین کرنے کے لیے فیلڈ کا استعمال کیا جاتا ہے۔
func (User) Fields() []ent.Field {
    return []ent.Field{
        field.String("name").Unique(),
        field.Int("age").Positive(),
    }
}

// اینٹجس کو تعینات کرنے کے لیے اینٹجس کا استعمال کیا جاتا ہے۔
func (User) Edges() []ent.Edge {
    // ایسوسی ایشنز کی تفصیلات اگلے سیکشن میں وضاحت دی جائے گی۔
}

ent کی سکیما فائلز گو لینگوئیج کی قسموں اور فعلوں کا استعمال کرتی ہیں، تمام فیلڈز اور ماڈلز کے درمیان رشتے کو تعین کرتے ہیں، اور ent فریم ورک کی فراہم کردہ آر پی آئی کا استعمال کرتی ہیں۔ یہ ترتیب ent کو بہت ہی آسان اور جاری کرنے کے قابل بناتی ہے، جبکہ گو لینگوئیج کی مضبوط ٹائپنگ کا بھی استعمال ہوتا ہے۔

3.1 کوڈ جنریشن چلانا

ent فریم ورک میں کوڈ جنریشن چلانا ایک اہم قدم ہے۔ اس کمانڈ سے، ent تعین شدہ سکیما پر مبنی موافقت کردہ گو کوڈ فائلیں تخلیق کرے گا، جو آئندہ ترقیاتی کام کو آسان بناتا ہے۔ کوڈ جنریشن کو چلانے کے لیے کمانڈ سیدھی ہے:

go generate ./ent

مذکورہ بالا کمانڈ کو پروجیکٹ کی روٹ ڈائریکٹری میں چلایا جانا چاہئے۔ جب go generate بلایا جاتا ہے تو وہ تمام گو فائلوں کو تلاش کرتا ہے جن میں مخصوص حوالے شامل ہوں اور انحضرات میں مخصوص انتہائیات پر مشتمل کمانڈز کو انجام دیتا ہے۔ ہمارے مثال میں، یہ کمانڈ ent کوڈ جنریٹر کے لیے مخصوص ہوتا ہے۔

یہ یاد رکھیں کہ انجمن کی سکیما کی ابتدائیت اور ضروری فیلڈ کی اضافے کو پورا ہونے دیں۔ صرف اس صورت میں تخلیق کا کوڈ تمام ضروری حصوں کو شامل کرے گا۔

3.2 تولید شدہ کوڈ اشیاء کی سمجھ

تولید شدہ کوڈ اشیاء مختلف فعلوں کے ساتھ مختلف اجزاء پر مشتمل ہوتے ہیں:

  • کلائنٹ اور ٹیکس اشیاء: ڈیٹا گراف کے ساتھ تعامل کرنے کے لئے استعمال ہوتے ہیں۔ کلائنٹ تراکیب فراہم کرتا ہے تاکه ٹرانزیکشنز (ٹیکس) بنایا جا سکے یا ڈیٹابیس عملیات کو سیدھے طور پر نفاذ کر سکے۔

  • CRUD بلڈرز: ہر سکیما قسم کے لئے یہ مواد پیدا کرتے ہیں جو مواد بنانے، پڑھنے، ترمیم کرنے اور حذف کرنے کے مشینی عمل کو آسان بناتے ہیں۔

  • Entity شے (Go سٹرکٹ): یہ ڈیٹابیس میں ٹیبلز کے لئے گو سٹرکٹس پیدا کرتا ہے۔

  • ثابت اور پریڈیکیٹس پیکیج: بلڈرز کے ساتھ تعامل کرنے کے لئے ثابت اور پریڈیکیٹس شامل ہوتا ہے۔

  • مائیگریشن پیکیج: ڈیٹابیس مائیگریشن کے لئے ایک پیکیج ہوتا ہے، جو SQL ڈائیلیکٹس کے لئے مناسب ہے۔

  • ہک پیکیج: تبدیلی مڈل ویئر کو شامل کرنے کی فعالیت فراہم کرتا ہے، جس کے ذریعے بنایا گیا ہے کہ مواد بنانے، ترمیم کرنے یا محذوف کرنے سے پہلے یا بعد میں کسٹم منطق کو نفاذ کیا جا سکتا ہے۔

تولید شدہ کوڈ کی جائزت کو دیکھ کر، آپ اپنی شیماؤں کے لئے ڈیٹا ایکسس کوڈ کو خود بخود انتظام دینے والے ent فریم ورک کے طریقے سے گہری سمجھ حاصل کر سکتے ہیں۔

4. کوڈ جنریشن آپشنز

ent generate کمانڈ مختلف آپشنز کو استعمال کرتا ہے تاکہ کوڈ جنریشن کے عمل کو customize کیا جا سکے۔ آپ زیر میں دی گئی کمانڈ کے ذریعے تمام سپورٹ کرتے ہوئے جنریشن آپشنز کی درخواست کر سکتے ہیں:

ent generate -h

یہاں کچھ عام استعمال ہونے والے کمانڈ لائن آپشنز ہیں:

  • --feature strings: اضافی فعالیت جمع کرتا ہے، اضافی فنکشنلٹی شامل کرتا ہے۔
  • --header string: کوڈ جنریشن ہیڈر فائل کو اووررائیٹ کرتا ہے۔
  • --storage string: کوڈ جنریشن میں سپورٹ کردہ اسٹوریج ڈرائیور کا تعین کرتا ہے، جس کی پہلی چوناو: "sql" ہوتی ہے۔
  • --target string: کوڈ جنریشن کے لئے ٹارگٹ ڈائریکٹری کا تعین کرتا ہے۔
  • --template strings: اضافی گو ٹیمپلیٹس کو نافذ کرتا ہے۔ فائل، ڈائریکٹری اور وائلڈ کارڈ پاٹھ کی پشتی کاری کرتا ہے، مثلاً: --template file="path/to/file.tmpl"۔

یہ آپشنز توسیعیت دیتے ہیں کہ مختلف ضروریات اور ترجیحات کے لحاظ سے کوڈ جنریشن کے عمل کو customize کرنے کی اجازت دیتے ہیں۔

5. اسٹوریج آپشن ترتیب

ent ساتھ ساتھ SQL اور گریملن ڈائیلیکٹس کے لئے تولید شدہ کوڈ اشیاء کو بھی سپورٹ کرتا ہے، جس کی پہلی چوناو SQL ڈائیلیکٹ ہوتی ہے۔ اگر پروجیکٹ کو گریملن ڈیٹابیس سے منسلک کرنا ہو تو، متعلقہ ڈیٹابیس ڈائیلیکٹ کو کنفیگر کرنے کی ضرورت ہوتی ہے۔ زیر میں دی گئی کمانڈ بیان کرتی ہے کہ کس طرح سٹوریج آپشن کو مخصوص کیا جائے:

ent generate --storage gremlin ./ent/schema

اوپر دی گئی کمانڈ ent کو ہدف کے لئے گریملن ڈائیلیکٹ استعمال کرنے کی ہدایت کرتی ہے۔ یہ یقینی بناتا ہے کہ تولید شدہ اشیاء گریملن ڈیٹابیس کی ضروریات کے مطابق ہوں، ایک خاص گراف ڈیٹابیس کے ساتھ ہم آہنگی کی تصدیق کرتے ہیں۔

6. انتہائی استعمال: entc پیکیج

6.1 entc کے استعمال کی شکل کے طور پر پراجیکٹ میں پیکیج کی استعمال

entc پروجیکٹ میں کوڈ جنریشن کے لئے استعمال ہوتا ہے۔ کمانڈ لائن ٹول کے علاوہ، entc کو پروجیکٹ میں ایک پیکیج کے طور پر شامل کیا جا سکتا ہے، جس کی وجہ سے ڈوولپرز اپنے کوڈ جنریشن کے عمل کو اپنی مرضی کے مطابق انتظام دینے کی اجازت ہے۔

entc کو پروجیکٹ میں ایک پیکیج کے طور پر استعمال کرنے کے لئے، آپ کو ایک فائل بنانی ہوگی جس کا نام entc.go ہو، اور اس فائل میں مندرجہ ذیل مواد شامل کرنے لازم ہوگا:

// +build ignore

package main

import (
    "log"
    "entgo.io/ent/entc"
    "entgo.io/ent/entc/gen"
)

func main() {
    if err := entc.Generate("./schema", &gen.Config{}); err != nil {
        log.Fatal("running ent codegen:", err)
    }
}

اس طریقے کا استعمال کرتے ہوئے آپ main فنکشن کے اندر gen.Config سٹرکٹ کو ترتیب دینے کے لئے تبدیلی کر سکتے ہیں۔ آپ کو ضرورت کے مطابق entc.Generate فنکشن کو بلا باقاعدگی سے استعمال کر کے کوڈ جنریشن کے عمل کو منظم کرنے کی اختیار دیتی ہے۔

6.2 entc کی تفصیلی ترتیب

entc وسیع ترتیبی اختیارات فراہم کرتا ہے جو ڈیولپر کو تشکیل شدہ کوڈ کو customize کرنے کی اجازت دیتا ہے۔ مثال کے طور پر، اندراج کردہ ہوکس کی تشکیل کریں تاکہ تشکیل شدہ کوڈ کی تفصیل سے جانچ یا ترتیب دی جاسکے، اور تعلقی شدتاعات کو ڈپینڈنسی انجیکٹ کرنے کیلئے بیرونی معولیات استعمال کریں۔

نیچے دی ہوئی مثال وضاحت کرتی ہے کہ entc.Generate کے لئے کس طرح کسٹم ہوکس فراہم کرنے ہیں:

func main() {
    err := entc.Generate("./schema", &gen.Config{
        Hooks: []gen.Hook{
            HookFunction,
        },
    })
    if err != nil {
        log.Fatalf("running ent codegen: %v", err)
    }
}

// HookFunction ایک کسٹم ہک فنکشن ہے
func HookFunction(next gen.Generator) gen.Generator {
    return gen.GenerateFunc(func(g *gen.Graph) error {
        // یہاں g کو دجلی موڈ سے ہینڈل کیا جا سکتا ہے
        // مثال کے طور پر، فیلڈز کے وجود کی تصدیق کریں یا ڈھانچے کو ترتیب دیں
        return next.Generate(g)
    })
}

اس کے علاوہ، entc.Dependency کے ذریعے بیرونی معولیات شامل کی جا سکتی ہیں:

func main() {
    opts := []entc.Option{
        entc.Dependency(
            entc.DependencyType(&http.Client{}),
        ),
        entc.Dependency(
            entc.DependencyName("Writer"),
            entc.DependencyTypeInfo(&field.TypeInfo{
                Ident:   "io.Writer",
                PkgPath: "io",
            }),
        ),
    }
    if err := entc.Generate("./schema", &gen.Config{}, opts...); err != nil {
        log.Fatalf("running ent codegen: %v", err)
    }
}

اس مثال میں ہم http.Client اور io.Writer کو تشکیل شدہ کلاینٹ آبجیکٹس میں ڈپینڈنسی کے طور پر انجیکٹ کرتے ہیں۔

7. سکیمہ کی وضاحت کا اخراج

ent فریم ورک میں، ent describe کمانڈ کو استعمال کیا جا سکتا ہے تاکہ سکیمہ کی وضاحت کو گرافیکل شکل میں اخراج کیا جا سکے۔ یہ ڈولپر کو موجودہ اینٹیٹیز اور تعلقات کو جلدی سے سمجھنے میں مدد فراہم کرتا ہے۔

موجودہ سکیمہ کی وضاحت حاصل کرنے کیلئے نیچے دی گئی کمانڈ کو نافذ کریں:

go run -mod=mod entgo.io/ent/cmd/ent describe ./ent/schema

اوپر دی گئی کمانڈ ایک مشابہ جدول کا اخراج دیگی، جو ہر اینٹیٹی کے لئے فیلڈ، قسمیں، تعلقات وغیرہ کی معلومات کو دکھاتا ہے۔

User:
    +-------+---------+--------+-----------+ ...
    | Field |  Type   | Unique | Optional  | ...
    +-------+---------+--------+-----------+ ...
    | id    | int     | false  | false     | ...
    | name  | string  | true   | false     | ...
    +-------+---------+--------+-----------+ ...
    +-------+--------+---------+-----------+ ...
    | Edge  |  Type  | Inverse | Relation  | ...
    +-------+--------+---------+-----------+ ...
    | pets  | Pet    | false   | O2M       | ...
    +-------+--------+---------+-----------+ ...

8. کوڈ جنریشن ہکس

8.1 ہکس کا تصور

ہکس میدلویئر فنکشن ہوتے ہیں جو ent کوڈ جنریشن پروسس میں داخل کرنے کی اجازت دیتے ہیں، جو کسٹم منطق کو کوڈ تشکیل سے پہلے اور بعد میں داخل کرنے کی اجازت دیتے ہیں۔ ہکس، تشکیل شدہ کوڈ کی ابسٹریکٹ سنٹیکس ٹری (AST) کو منجمد کرنے، تصدیق کرنے، یا اضافی کوڈ سنیپیٹس شامل کرنے کے لئے استعمال کیا جا سکتا ہے۔

8.2 ہکس استعمال کرنے کا مثال

یہاں ایک مثال ہے کہ کسٹم لاجک کرنے کے لئے ایک ہکس کو استعمال کریں تاکہ یقینی سے تمام فیلڈز میں ایک مخصوص سٹرکٹ ٹیگ (مثلاً json) شامل ہوں:

func main() {
    err := entc.Generate("./schema", &gen.Config{
        Hooks: []gen.Hook{
            EnsureStructTag("json"),
        },
    })
    if err != nil {
        log.Fatalf("running ent codegen: %v", err)
    }
}

// EnsureStructTag یہ یقینی بناتا ہے کہ گراف کے تمام فیلڈز میں خاص سٹرکٹ ٹیگ شامل ہیں
func EnsureStructTag(name string) gen.Hook {
    return func(next gen.Generator) gen.Generator {
        return gen.GenerateFunc(func(g *gen.Graph) error {
            for _, node := range g.Nodes {
                for _, field := range node.Fields {
                    tag := reflect.StructTag(field.StructTag)
                    if _, ok := tag.Lookup(name); !ok {
                        return fmt.Errorf("struct tag %q is missing for field %s.%s", name, node.Name, field.Name)
                    }
                }
            }
            return next.Generate(g)
        })
    }
}

اس مثال میں، کوڈ تشکیل سے پہلے، EnsureStructTag فنکشن ہر فیلڈ کے لئے json ٹیگ کی تصدیق کرتا ہے۔ اگر کسی فیلڈ میں یہ ٹیگ نہیں ہے تو کوڈ جنریشن منسوخ ہو جائے گا اور ایک خطا واپس کریگا۔ یہ کوڈ صفائی اور تسلی کی ایک مؤثر طریقہ ہے۔