OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
 
master @ 133 LINES
 
[ HISTORY ]  [ UP ]
 

package loader

import (
	"database/sql"
	"fmt"
	"strings"
)

// EquipmentData represents a piece of equipment
type EquipmentData struct {
	ID               int64
	SlotType         string
	ItemID           sql.NullInt64
	UpgradeID        sql.NullInt64
	Quality          string
	ItemName         string
	SnapshotTs       int64
	ItemIcon         sql.NullString
	ItemType         sql.NullString
	ItemStats        sql.NullString
	ItemEffect       sql.NullString
	SpellDescription sql.NullString
}

// EnchantmentData represents an enchantment or gem on equipment
type EnchantmentData struct {
	EquipmentID    int64
	EnchantmentID  sql.NullInt64
	SlotID         sql.NullInt64
	SlotType       sql.NullString
	DisplayString  sql.NullString
	SourceItemID   sql.NullInt64
	SourceItemName sql.NullString
	SpellID        sql.NullInt64
	GemIconSlug    sql.NullString
}

// LoadAllEquipment loads equipment and enchantments for a set of players
// Returns: map[playerID][]EquipmentData, map[equipmentID][]EnchantmentData, error
func LoadAllEquipment(db *sql.DB, playerIDs []int64) (map[int64][]EquipmentData, m
ap[int64][]EnchantmentData, error) {
	if len(playerIDs) == 0 {
		return make(map[int64][]EquipmentData), make(map[int64][]EnchantmentData), nil
	}

	// Build IN clause
	placeholders := make([]string, len(playerIDs))
	args := make([]any, len(playerIDs))
	for i, id := range playerIDs {
		placeholders[i] = "?"
		args[i] = id
	}

	equipmentMap := make(map[int64][]EquipmentData)
	var allEquipmentIDs []int64

	// Simple query - one row per (player_id, slot_type)
	eqQuery := fmt.Sprintf(`
		SELECT e.player_id, e.id, e.slot_type, e.item_id, e.upgrade_id, e.quality, e.ite
m_name, e.snapshot_timestamp,
		       i.icon AS item_icon_slug, i.type AS item_type, i.stats AS item_stats, i.i
tem_effect, i.spell_description
		FROM player_equipment e
		LEFT JOIN items i ON e.item_id = i.id
		WHERE e.player_id IN (%s)
		ORDER BY e.player_id, e.slot_type
	`, strings.Join(placeholders, ","))

	eqRows, err := db.Query(eqQuery, args...)
	if err != nil {
		return nil, nil, fmt.Errorf("batch equipment query: %w", err)
	}
	defer eqRows.Close()

	for eqRows.Next() {
		var playerID int64
		var eq EquipmentData
		if err := eqRows.Scan(
			&playerID, &eq.ID, &eq.SlotType, &eq.ItemID, &eq.UpgradeID, &eq.Quality, &eq.It
emName, &eq.SnapshotTs,
			&eq.ItemIcon, &eq.ItemType, &eq.ItemStats, &eq.ItemEffect, &eq.SpellDescription
); err != nil {
			return nil, nil, fmt.Errorf("scan equipment: %w", err)
		}

		equipmentMap[playerID] = append(equipmentMap[playerID], eq)
		allEquipmentIDs = append(allEquipmentIDs, eq.ID)
	}

	// Load enchantments in batches
	enchantmentsMap := make(map[int64][]EnchantmentData)
	if len(allEquipmentIDs) > 0 {
		const enchBatchSize = 10000
		for i := 0; i < len(allEquipmentIDs); i += enchBatchSize {
			end := i + enchBatchSize
			if end > len(allEquipmentIDs) {
				end = len(allEquipmentIDs)
			}

			batch := allEquipmentIDs[i:end]
			placeholders := make([]string, len(batch))
			args := make([]any, len(batch))
			for j, id := range batch {
				placeholders[j] = "?"
				args[j] = id
			}

			enchQuery := fmt.Sprintf(`
                SELECT pee.equipment_id, pee.enchantment_id, pee.slot_id, pee.slot
_type, pee.display_string,
                       pee.source_item_id, pee.source_item_name, pee.spell_id, i.i
con as gem_icon_slug
                FROM player_equipment_enchantments pee
                LEFT JOIN items i ON pee.source_item_id = i.id
                WHERE pee.equipment_id IN (%s)
                ORDER BY pee.equipment_id, pee.slot_id
            `, strings.Join(placeholders, ","))

			enchRows, err := db.Query(enchQuery, args...)
			if err != nil {
				return nil, nil, fmt.Errorf("enchantments batch %d: %w", i/enchBatchSize+1, er
r)
			}

			for enchRows.Next() {
				var ench EnchantmentData
				if err := enchRows.Scan(
					&ench.EquipmentID, &ench.EnchantmentID, &ench.SlotID, &ench.SlotType, &ench.D
isplayString,
					&ench.SourceItemID, &ench.SourceItemName, &ench.SpellID, &ench.GemIconSlug); 
err != nil {
					enchRows.Close()
					return nil, nil, fmt.Errorf("scan enchantment: %w", err)
				}
				enchantmentsMap[ench.EquipmentID] = append(enchantmentsMap[ench.EquipmentID], 
ench)
			}
			enchRows.Close()
		}
	}

	return equipmentMap, enchantmentsMap, nil
}

package loader

import (
	"database/sql"
	"fmt"
	"strings"
)

// EquipmentData represents a piece of equip
ment
type EquipmentData struct {
	ID               int64
	SlotType         string
	ItemID           sql.NullInt64
	UpgradeID        sql.NullInt64
	Quality          string
	ItemName         string
	SnapshotTs       int64
	ItemIcon         sql.NullString
	ItemType         sql.NullString
	ItemStats        sql.NullString
	ItemEffect       sql.NullString
	SpellDescription sql.NullString
}

// EnchantmentData represents an enchantment
 or gem on equipment
type EnchantmentData struct {
	EquipmentID    int64
	EnchantmentID  sql.NullInt64
	SlotID         sql.NullInt64
	SlotType       sql.NullString
	DisplayString  sql.NullString
	SourceItemID   sql.NullInt64
	SourceItemName sql.NullString
	SpellID        sql.NullInt64
	GemIconSlug    sql.NullString
}

// LoadAllEquipment loads equipment and ench
antments for a set of players
// Returns: map[playerID][]EquipmentData, ma
p[equipmentID][]EnchantmentData, error
func LoadAllEquipment(db *sql.DB, playerIDs 
[]int64) (map[int64][]EquipmentData, map[int
64][]EnchantmentData, error) {
	if len(playerIDs) == 0 {
		return make(map[int64][]EquipmentData), ma
ke(map[int64][]EnchantmentData), nil
	}

	// Build IN clause
	placeholders := make([]string, len(playerID
s))
	args := make([]any, len(playerIDs))
	for i, id := range playerIDs {
		placeholders[i] = "?"
		args[i] = id
	}

	equipmentMap := make(map[int64][]EquipmentD
ata)
	var allEquipmentIDs []int64

	// Simple query - one row per (player_id, s
lot_type)
	eqQuery := fmt.Sprintf(`
		SELECT e.player_id, e.id, e.slot_type, e.i
tem_id, e.upgrade_id, e.quality, e.item_name
, e.snapshot_timestamp,
		       i.icon AS item_icon_slug, i.type AS
 item_type, i.stats AS item_stats, i.item_ef
fect, i.spell_description
		FROM player_equipment e
		LEFT JOIN items i ON e.item_id = i.id
		WHERE e.player_id IN (%s)
		ORDER BY e.player_id, e.slot_type
	`, strings.Join(placeholders, ","))

	eqRows, err := db.Query(eqQuery, args...)
	if err != nil {
		return nil, nil, fmt.Errorf("batch equipme
nt query: %w", err)
	}
	defer eqRows.Close()

	for eqRows.Next() {
		var playerID int64
		var eq EquipmentData
		if err := eqRows.Scan(
			&playerID, &eq.ID, &eq.SlotType, &eq.Item
ID, &eq.UpgradeID, &eq.Quality, &eq.ItemName
, &eq.SnapshotTs,
			&eq.ItemIcon, &eq.ItemType, &eq.ItemStats
, &eq.ItemEffect, &eq.SpellDescription); err
 != nil {
			return nil, nil, fmt.Errorf("scan equipme
nt: %w", err)
		}

		equipmentMap[playerID] = append(equipmentM
ap[playerID], eq)
		allEquipmentIDs = append(allEquipmentIDs, 
eq.ID)
	}

	// Load enchantments in batches
	enchantmentsMap := make(map[int64][]Enchant
mentData)
	if len(allEquipmentIDs) > 0 {
		const enchBatchSize = 10000
		for i := 0; i < len(allEquipmentIDs); i +=
 enchBatchSize {
			end := i + enchBatchSize
			if end > len(allEquipmentIDs) {
				end = len(allEquipmentIDs)
			}

			batch := allEquipmentIDs[i:end]
			placeholders := make([]string, len(batch)
)
			args := make([]any, len(batch))
			for j, id := range batch {
				placeholders[j] = "?"
				args[j] = id
			}

			enchQuery := fmt.Sprintf(`
                SELECT pee.equipment_id, pee
.enchantment_id, pee.slot_id, pee.slot_type,
 pee.display_string,
                       pee.source_item_id, p
ee.source_item_name, pee.spell_id, i.icon as
 gem_icon_slug
                FROM player_equipment_enchan
tments pee
                LEFT JOIN items i ON pee.sou
rce_item_id = i.id
                WHERE pee.equipment_id IN (%
s)
                ORDER BY pee.equipment_id, p
ee.slot_id
            `, strings.Join(placeholders, ",
"))

			enchRows, err := db.Query(enchQuery, args
...)
			if err != nil {
				return nil, nil, fmt.Errorf("enchantment
s batch %d: %w", i/enchBatchSize+1, err)
			}

			for enchRows.Next() {
				var ench EnchantmentData
				if err := enchRows.Scan(
					&ench.EquipmentID, &ench.EnchantmentID,
 &ench.SlotID, &ench.SlotType, &ench.Display
String,
					&ench.SourceItemID, &ench.SourceItemNam
e, &ench.SpellID, &ench.GemIconSlug); err !=
 nil {
					enchRows.Close()
					return nil, nil, fmt.Errorf("scan encha
ntment: %w", err)
				}
				enchantmentsMap[ench.EquipmentID] = appe
nd(enchantmentsMap[ench.EquipmentID], ench)
			}
			enchRows.Close()
		}
	}

	return equipmentMap, enchantmentsMap, nil
}
 
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET