CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-mariadb

Fast MariaDB and MySQL connector for Node.js with Promise and callback APIs

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

types.mddocs/

Type Definitions

Comprehensive type definitions for MariaDB/MySQL data types, field attributes, and type casting functionality. These types provide full type safety and precise control over data handling in the MariaDB connector.

Capabilities

Column Type Enumerations

Numeric constants representing MySQL/MariaDB column types as they appear in the protocol.

enum TypeNumbers {
  DECIMAL = 0,
  TINY = 1,
  SHORT = 2,
  LONG = 3,
  FLOAT = 4,
  DOUBLE = 5,
  NULL = 6,
  TIMESTAMP = 7,
  BIGINT = 8,
  INT24 = 9,
  DATE = 10,
  TIME = 11,
  DATETIME = 12,
  YEAR = 13,
  NEWDATE = 14,
  VARCHAR = 15,
  BIT = 16,
  TIMESTAMP2 = 17,
  DATETIME2 = 18,
  TIME2 = 19,
  JSON = 245,        // MySQL only
  NEWDECIMAL = 246,
  ENUM = 247,
  SET = 248,
  TINY_BLOB = 249,
  MEDIUM_BLOB = 250,
  LONG_BLOB = 251,
  BLOB = 252,
  VAR_STRING = 253,
  STRING = 254,
  GEOMETRY = 255
}

Column Type Strings

String constants representing MySQL/MariaDB column types for readable type identification.

enum Types {
  DECIMAL = 'DECIMAL',
  TINY = 'TINY',
  SHORT = 'SHORT',
  LONG = 'LONG',
  FLOAT = 'FLOAT',
  DOUBLE = 'DOUBLE',
  NULL = 'NULL',
  TIMESTAMP = 'TIMESTAMP',
  BIGINT = 'BIGINT',
  INT24 = 'INT24',
  DATE = 'DATE',
  TIME = 'TIME',
  DATETIME = 'DATETIME',
  YEAR = 'YEAR',
  NEWDATE = 'NEWDATE',
  VARCHAR = 'VARCHAR',
  BIT = 'BIT',
  TIMESTAMP2 = 'TIMESTAMP2',
  DATETIME2 = 'DATETIME2',  
  TIME2 = 'TIME2',
  JSON = 'JSON',
  NEWDECIMAL = 'NEWDECIMAL',
  ENUM = 'ENUM',
  SET = 'SET',
  TINY_BLOB = 'TINY_BLOB',
  MEDIUM_BLOB = 'MEDIUM_BLOB',
  LONG_BLOB = 'LONG_BLOB',
  BLOB = 'BLOB',
  VAR_STRING = 'VAR_STRING',
  STRING = 'STRING',
  GEOMETRY = 'GEOMETRY'
}

Field Attribute Flags

Bit flags representing various attributes and constraints of database columns.

enum Flags {
  /** Field cannot be null */
  NOT_NULL = 1,
  
  /** Field is a primary key */
  PRIMARY_KEY = 2,
  
  /** Field has a unique constraint */
  UNIQUE_KEY = 4,
  
  /** Field is part of a multiple-column key */
  MULTIPLE_KEY = 8,
  
  /** Field is a BLOB type */
  BLOB = 16,
  
  /** Field is unsigned (numeric types) */
  UNSIGNED = 32,
  
  /** Field has ZEROFILL attribute */
  ZEROFILL_FLAG = 64,
  
  /** Field has binary collation */
  BINARY_COLLATION = 128,
  
  /** Field is an ENUM */
  ENUM = 256,
  
  /** Field auto-increments */
  AUTO_INCREMENT = 512,
  
  /** Field is a TIMESTAMP */
  TIMESTAMP = 1024,
  
  /** Field is a SET */
  SET = 2048,
  
  /** Field has no default value */
  NO_DEFAULT_VALUE_FLAG = 4096,
  
  /** Field updates to NOW() on UPDATE */
  ON_UPDATE_NOW_FLAG = 8192,
  
  /** Field is numeric */
  NUM_FLAG = 16384
}

Type Casting System

Type casting functionality for customizing how database values are converted to JavaScript types.

/**
 * Custom type casting function for controlling data type conversion
 * @param field - Field metadata information  
 * @param next - Function to get default type conversion
 * @returns Converted value or result of next() for default conversion
 */
type TypeCastFunction = (field: FieldInfo, next: TypeCastNextFunction) => TypeCastResult;

/**
 * Function to get the default type conversion for a field
 * @returns Default converted value
 */
type TypeCastNextFunction = () => TypeCastResult;

/**
 * Possible return types from type casting functions
 */
type TypeCastResult = boolean | number | string | symbol | null | Date | Geometry | Buffer;

Type Casting Examples:

import { TypeCastFunction } from "mariadb";

// Convert TINYINT(1) to boolean, others to default
const booleanTypeCast: TypeCastFunction = (field, next) => {
  if (field.type === 'TINY' && field.columnLength === 1) {
    return field.string() === '1';
  }
  return next(); // Use default conversion
};

// Custom date formatting
const dateTypeCast: TypeCastFunction = (field, next) => {
  if (field.type === 'DATE') {
    const date = field.date();
    return date ? date.toISOString().split('T')[0] : null;
  }
  return next();
};

// Handle large numbers safely
const safeNumberTypeCast: TypeCastFunction = (field, next) => {
  if (field.type === 'BIGINT') {
    const str = field.string();
    const num = str ? BigInt(str) : null;
    // Keep as BigInt if outside safe integer range
    return num && num <= Number.MAX_SAFE_INTEGER && num >= Number.MIN_SAFE_INTEGER 
      ? Number(num) : num;
  }
  return next();
};

// Use in connection config
const connection = await mariadb.createConnection({
  host: "localhost",
  user: "root",
  password: "password",
  database: "test",
  typeCast: booleanTypeCast
});

Collation Interface

Interface for handling character set collations and encoding information.

interface Collation {
  /** Collation index number */
  index: number;
  
  /** Collation name (e.g., 'utf8mb4_unicode_ci') */
  name: string;
  
  /** Character encoding (e.g., 'utf8mb4') */
  encoding: string;
  
  /** Maximum bytes per character */
  maxLength: number;
  
  /** Get collation by encoding name */
  fromEncoding(encoding: string): Collation;
  
  /** Get collation by index number */
  fromIndex(index: number): Collation;
  
  /** Get collation by collation name */
  fromName(name: string): Collation;
}

Field Information Interface

Comprehensive metadata interface for database columns providing type information and value access methods.

interface FieldInfo {
  /** Collation information for the field */
  collation: Collation;
  
  /** Maximum length of the column */
  columnLength: number;
  
  /** Numeric type identifier */
  columnType: TypeNumbers;
  
  /** Decimal scale for numeric types */
  scale: number;
  
  /** String type identifier */
  type: Types;
  
  /** Bit flags for field attributes */
  flags: Flags;
  
  /** Get database name */
  db(): string;
  
  /** Get schema name (alias for db) */
  schema(): string;
  
  /** Get table name */
  table(): string;
  
  /** Get original table name */
  orgTable(): string;
  
  /** Get column name */
  name(): string;
  
  /** Get original column name */
  orgName(): string;
  
  /** Get field value as string */
  string(): string | null;
  
  /** Get field value as Buffer */
  buffer(): Buffer | null;
  
  /** Get field value as float */
  float(): number | null;
  
  /** Get field value as integer */
  int(): number | null;
  
  /** Get field value as long integer */
  long(): number | null;
  
  /** Get field value as decimal */
  decimal(): number | null;
  
  /** Get field value as Date object */
  date(): Date | null;
  
  /** Get field value as GeoJSON Geometry */
  geometry(): Geometry | null;
}

FieldInfo Usage Examples:

// Custom result processing with field metadata
const results = await connection.query("SELECT id, name, created_at, location FROM users");

// Access metadata through meta property
const meta = results.meta as FieldInfo[];

meta.forEach((field, index) => {
  console.log(`Column ${index}:`);
  console.log(`  Name: ${field.name()}`);
  console.log(`  Type: ${field.type}`);
  console.log(`  Table: ${field.table()}`);
  console.log(`  Nullable: ${!(field.flags & Flags.NOT_NULL)}`);
  console.log(`  Primary Key: ${!!(field.flags & Flags.PRIMARY_KEY)}`);
  console.log(`  Auto Increment: ${!!(field.flags & Flags.AUTO_INCREMENT)}`);
});

// Type-based processing
const processRow = (row: any, meta: FieldInfo[]) => {
  const processed: any = {};
  
  meta.forEach((field, index) => {
    const value = row[index];
    const name = field.name();
    
    switch (field.type) {
      case 'TINY':
        // Convert TINYINT(1) to boolean
        processed[name] = field.columnLength === 1 ? !!value : value;
        break;
      case 'DATETIME':
      case 'TIMESTAMP':
        // Ensure dates are Date objects
        processed[name] = value instanceof Date ? value : new Date(value);
        break;
      case 'JSON':
        // Parse JSON strings
        processed[name] = typeof value === 'string' ? JSON.parse(value) : value;
        break;
      default:
        processed[name] = value;
    }
  });
  
  return processed;
};

Geometry Types

Support for spatial/geometry data types using GeoJSON format.

import { Geometry } from 'geojson';

// Geometry types are represented using the standard GeoJSON format
interface Point extends Geometry {
  type: 'Point';
  coordinates: [number, number] | [number, number, number];
}

interface LineString extends Geometry {
  type: 'LineString';
  coordinates: Array<[number, number] | [number, number, number]>;
}

interface Polygon extends Geometry {
  type: 'Polygon';
  coordinates: Array<Array<[number, number] | [number, number, number]>>;
}

Geometry Usage Example:

// Insert geometry data
await connection.execute(
  "INSERT INTO locations (name, point) VALUES (?, ?)",
  ['Central Park', { type: 'Point', coordinates: [-73.965355, 40.782865] }]
);

// Query geometry data
const locations = await connection.query("SELECT name, ST_AsGeoJSON(point) as point FROM locations");

locations.forEach(row => {
  const point = JSON.parse(row.point) as Point;
  console.log(`${row.name}: ${point.coordinates[1]}, ${point.coordinates[0]}`);
});

Stream Callback Types

Type definitions for stream-related callback functions.

/**
 * Callback function for stream operations
 * @param err - Error if stream creation failed
 * @param stream - Duplex stream for database communication
 */
function StreamCallback(err?: Error, stream?: Duplex): void;

Utility Types

Additional utility types for working with MariaDB data.

/**
 * User connection configuration for changeUser operations
 */
interface UserConnectionConfig {
  /** Database name to switch to */
  database?: string;
  
  /** Connection attributes to send to server */
  connectAttributes?: any;
  
  /** Character set for the connection */
  charset?: string;
  
  /** Collation for the connection */
  collation?: string;
  
  /** Username to authenticate as */
  user?: string;
  
  /** Password for authentication */
  password?: string;
}

/**
 * Logger configuration for debugging and monitoring
 */
interface LoggerConfig {
  /** Network-level logging */
  network?: (msg: string) => void;
  
  /** Query-level logging */
  query?: (msg: string) => void;
  
  /** Error logging */
  error?: (err: Error) => void;
  
  /** Warning logging */
  warning?: (msg: string) => void;
}

/**
 * Collation information for character encoding
 */
interface Collation {
  /** Collation index number */
  index: number;
  
  /** Collation name */
  name: string;
  
  /** Character encoding */
  encoding: string;
  
  /** Maximum character length in bytes */
  maxLength: number;
  
  /** Get collation by encoding name */
  fromEncoding(encoding: string): Collation;
  
  /** Get collation by index */
  fromIndex(index: number): Collation;
  
  /** Get collation by name */
  fromName(name: string): Collation;
}

/**
 * Result structure for INSERT/UPDATE/DELETE operations
 */
interface UpsertResult {
  /** Number of rows affected by the operation */
  affectedRows: number;
  
  /** Auto-generated ID from INSERT operations */
  insertId: number | bigint;
  
  /** Warning status from the server */
  warningStatus: number;
}

/**
 * Server version information
 */
interface ServerVersion {
  /** Raw version string from server */
  raw: string;
  
  /** Whether server is MariaDB (true) or MySQL (false) */
  mariaDb: boolean;
  
  /** Major version number */
  major: number;
  
  /** Minor version number */
  minor: number;
  
  /** Patch version number */
  patch: number;
}

/**
 * Connection information and server details
 */
interface ConnectionInfo {
  /** Server connection thread ID */
  threadId: number | null;
  
  /** Connection status flags */
  status: number;
  
  /** Server version information */
  serverVersion: ServerVersion;
  
  /** Connection collation */
  collation: any;
  
  /** Server capability flags */
  serverCapabilities: number;
  
  /** Check if server is MariaDB */
  isMariaDB(): boolean;
  
  /** Check if server version meets minimum requirement */
  hasMinVersion(major: number, minor: number, patch: number): boolean;
}

Type System Best Practices

Working with Large Numbers:

// Configure safe number handling
const connection = await mariadb.createConnection({
  host: "localhost",
  user: "root", 
  password: "password",
  database: "test",
  
  // Keep BigInt as BigInt, don't convert to number
  bigIntAsNumber: false,
  
  // Keep decimals as strings for precision
  decimalAsNumber: false,
  
  // Throw error if number conversion would be unsafe
  checkNumberRange: true,
  
  // Convert insert IDs to numbers for convenience
  insertIdAsNumber: true
});

Custom Type Validation:

const validateTypeCast: TypeCastFunction = (field, next) => {
  const value = next();
  
  // Validate email format for email columns
  if (field.name() === 'email' && typeof value === 'string') {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(value)) {
      throw new Error(`Invalid email format: ${value}`);
    }
  }
  
  // Validate date ranges
  if (field.type === 'DATE' && value instanceof Date) {
    const minDate = new Date('1900-01-01');
    const maxDate = new Date('2100-01-01');
    if (value < minDate || value > maxDate) {
      throw new Error(`Date out of valid range: ${value}`);
    }
  }
  
  return value;
};

docs

callbacks.md

clustering.md

configuration.md

connections.md

errors.md

index.md

pooling.md

queries.md

types.md

tile.json