// Package db provides database access for the IMC application. // It uses GORM (Go ORM) for database operations. package db // ============================================================================= // VirtualDomain - Mail domain operations // These functions interact with the ISPmail virtual_domains table. // ============================================================================= // GetAllDomains retrieves all domains with user and alias counts. // Returns a slice of DomainStats (includes counts) or an error. func (d *DB) GetAllDomains() ([]DomainStats, error) { var domains []VirtualDomain if err := d.Order("name ASC").Find(&domains).Error; err != nil { return nil, err } stats := make([]DomainStats, len(domains)) for i, dom := range domains { var userCount, aliasCount int64 d.Model(&VirtualUser{}).Where("domain_id = ?", dom.ID).Count(&userCount) d.Model(&VirtualAlias{}).Where("domain_id = ?", dom.ID).Count(&aliasCount) stats[i] = DomainStats{ ID: dom.ID, Name: dom.Name, UserCount: userCount, AliasCount: aliasCount, } } if stats == nil { stats = []DomainStats{} } return stats, nil } // GetDomainByID retrieves a single domain by its ID. // id: the domain's ID. // Returns the VirtualDomain or an error (including "record not found"). func (d *DB) GetDomainByID(id uint) (*VirtualDomain, error) { var domain VirtualDomain if err := d.Where("id = ?", id).First(&domain).Error; err != nil { return nil, err } return &domain, nil } // GetDomainByName retrieves a single domain by its name. // name: the domain name (e.g., "example.org"). // Returns the VirtualDomain or an error (including "record not found"). func (d *DB) GetDomainByName(name string) (*VirtualDomain, error) { var domain VirtualDomain if err := d.Where("name = ?", name).First(&domain).Error; err != nil { return nil, err } return &domain, nil } // CreateDomain creates a new mail domain. // name: the domain name (e.g., "example.org"). // Returns the created VirtualDomain or an error. func (d *DB) CreateDomain(name string) (*VirtualDomain, error) { domain := VirtualDomain{Name: name} if err := d.Create(&domain).Error; err != nil { return nil, err } return &domain, nil } // DeleteDomain permanently removes a domain and all associated users and aliases. // id: the domain's ID to delete. // This also deletes all virtual_users and virtual_aliases belonging to this domain. // Returns an error if the deletion fails. func (d *DB) DeleteDomain(id uint) error { tx := d.Begin() defer func() { tx.Rollback() }() if err := tx.Where("domain_id = ?", id).Delete(&VirtualUser{}).Error; err != nil { return err } if err := tx.Where("domain_id = ?", id).Delete(&VirtualAlias{}).Error; err != nil { return err } if err := tx.Delete(&VirtualDomain{}, id).Error; err != nil { return err } return tx.Commit().Error }