inventory

package
v0.0.0-...-b9a8d5c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 26, 2026 License: GPL-2.0 Imports: 11 Imported by: 0

README

ॐᳬ᳞ भूर्भुवः स्वः

तत्स॑वि॒तुर्वरे॑ण्यं॒

भर्गो॑ दे॒वस्य॑ धीमहि।

धियो॒ यो नः॑ प्रचो॒दया॑त्॥

बी.वी.एल - बोसजी के द्वारा रचित भंडार लेखांकन हेतु तन्त्राक्ष्।

एक सुगम एवं उपयोगी भंडार संचालन हेतु तन्त्राक्ष्।

एक रचनात्मक भारतीय उत्पाद ।

Inventory CLI Logo

bvl - Boseji's Inventory Management Program

GitHub license

Easy to use and useful stock, goods and materials handling software designed in Golang and a prototype in Python.

Simple GPLv2 CLI tool to manage inventory with SQLite, CSV import/export and logging.


inventory Package for Inventory DB Implementation in Golang

Core
  • InventoryDB wrapper — safe, transactional DB access
  • In-memory or file-based SQLite support
  • Configurable sequence start (IndexStart)
Data Model
  • Item struct — ID, Description, Location, Status, Remarks (with FormatRemarks())
  • FormatRemarks() — consistent timestamped remarks
  • JSON tags — for web/app/API compatibility
Database Operations
  • AddItem()
  • EditItem()
  • DeleteItem()
  • AppendItem()
  • AppendRemarksEntry()
  • GetItemByID()
  • ListAll()
  • ListItemsPaged() — with pagination
  • NewItemIterator() — with streaming Next()
  • ResetSequence()
CSV Support
  • ExportCSV()
  • ImportCSV()
  • ViewCSV()
  • InventoryDB wrappers
  • CLI-friendly and Excel-friendly CSV format
JSON Support
  • ExportJSON()
  • ImportJSON()
  • ViewJSON()
  • ExportJSONToString()
  • ImportJSONFromString()
  • InventoryDB wrappers
  • Web/Electron/API/jq friendly JSON format
Item JSON Helpers
  • Item.ToJSON()
  • Item.FromJSON()
Test Suite
  • db_test.go — core DB functions
  • inventorydb_test.go — InventoryDB methods
  • csv_test.go — CSV
  • json_test.go — JSON
  • Full error path coverage
  • Rollback scenarios covered
Ready for:
  • CLI tools
  • Web frontends
  • Electron apps
  • REST APIs
  • jq pipelines
  • Automation scripts
  • CI/CD integration

License

This project is released under the GNU General Public License v2. See the LICENSE file for details.

Sources: https://github.com/boseji/bvl

bvl - Boseji's Inventory Management Program

Copyright (C) 2025 by Abhijit Bose (aka. Boseji)

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 only as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.

SPDX-License-Identifier: GPL-2.0-only

Full Name: GNU General Public License v2.0 only

Please visit https://spdx.org/licenses/GPL-2.0-only.html for details.


Documentation

Overview

Package inventory provides a complete inventory management layer for use with SQLite databases. It has with full CRUD support, with CSV/JSON import/export, and ready-to-use CLI and web features.

बी.वी.एल - बोसजी के द्वारा रचित भंडार लेखांकन हेतु तन्त्राक्ष्।

=============================================

एक सुगम एवं उपयोगी भंडार संचालन हेतु तन्त्राक्ष्।

एक रचनात्मक भारतीय उत्पाद ।

bvl - Boseji's Inventory Management Program

Package inventory

Core Features:

- InventoryDB wrapper: safe, transactional DB access - In-memory / file SQLite support - Configurable sequence start (IndexStart)

Data Model:

  • Item struct: ID, Description, Location, Status, Remarks (with FormatRemarks)
  • FormatRemarks(): consistent timestamped remarks
  • JSON tags for web/app/API compatibility

Database Operations:

- AddItem() - EditItem() - DeleteItem() - AppendItem() - AppendRemarksEntry() - GetItemByID() - ListAll() - ListItemsPaged() with pagination - NewItemIterator() with streaming Next() - ResetSequence()

CSV Support:

- ExportCSV() - ImportCSV() - ViewCSV() - InventoryDB wrappers - CLI-friendly and Excel-friendly format

JSON Support:

- ExportJSON() - ImportJSON() - ViewJSON() - ExportJSONToString() - ImportJSONFromString() - InventoryDB wrappers - CLI-friendly, Web API-ready format - jq / Web / Electron compatibility

Item JSON helpers:

- Item.ToJSON() - Item.FromJSON()

Test Suite:

- db_test.go: core DB functions - inventorydb_test.go: InventoryDB methods - csv_test.go: CSV - json_test.go: JSON - All error paths covered - Rollback scenarios covered

Ready for:

- CLI tools - Web frontends - Electron apps - REST APIs - jq pipelines - Automation scripts - CI/CD integration

License:

This package is GPL-2.0-only.

bvl - Boseji's Inventory Management Program. Copyright (C) 2025 by Abhijit Bose (aka. Boseji).

SPDX-License-Identifier: GPL-2.0-only Full Name: GNU General Public License v2.0 only Please visit <https://spdx.org/licenses/GPL-2.0-only.html> for details.

Sources: https://github.com/boseji/bvl

Index

Constants

View Source
const (
	// Starting value of the Index
	IndexStart = 1000
)

IndexStart defines the starting value for auto-incremented IDs.

Variables

This section is empty.

Functions

func AddItem

func AddItem(exec Execer, item Item) error

AddItem inserts a new item into the inventory table.

The ID is assigned automatically (auto-increment). The remarks field is always stored in timestamped format by calling item.FormatRemarks().

Usage:

item := Item{
    Description: "New inverter",
    Location:    "Warehouse 1",
    Status:      "Operational",
    Remarks:     "installed and tested",
}
err := AddItem(tx, item)

Resulting remarks field:

[2025-06-20 16:45] installed and tested

Notes: - If used inside a transaction, pass tx as exec - If using plain db connection, pass db as exec - Remarks will always follow consistent format - Works with both *sql.DB and *sql.Tx.

func AppendItem

func AppendItem(exec Execer, item Item) error

AppendItem inserts or replaces an item in the inventory table, using the provided ID. If an item with the same ID already exists, it will be replaced with the new values.

The remarks field is processed through item.FormatRemarks() to ensure consistent timestamped formatting.

Typical usage:

item := Item{
    ID:          1234,
    Description: "UPS 3KVA",
    Location:    "Rack 5",
    Status:      "Operational",
    Remarks:     "installed new unit",
}
err := AppendItem(tx, item)

Resulting record:

id          = 1234
description = "UPS 3KVA"
location    = "Rack 5"
status      = "Operational"
remarks     = "[2025-06-20 12:30] installed new unit"

Use cases:

- To update an existing record fully (replace) - To insert a new record with known ID - To bulk insert/update items

Notes:

- Safe to call repeatedly with the same item - Will replace existing record (INSERT OR REPLACE) - Does not check for ID conflicts beyond replacement - Remarks field will always be formatted via FormatRemarks() - If ID is not set, use AddItem() instead - Works with both *sql.DB and *sql.Tx.

func AppendRemarksEntry

func AppendRemarksEntry(exec Execer, id int, message string) error

AppendRemarksEntry appends a new log entry to the item's remarks field, using the standard timestamp format.

The entry is formatted as:

[YYYY-MM-DD HH:MM] message

This function uses SQL to append without loading the entire remarks field:

SET remarks = COALESCE(remarks, '') || char(10) || ?

Usage:

err := AppendRemarksEntry(tx, 1002, "replaced battery")

Resulting remarks field:

(previous remarks)
[2025-06-20 16:55] replaced battery

Notes: - Does not modify other fields (description, location, status) - If item ID does not exist, no rows are updated - Use when you only want to add an audit/log entry - Works with both *sql.DB and *sql.Tx.

func DeleteItem

func DeleteItem(exec Execer, id int) error

DeleteItem removes a record from the inventory table by ID.

If the specified ID does not exist, the operation is a no-op (no error is returned).

Typical usage:

err := inv.DeleteItem(1234)

Result:

- If item with id = 1234 exists → record is deleted - If no such item → nothing is done, no error

Use cases:

- To permanently remove an inventory record - To clean up old or duplicate items - To reset part of the inventory manually

Notes:

- This is a destructive operation (cannot be undone) - Should typically be logged via remarks before use - Use AppendRemarksEntry() if you want an audit trail before delete - Works with both *sql.DB and *sql.Tx.

func EditItem

func EditItem(exec Execer, item Item) error

EditItem updates the item's fields (description, location, status) and appends the new remarks text to the existing remarks field.

Remarks field acts as an append-only log:

  • Previous remarks are preserved
  • New entry is appended with timestamp format: [YYYY-MM-DD HH:MM] message

This function does not load existing remarks in Go; it performs the append using SQL:

SET remarks = COALESCE(remarks, '') || char(10) || ?

Usage:

item := Item{
    ID: 1002,
    Description: "Updated inverter",
    Location:    "Warehouse 3",
    Status:      "Operational",
    Remarks:     "maintenance check completed",
}
err := EditItem(tx, item)

Resulting remarks field:

(previous remarks)
[2025-06-20 16:22] maintenance check completed

Notes: - If item ID does not exist, no rows are updated - If used inside transaction (tx), pass tx as exec - To append a single new log entry, use AppendRemarksEntry() - To display remarks nicely, use item.FormatRemarks() - Works with both *sql.DB and *sql.Tx.

func ExportCSV

func ExportCSV(db *sql.DB, filename string) error

ExportCSV writes all inventory records to a CSV file.

Usage:

err := ExportCSV(db, "inventory.csv")

The CSV will have the following columns:

id, description, location, status, remarks

Existing file will be overwritten.

Returns error if file cannot be written or query fails.

func ExportJSON

func ExportJSON(db *sql.DB, filename string) error

ExportJSON writes all inventory records to a JSON file.

The output JSON is an array of Item objects:

[
  { "id": 1001, "description": "UPS", "location": "Rack 1", ... },
  { ... },
  ...
]

Usage:

err := ExportJSON(db, "inventory.json")

Example:

// Export inventory to file
err := inventory.ExportJSON(db, "export.json")

Errors:

  • returns error if database query fails
  • returns error if JSON marshal fails
  • returns error if file cannot be written (permission, path)

func ExportJSONToString

func ExportJSONToString(db *sql.DB) (string, error)

ExportJSONToString returns all inventory records as a JSON string.

Usage:

jsonStr, err := ExportJSONToString(db)

Example:

jsonStr, err := inventory.ExportJSONToString(db)

Useful for:

  • Web API response
  • Electron UI
  • jq processing
  • CLI --json flag

func ImportCSV

func ImportCSV(exec Execer, filename string) error

ImportCSV reads inventory records from a CSV file and imports them.

Existing records with matching IDs will be replaced.

Usage:

err := ImportCSV(db, "inventory.csv")

CSV format must have columns:

id, description, location, status, remarks

Each row is imported using AppendItem().

Returns error on file error, parse error, or DB error.

func ImportJSON

func ImportJSON(exec Execer, filename string) error

ImportJSON reads inventory records from a JSON file and imports them.

Existing records with matching IDs will be replaced.

Usage:

err := ImportJSON(exec, "inventory.json")

Example:

// Import from JSON
err := inventory.ImportJSON(inv, "import.json")

Errors:

  • returns error if file read fails
  • returns error if JSON unmarshal fails
  • returns error if individual Insert/Replace fails

func ImportJSONFromBytes

func ImportJSONFromBytes(exec Execer, data []byte) error

ImportJSONFromBytes helper

func ImportJSONFromString

func ImportJSONFromString(exec Execer, jsonString string) error

ImportJSONFromString reads inventory records from a JSON string.

Existing records with matching IDs will be replaced.

Usage:

err := ImportJSONFromString(exec, jsonString)

Example:

err := inventory.ImportJSONFromString(inv, jsonPayload)

Errors:

  • returns error if JSON is invalid
  • returns error if DB insert fails

func OpenDB

func OpenDB(dbFile string) *sql.DB

OpenDB opens or creates the SQLite database file at dbFile path.

It ensures that the 'inventory' table exists with the required fields: - id INTEGER PRIMARY KEY AUTOINCREMENT - description TEXT - location TEXT - status TEXT - remarks TEXT

It also ensures that the autoincrement sequence is initialized: - If the sequence is missing, sets it to IndexStart.

Usage:

db := OpenDB("inventory.db")

Notes: - Returns a *sql.DB connection (ready to use) - Fails fatally if the database cannot be opened or schema is invalid - Table creation is idempotent (safe to call multiple times) - Auto-increment starts from IndexStart (default 1000)

func ResetSequence

func ResetSequence(exec Execer) error

ResetSequence wraps ResetSequence with automatic transaction.

Resets the auto-increment sequence for the inventory table back to IndexStart (default: 1000).

Typically used after manually clearing records, or for test setups.

Usage:

err := inv.ResetSequence()

Result:

- Sets the internal sqlite_sequence counter for 'inventory' table - Next inserted record will use ID = IndexStart + 1

Use cases:

- After deleting all items (clear inventory) - For test environments to reset IDs - To reinitialize an empty database

Notes:

- Does not delete records (use DeleteItem or manual purge first) - Safe to call multiple times - Has no effect if records still exist with higher IDs - Works with both *sql.DB and *sql.Tx.

func ViewCSV

func ViewCSV(filename string) error

ViewCSV prints the content of a CSV file to stdout.

Usage:

err := ViewCSV("inventory.csv")

The output is formatted as columns:

id  description  location  status  remarks

Errors are returned if the file cannot be read.

func ViewJSON

func ViewJSON(filename string) error

ViewJSON pretty prints the content of a JSON file to stdout.

Usage:

err := ViewJSON("inventory.json")

Example:

err := inventory.ViewJSON("export.json")

Useful for:

  • CLI debugging
  • Inspection
  • jq pipelines

Errors:

  • returns error if file read fails
  • returns error if JSON is invalid

Types

type Execer

type Execer interface {
	Exec(query string, args ...interface{}) (sql.Result, error)
}

Execer defines something that can Exec SQL. Both *sql.DB and *sql.Tx implement this.

type InventoryDB

type InventoryDB struct {
	// contains filtered or unexported fields
}

InventoryDB wraps *sql.DB and provides safe transaction helpers.

Users do not need to work with *sql.DB directly.

func NewInventoryDB

func NewInventoryDB(dbFile string) *InventoryDB

NewInventoryDB opens or creates the database and returns InventoryDB.

Ensures the table exists, sequence is initialized. Returns a ready-to-use InventoryDB wrapper.

Usage:

inv := NewInventoryDB("inventory.db")

Notes: - Underlying connection is stored in inv.db - Close() must be called when finished - Table creation is idempotent

func (*InventoryDB) AddItem

func (inv *InventoryDB) AddItem(item Item) error

AddItem wraps AddItem with automatic transaction.

Usage:

err := inv.AddItem(item)

func (*InventoryDB) AppendItem

func (inv *InventoryDB) AppendItem(item Item) error

AppendItem wraps AppendItem with automatic transaction.

Usage:

err := inv.AppendItem(item)

func (*InventoryDB) AppendRemarksEntry

func (inv *InventoryDB) AppendRemarksEntry(id int, message string) error

AppendRemarksEntry wraps AppendRemarksEntry with automatic transaction.

Usage:

err := inv.AppendRemarksEntry(id, "log message")

func (*InventoryDB) Close

func (inv *InventoryDB) Close() error

Close closes the underlying database connection.

func (*InventoryDB) DB

func (inv *InventoryDB) DB() *sql.DB

DB returns the underlying *sql.DB (for read-only queries). Use only when needed, e.g. for GetItemByID.

func (*InventoryDB) DeleteItem

func (inv *InventoryDB) DeleteItem(id int) error

DeleteItem wraps DeleteItem with automatic transaction.

Usage:

err := inv.DeleteItem(id)

func (*InventoryDB) EditItem

func (inv *InventoryDB) EditItem(item Item) error

EditItem wraps EditItem with automatic transaction.

Usage:

err := inv.EditItem(item)

func (*InventoryDB) ExportCSV

func (inv *InventoryDB) ExportCSV(filename string) error

ExportCSV writes all inventory records to CSV using InventoryDB.

Usage:

err := inv.ExportCSV("inventory.csv")

Same as ExportCSV() raw.

func (*InventoryDB) ExportJSON

func (inv *InventoryDB) ExportJSON(filename string) error

InventoryDB method: ExportJSON

Usage:

err := inv.ExportJSON("inventory.json")

func (*InventoryDB) ExportJSONToString

func (inv *InventoryDB) ExportJSONToString() (string, error)

InventoryDB method: ExportJSONToString

Usage:

jsonStr, err := inv.ExportJSONToString()

func (*InventoryDB) GetItemByID

func (inv *InventoryDB) GetItemByID(id int) (Item, error)

GetItemByID wraps GetItemByID.

Usage:

item, err := inv.GetItemByID(id)

func (*InventoryDB) ImportCSV

func (inv *InventoryDB) ImportCSV(filename string) error

ImportCSV imports inventory records from CSV using InventoryDB.

Usage:

err := inv.ImportCSV("inventory.csv")

The import runs inside a transaction.

func (*InventoryDB) ImportJSON

func (inv *InventoryDB) ImportJSON(filename string) error

InventoryDB method: ImportJSON

Usage:

err := inv.ImportJSON("inventory.json")

Runs inside transaction.

func (*InventoryDB) ImportJSONFromString

func (inv *InventoryDB) ImportJSONFromString(jsonString string) error

InventoryDB method: ImportJSONFromString

Usage:

err := inv.ImportJSONFromString(jsonString)

Runs inside transaction.

func (*InventoryDB) ListAll

func (inv *InventoryDB) ListAll() ([]Item, error)

ListAll wraps ListAll.

Usage:

items, err := inv.ListAll()

func (*InventoryDB) ListItemsPaged

func (inv *InventoryDB) ListItemsPaged(afterID int, limit int) ([]Item, error)

ListItemsPaged wraps ListItemsPaged.

Usage:

items, err := inv.ListItemsPaged(afterID, limit)

func (*InventoryDB) NewItemIterator

func (inv *InventoryDB) NewItemIterator(
	whereClause string, args ...interface{},
) (*ItemIterator, error)

NewItemIterator returns an ItemIterator for scanning records with an optional WHERE clause.

Usage:

iter, err := inv.NewItemIterator("WHERE status = ?", "Operational")
if err != nil {
    // handle error
}
defer iter.Close()

for {
    item, ok, err := iter.Next()
    if err != nil {
        // handle error
    }
    if !ok {
        break // end of results
    }
    fmt.Println(item.ID, item.Description)
}

func (*InventoryDB) ResetSequence

func (inv *InventoryDB) ResetSequence() error

ResetSequence wraps ResetSequence with automatic transaction.

Usage:

err := inv.ResetSequence()

func (*InventoryDB) WithTransaction

func (inv *InventoryDB) WithTransaction(
	fn func(tx Execer) error) error

WithTransaction executes the given function inside a transaction.

Usage:

err := inv.WithTransaction(func(tx Execer) error {
    err := AddItem(tx, item)
    if err != nil {
        return err
    }
    return AppendRemarksEntry(tx, item.ID, "added new")
})

If fn() returns error: - Transaction is rolled back

If fn() returns nil: - Transaction is committed

Notes: - Use for any group of changes that must be atomic - If the DB fails, returns error

type Item

type Item struct {
	ID          int    `json:"id"`
	Description string `json:"description"`
	Location    string `json:"location"`
	Status      string `json:"status"`
	Remarks     string `json:"remarks"`
}

Item represents an inventory record.

Fields:

ID          - auto-increment primary key
Description - free text
Location    - free text
Status      - free text
Remarks     - audit log, may contain timestamped entries

The Remarks field is typically maintained using FormatRemarks() to ensure consistent timestamp format.

Example:

[2025-06-21 14:30] installed new battery

The Item struct is used across all DB, CSV, and JSON functions.

func GetItemByID

func GetItemByID(db *sql.DB, id int) (Item, error)

GetItemByID returns a single item from the inventory table that matches the given ID.

If no item is found with the given ID, returns an error:

"item <id> not found"

Typical usage:

item, err := inv.GetItemByID(1234)
if err != nil {
    // handle error (not found, or query error)
} else {
    fmt.Println(item.Description, item.Status)
}

Result:

- If item exists → returns populated Item struct - If not found → returns zero-value Item + error

Use cases:

- To display or edit a specific inventory item - To retrieve details for audit or reporting - To check existence of an item by ID

Notes:

  • This is a read-only query (no transaction needed)
  • The remarks field is returned as raw string (use item.FormatRemarks() for formatted display)

func ListAll

func ListAll(db *sql.DB) ([]Item, error)

ListAll returns all items in the inventory table, sorted by ID.

This is a read-only operation. It does not require a transaction. It can be used for reporting, exporting, or displaying all items.

Usage:

items, err := inv.ListAll()
if err != nil {
    // handle error
}
for _, item := range items {
    fmt.Println(item.ID, item.Description, item.Status)
}

Result:

- Returns []Item containing all inventory records - Sorted by id ASC (oldest first)

Use cases:

- To display the full inventory - To export data to CSV, JSON - For reports or dashboards

Notes:

  • If the table is empty, returns an empty slice (no error)
  • The remarks field will be returned in raw form (use item.FormatRemarks() for display)
  • This method does not paginate large inventories (use ListItemsPaged for that)
  • Use cautiously for very large databases. For pagination, use ListItemsPaged() or ItemIterator().

func ListItemsPaged

func ListItemsPaged(
	db *sql.DB, afterID int, limit int) ([]Item, error)

ListItemsPaged returns a slice of items after a given starting ID, up to a specified limit.

This is a read-only operation. It does not require a transaction.

Usage:

items, err := inv.ListItemsPaged(lastID, 10)
if err != nil {
    // handle error
}
for _, item := range items {
    fmt.Printf("%d: %s\n", item.ID, item.Description)
}

Result:

- Returns up to 'limit' number of items with id > afterID - Results are sorted by id ASC

Use cases:

- For paging through large inventories - For implementing UI pagination - For batch export or processing

Notes:

- If no items match the query, returns an empty slice - Use afterID = 0 to start from beginning - If fewer than 'limit' items remain, returns as many as available

func (*Item) FormatRemarks

func (item *Item) FormatRemarks() string

FormatRemarks returns the Remarks field formatted as:

[YYYY-MM-DD HH:MM] <remarks>

If Remarks is already formatted (starts with timestamp), it returns Remarks unchanged.

If Remarks is blank, returns only timestamp prefix.

Usage:

formatted := item.FormatRemarks()

This function is used by AddItem(), AppendItem(), EditItem() to ensure Remarks field is consistent.

Example output:

"[2025-06-21 15:00] installed UPS"

func (*Item) FromJSON

func (item *Item) FromJSON(jsonStr string) error

FromJSON parses a JSON string into this Item.

Usage:

var item Item
err := item.FromJSON(jsonStr)

Example:

var item Item
err := item.FromJSON(`{"id":1001,"description":"UPS"}`)

Errors:

  • returns error if JSON is invalid

func (*Item) ToJSON

func (item *Item) ToJSON() (string, error)

ToJSON returns this Item as a JSON string.

Usage:

jsonStr, err := item.ToJSON()

Example output:

{
  "id": 1001,
  "description": "UPS",
  "location": "Rack 1",
  "status": "Operational",
  "remarks": "[2025-06-21 15:00] installed UPS"
}

Useful for:

  • Logging
  • CLI --json
  • Websocket events
  • API single-item

type ItemIterator

type ItemIterator struct {
	// contains filtered or unexported fields
}

ItemIterator provides a streaming interface to iterate over inventory records, one item at a time.

Internally uses sql.Rows and rows.Next(). Allows for processing large result sets with low memory usage.

Usage:

iter, err := NewItemIterator(db, "WHERE status = ?", "Operational")
if err != nil {
    // handle error
}
defer iter.Close()

for {
    item, ok, err := iter.Next()
    if err != nil {
        // handle error
    }
    if !ok {
        break // end of results
    }
    fmt.Println(item.ID, item.Description)
}

Use cases:

- To process large inventories without loading all into memory - To stream records to external systems - To filter results with WHERE clause

Notes:

- You must call Close() when done to release database resources - The iterator must be used in a single goroutine - If WHERE clause is empty (""), all records are returned - Always check for error on Next() even if ok == false

func NewItemIterator

func NewItemIterator(
	db *sql.DB, whereClause string, args ...interface{},
) (*ItemIterator, error)

NewItemIterator returns an ItemIterator for scanning records in the inventory table with an optional WHERE clause.

The iterator streams results one at a time and uses minimal memory.

Usage:

iter, err := NewItemIterator(inv.DB(), "WHERE status = ?", "Operational")
if err != nil {
    // handle error
}
defer iter.Close()

for {
    item, ok, err := iter.Next()
    if err != nil {
        // handle error
    }
    if !ok {
        break // end of results
    }
    fmt.Println(item.ID, item.Description)
}

Use cases:

- To process large inventories without loading entire table - To filter items with a dynamic WHERE clause - To support streaming export to CSV, JSON, etc.

Notes:

- WHERE clause must begin with "WHERE ..." or be empty string "" - Use parameter substitution for arguments (? placeholders) - Must call Close() when done to release database resources

func (*ItemIterator) Close

func (it *ItemIterator) Close() error

Close releases the database resources held by this iterator.

You must call Close() when you are finished iterating, otherwise database connections may be leaked.

Usage:

iter, err := NewItemIterator(inv.DB(), "WHERE status = ?", "Operational")
if err != nil {
    // handle error
}
defer iter.Close() // always defer Close!

for {
    item, ok, err := iter.Next()
    if err != nil {
        // handle error
    }
    if !ok {
        break
    }
    fmt.Println(item.ID, item.Description)
}

Use cases:

- Always used after calling NewItemIterator() - Should be deferred immediately after iterator creation

Notes:

- Safe to call even if no rows were read - Safe to call multiple times (subsequent calls will do nothing) - Does not affect the underlying database connection

func (*ItemIterator) Next

func (it *ItemIterator) Next() (Item, bool, error)

Next returns the next item from the iterator.

Usage:

for {
    item, ok, err := iter.Next()
    if err != nil {
        // handle error (scan error)
    }
    if !ok {
        break // no more rows
    }
    fmt.Println(item.ID, item.Description)
}

Return values:

- item: the next Item in the result set (if ok == true) - ok: true if a row was returned, false if at end of result set - err: non-nil if scan failed

Use cases:

- To process items one at a time from a filtered query - For streaming export (CSV, JSON) - For large inventories without loading all items into memory

Notes:

- Must check err even if ok == false - Must call Close() on the iterator after use - Each call advances the cursor (forward-only) - This is not thread-safe: use only in single goroutine

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL