From 1111da5a622d36e0de28cff8ee8f1dbadba1532b Mon Sep 17 00:00:00 2001 From: usernametooshort Date: Fri, 6 Mar 2026 16:47:00 +0100 Subject: [PATCH] feat: add is_extended_promotional column to all component tables Adds the is_extended_promotional field to: - BaseComponent interface (component-base.ts) - All 37 derived component tables - A new DB optimization (component-extended-promotional-column.ts) that adds the column to the base components table via a SQLite generated column using json_extract(extra, '$.promotional') The value is sourced from the 'promotional' key in the component's extra JSON field, consistent with how is_basic / is_preferred are derived. Fixes #92 /bounty $75 --- lib/db/derivedtables/accelerometer.ts | 2 + lib/db/derivedtables/adc.ts | 2 + lib/db/derivedtables/analog_multiplexer.ts | 2 + lib/db/derivedtables/battery_holder.ts | 2 + lib/db/derivedtables/bjt_transistor.ts | 2 + lib/db/derivedtables/boost_converter.ts | 2 + lib/db/derivedtables/buck_boost_converter.ts | 2 + lib/db/derivedtables/capacitor.ts | 2 + lib/db/derivedtables/component-base.ts | 1 + lib/db/derivedtables/dac.ts | 2 + lib/db/derivedtables/diode.ts | 2 + lib/db/derivedtables/fpc_connector.ts | 2 + lib/db/derivedtables/fpga.ts | 2 + lib/db/derivedtables/fuse.ts | 2 + lib/db/derivedtables/gas_sensor.ts | 2 + lib/db/derivedtables/gyroscope.ts | 2 + lib/db/derivedtables/header.ts | 2 + lib/db/derivedtables/io_expander.ts | 2 + lib/db/derivedtables/jst_connector.ts | 2 + lib/db/derivedtables/lcd_display.ts | 2 + lib/db/derivedtables/led.ts | 2 + .../derivedtables/led_dot_matrix_display.ts | 2 + lib/db/derivedtables/led_driver.ts | 2 + lib/db/derivedtables/led_segment_display.ts | 2 + lib/db/derivedtables/led_with_ic.ts | 2 + lib/db/derivedtables/microcontroller.ts | 2 + lib/db/derivedtables/mosfet.ts | 2 + lib/db/derivedtables/oled_display.ts | 2 + lib/db/derivedtables/pcie_m2_connector.ts | 2 + lib/db/derivedtables/potentiometer.ts | 2 + lib/db/derivedtables/relay.ts | 2 + lib/db/derivedtables/resistor.ts | 2 + lib/db/derivedtables/resistor_array.ts | 1 + lib/db/derivedtables/switch.ts | 2 + lib/db/derivedtables/usb_c_connector.ts | 2 + lib/db/derivedtables/voltage_regulator.ts | 2 + lib/db/derivedtables/wifi_module.ts | 2 + .../derivedtables/wire_to_board_connector.ts | 2 + .../component-extended-promotional-column.ts | 39 +++++++++++++++++++ scripts/setup-db-optimizations.ts | 2 + 40 files changed, 115 insertions(+) create mode 100644 lib/db/optimizations/component-extended-promotional-column.ts diff --git a/lib/db/derivedtables/accelerometer.ts b/lib/db/derivedtables/accelerometer.ts index bd67aeb..ae44f1b 100644 --- a/lib/db/derivedtables/accelerometer.ts +++ b/lib/db/derivedtables/accelerometer.ts @@ -28,6 +28,7 @@ export const accelerometerTableSpec: DerivedTableSpec = { { name: "has_uart", type: "boolean" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -102,6 +103,7 @@ export const accelerometerTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", supply_voltage_min: voltageMin, supply_voltage_max: voltageMax, diff --git a/lib/db/derivedtables/adc.ts b/lib/db/derivedtables/adc.ts index 008b533..3efb08a 100644 --- a/lib/db/derivedtables/adc.ts +++ b/lib/db/derivedtables/adc.ts @@ -40,6 +40,7 @@ export const adcTableSpec: DerivedTableSpec = { { name: "operating_temp_max", type: "real" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -115,6 +116,7 @@ export const adcTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", resolution_bits: resolution, sampling_rate_hz: samplingRate, diff --git a/lib/db/derivedtables/analog_multiplexer.ts b/lib/db/derivedtables/analog_multiplexer.ts index 1e4bb7d..1eeb6f7 100644 --- a/lib/db/derivedtables/analog_multiplexer.ts +++ b/lib/db/derivedtables/analog_multiplexer.ts @@ -40,6 +40,7 @@ export const analogMultiplexerTableSpec: DerivedTableSpec = { { name: "channel_type", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -144,6 +145,7 @@ export const analogMultiplexerTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", num_channels: numChannels, num_bits: numBits, diff --git a/lib/db/derivedtables/battery_holder.ts b/lib/db/derivedtables/battery_holder.ts index c970eee..180c604 100644 --- a/lib/db/derivedtables/battery_holder.ts +++ b/lib/db/derivedtables/battery_holder.ts @@ -32,6 +32,7 @@ export const batteryHolderTableSpec: DerivedTableSpec = { { name: "operating_temp_max", type: "real" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -74,6 +75,7 @@ export const batteryHolderTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), connector_type: attrs["Connector Type"] || null, battery_type: attrs["Battery Type"] || null, diff --git a/lib/db/derivedtables/bjt_transistor.ts b/lib/db/derivedtables/bjt_transistor.ts index ae3a255..b7677df 100644 --- a/lib/db/derivedtables/bjt_transistor.ts +++ b/lib/db/derivedtables/bjt_transistor.ts @@ -26,6 +26,7 @@ export const bjtTransistorTableSpec: DerivedTableSpec = { { name: "temperature_range", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -74,6 +75,7 @@ export const bjtTransistorTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", current_gain: current_gain, collector_current: collector_current, diff --git a/lib/db/derivedtables/boost_converter.ts b/lib/db/derivedtables/boost_converter.ts index da3fad8..25f4198 100644 --- a/lib/db/derivedtables/boost_converter.ts +++ b/lib/db/derivedtables/boost_converter.ts @@ -31,6 +31,7 @@ export const boostConverterTableSpec: DerivedTableSpec = { { name: "number_of_outputs", type: "integer" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -117,6 +118,7 @@ export const boostConverterTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", input_voltage_min: inputMin, input_voltage_max: inputMax, diff --git a/lib/db/derivedtables/buck_boost_converter.ts b/lib/db/derivedtables/buck_boost_converter.ts index 784ec02..9309a2b 100644 --- a/lib/db/derivedtables/buck_boost_converter.ts +++ b/lib/db/derivedtables/buck_boost_converter.ts @@ -32,6 +32,7 @@ export const buckBoostConverterTableSpec: DerivedTableSpec = { name: "number_of_outputs", type: "integer" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -121,6 +122,7 @@ export const buckBoostConverterTableSpec: DerivedTableSpec = in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", input_voltage_min: inputMin, input_voltage_max: inputMax, diff --git a/lib/db/derivedtables/capacitor.ts b/lib/db/derivedtables/capacitor.ts index 971f055..f6b1f7f 100644 --- a/lib/db/derivedtables/capacitor.ts +++ b/lib/db/derivedtables/capacitor.ts @@ -34,6 +34,7 @@ export const capacitorTableSpec: DerivedTableSpec = { { name: "capacitor_type", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -115,6 +116,7 @@ export const capacitorTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), capacitance_farads: capacitance, tolerance_fraction: tolerance, voltage_rating: voltage, diff --git a/lib/db/derivedtables/component-base.ts b/lib/db/derivedtables/component-base.ts index c028aec..35f2fe6 100644 --- a/lib/db/derivedtables/component-base.ts +++ b/lib/db/derivedtables/component-base.ts @@ -7,5 +7,6 @@ export interface BaseComponent { in_stock: boolean is_basic: boolean is_preferred: boolean + is_extended_promotional: boolean attributes: Record } diff --git a/lib/db/derivedtables/dac.ts b/lib/db/derivedtables/dac.ts index a0388ad..1580050 100644 --- a/lib/db/derivedtables/dac.ts +++ b/lib/db/derivedtables/dac.ts @@ -38,6 +38,7 @@ export const dacTableSpec: DerivedTableSpec = { { name: "nonlinearity_lsb", type: "real" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -129,6 +130,7 @@ export const dacTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", resolution_bits: resolution, num_channels: numChannels, diff --git a/lib/db/derivedtables/diode.ts b/lib/db/derivedtables/diode.ts index dad2916..202afa2 100644 --- a/lib/db/derivedtables/diode.ts +++ b/lib/db/derivedtables/diode.ts @@ -40,6 +40,7 @@ export const diodeTableSpec: DerivedTableSpec = { { name: "configuration", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -159,6 +160,7 @@ export const diodeTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", forward_voltage: forwardVoltage, reverse_voltage: reverseVoltage, diff --git a/lib/db/derivedtables/fpc_connector.ts b/lib/db/derivedtables/fpc_connector.ts index ced77e9..635baff 100644 --- a/lib/db/derivedtables/fpc_connector.ts +++ b/lib/db/derivedtables/fpc_connector.ts @@ -20,6 +20,7 @@ export const fpcConnectorTableSpec: DerivedTableSpec = { { name: "locking_feature", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -55,6 +56,7 @@ export const fpcConnectorTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), pitch_mm: parseNum(attrs["Pitch"]), number_of_contacts: isNaN(contacts) ? null : contacts, contact_type: attrs["Contact Type"] || null, diff --git a/lib/db/derivedtables/fpga.ts b/lib/db/derivedtables/fpga.ts index e7d0402..78a57af 100644 --- a/lib/db/derivedtables/fpga.ts +++ b/lib/db/derivedtables/fpga.ts @@ -68,6 +68,7 @@ export const fpgaTableSpec: DerivedTableSpec = { { name: "logic_gates", type: "real" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -99,6 +100,7 @@ export const fpgaTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock ?? 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: extra?.package ?? c.package ?? "", type: attrs["Type"] ?? null, logic_array_blocks: parseNumericValue(attrs["Logic Array Blocks"]), diff --git a/lib/db/derivedtables/fuse.ts b/lib/db/derivedtables/fuse.ts index 0b56ac1..056d71d 100644 --- a/lib/db/derivedtables/fuse.ts +++ b/lib/db/derivedtables/fuse.ts @@ -25,6 +25,7 @@ export const fuseTableSpec: DerivedTableSpec = { { name: "is_resettable", type: "boolean" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -90,6 +91,7 @@ export const fuseTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), current_rating: current_rating as number, voltage_rating: voltage_rating as number, response_time, diff --git a/lib/db/derivedtables/gas_sensor.ts b/lib/db/derivedtables/gas_sensor.ts index a44050b..d0616df 100644 --- a/lib/db/derivedtables/gas_sensor.ts +++ b/lib/db/derivedtables/gas_sensor.ts @@ -36,6 +36,7 @@ export const gasSensorTableSpec: DerivedTableSpec = { { name: "measures_explosive_gases", type: "boolean" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db) { return db @@ -82,6 +83,7 @@ export const gasSensorTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", sensor_type: sensorType, measures_air_quality: measuresAirQuality, diff --git a/lib/db/derivedtables/gyroscope.ts b/lib/db/derivedtables/gyroscope.ts index 9671b5d..37e2d64 100644 --- a/lib/db/derivedtables/gyroscope.ts +++ b/lib/db/derivedtables/gyroscope.ts @@ -28,6 +28,7 @@ export const gyroscopeTableSpec: DerivedTableSpec = { { name: "has_uart", type: "boolean" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -106,6 +107,7 @@ export const gyroscopeTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", supply_voltage_min: voltageMin, supply_voltage_max: voltageMax, diff --git a/lib/db/derivedtables/header.ts b/lib/db/derivedtables/header.ts index 04bc7bb..0201fcc 100644 --- a/lib/db/derivedtables/header.ts +++ b/lib/db/derivedtables/header.ts @@ -48,6 +48,7 @@ export const headerTableSpec: DerivedTableSpec
= { { name: "is_right_angle", type: "boolean" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -197,6 +198,7 @@ export const headerTableSpec: DerivedTableSpec
= { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), price1: extractMinQPrice(c.price)!, package: c.package || "", pitch_mm: pitch, diff --git a/lib/db/derivedtables/io_expander.ts b/lib/db/derivedtables/io_expander.ts index e9bf2da..0fd61af 100644 --- a/lib/db/derivedtables/io_expander.ts +++ b/lib/db/derivedtables/io_expander.ts @@ -40,6 +40,7 @@ export const ioExpanderTableSpec: DerivedTableSpec = { { name: "source_current_ma", type: "real" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -139,6 +140,7 @@ export const ioExpanderTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", num_gpios: numGpios, supply_voltage_min: voltageMin, diff --git a/lib/db/derivedtables/jst_connector.ts b/lib/db/derivedtables/jst_connector.ts index 0afd2aa..01d13ea 100644 --- a/lib/db/derivedtables/jst_connector.ts +++ b/lib/db/derivedtables/jst_connector.ts @@ -22,6 +22,7 @@ export const jstConnectorTableSpec: DerivedTableSpec = { { name: "reference_series", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -69,6 +70,7 @@ export const jstConnectorTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), pitch_mm: parseNum(attrs["Pitch"]), num_rows: isNaN(numRows) ? null : numRows, diff --git a/lib/db/derivedtables/lcd_display.ts b/lib/db/derivedtables/lcd_display.ts index 15a34c5..0bc886a 100644 --- a/lib/db/derivedtables/lcd_display.ts +++ b/lib/db/derivedtables/lcd_display.ts @@ -19,6 +19,7 @@ export const lcdDisplayTableSpec: DerivedTableSpec = { { name: "display_type", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -64,6 +65,7 @@ export const lcdDisplayTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), display_size, resolution, diff --git a/lib/db/derivedtables/led.ts b/lib/db/derivedtables/led.ts index f12a12e..74d0f41 100644 --- a/lib/db/derivedtables/led.ts +++ b/lib/db/derivedtables/led.ts @@ -37,6 +37,7 @@ export const ledTableSpec: DerivedTableSpec = { { name: "is_rgb", type: "boolean" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -165,6 +166,7 @@ export const ledTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", forward_voltage: forwardVoltage, forward_current: forwardCurrent, diff --git a/lib/db/derivedtables/led_dot_matrix_display.ts b/lib/db/derivedtables/led_dot_matrix_display.ts index 2d32eda..cf1a4be 100644 --- a/lib/db/derivedtables/led_dot_matrix_display.ts +++ b/lib/db/derivedtables/led_dot_matrix_display.ts @@ -18,6 +18,7 @@ export const ledDotMatrixDisplayTableSpec: DerivedTableSpec { name: "color", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -57,6 +58,7 @@ export const ledDotMatrixDisplayTableSpec: DerivedTableSpec in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), matrix_size, color, diff --git a/lib/db/derivedtables/led_driver.ts b/lib/db/derivedtables/led_driver.ts index 55f0e8c..771ef99 100644 --- a/lib/db/derivedtables/led_driver.ts +++ b/lib/db/derivedtables/led_driver.ts @@ -42,6 +42,7 @@ export const ledDriverTableSpec: DerivedTableSpec = { { name: "mounting_style", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -77,6 +78,7 @@ export const ledDriverTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), supply_voltage_min: parseValue(attrs["Input Voltage"]?.split("~")[0]), supply_voltage_max: parseValue(attrs["Input Voltage"]?.split("~")[1]), diff --git a/lib/db/derivedtables/led_segment_display.ts b/lib/db/derivedtables/led_segment_display.ts index bf5f50e..ede8e4c 100644 --- a/lib/db/derivedtables/led_segment_display.ts +++ b/lib/db/derivedtables/led_segment_display.ts @@ -21,6 +21,7 @@ export const ledSegmentDisplayTableSpec: DerivedTableSpec = { { name: "color", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { @@ -70,6 +71,7 @@ export const ledSegmentDisplayTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), positions, type, diff --git a/lib/db/derivedtables/led_with_ic.ts b/lib/db/derivedtables/led_with_ic.ts index bba0faa..223d461 100644 --- a/lib/db/derivedtables/led_with_ic.ts +++ b/lib/db/derivedtables/led_with_ic.ts @@ -27,6 +27,7 @@ export const ledWithICTableSpec: DerivedTableSpec = { { name: "protocol", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -99,6 +100,7 @@ export const ledWithICTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), forward_voltage: forwardVoltage, forward_current: forwardCurrent, diff --git a/lib/db/derivedtables/microcontroller.ts b/lib/db/derivedtables/microcontroller.ts index 6b7b083..80fc598 100644 --- a/lib/db/derivedtables/microcontroller.ts +++ b/lib/db/derivedtables/microcontroller.ts @@ -62,6 +62,7 @@ export const microcontrollerTableSpec: DerivedTableSpec = { { name: "dac_resolution_bits", type: "integer" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -228,6 +229,7 @@ export const microcontrollerTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", cpu_core: cpuCore, cpu_speed_hz: cpuSpeed, diff --git a/lib/db/derivedtables/mosfet.ts b/lib/db/derivedtables/mosfet.ts index 31f5412..725db7d 100644 --- a/lib/db/derivedtables/mosfet.ts +++ b/lib/db/derivedtables/mosfet.ts @@ -35,6 +35,7 @@ export const mosfetTableSpec: DerivedTableSpec = { { name: "mounting_style", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -68,6 +69,7 @@ export const mosfetTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), drain_source_voltage: parseValue( attrs["Drain Source Voltage (Vdss)"], diff --git a/lib/db/derivedtables/oled_display.ts b/lib/db/derivedtables/oled_display.ts index dbabb65..e2c0ce6 100644 --- a/lib/db/derivedtables/oled_display.ts +++ b/lib/db/derivedtables/oled_display.ts @@ -19,6 +19,7 @@ export const oledDisplayTableSpec: DerivedTableSpec = { { name: "pixel_resolution", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { @@ -65,6 +66,7 @@ export const oledDisplayTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), protocol: protocol || undefined, display_width, diff --git a/lib/db/derivedtables/pcie_m2_connector.ts b/lib/db/derivedtables/pcie_m2_connector.ts index 0e9bcc1..9ca18a8 100644 --- a/lib/db/derivedtables/pcie_m2_connector.ts +++ b/lib/db/derivedtables/pcie_m2_connector.ts @@ -14,6 +14,7 @@ export const pcieM2ConnectorTableSpec: DerivedTableSpec = { { name: "is_right_angle", type: "boolean" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -49,6 +50,7 @@ export const pcieM2ConnectorTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), key, is_right_angle: isRightAngle, attributes: attrs, diff --git a/lib/db/derivedtables/potentiometer.ts b/lib/db/derivedtables/potentiometer.ts index b7c0080..1cc4a70 100644 --- a/lib/db/derivedtables/potentiometer.ts +++ b/lib/db/derivedtables/potentiometer.ts @@ -19,6 +19,7 @@ export const potentiometerTableSpec: DerivedTableSpec = { { name: "is_surface_mount", type: "boolean" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -67,6 +68,7 @@ export const potentiometerTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), max_resistance: maxResistance, pin_variant: pinVariant, package: c.package || "", diff --git a/lib/db/derivedtables/relay.ts b/lib/db/derivedtables/relay.ts index 944a5fe..402a7d7 100644 --- a/lib/db/derivedtables/relay.ts +++ b/lib/db/derivedtables/relay.ts @@ -29,6 +29,7 @@ export const relayTableSpec: DerivedTableSpec = { { name: "pin_number", type: "integer" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -62,6 +63,7 @@ export const relayTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), relay_type: (c as any).subcategory || "", contact_form: attrs["Contact Form"] || null, diff --git a/lib/db/derivedtables/resistor.ts b/lib/db/derivedtables/resistor.ts index b6b437d..f11563f 100644 --- a/lib/db/derivedtables/resistor.ts +++ b/lib/db/derivedtables/resistor.ts @@ -31,6 +31,7 @@ export const resistorTableSpec: DerivedTableSpec = { { name: "is_multi_resistor_chip", type: "boolean" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -82,6 +83,7 @@ export const resistorTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), resistance: resistance, tolerance_fraction: tolerance, power_watts, diff --git a/lib/db/derivedtables/resistor_array.ts b/lib/db/derivedtables/resistor_array.ts index 5521d4d..5ae02a7 100644 --- a/lib/db/derivedtables/resistor_array.ts +++ b/lib/db/derivedtables/resistor_array.ts @@ -69,6 +69,7 @@ export const resistorArrayTableSpec: DerivedTableSpec = { { name: "is_surface_mount", type: "boolean" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db diff --git a/lib/db/derivedtables/switch.ts b/lib/db/derivedtables/switch.ts index 5730306..ccf0328 100644 --- a/lib/db/derivedtables/switch.ts +++ b/lib/db/derivedtables/switch.ts @@ -37,6 +37,7 @@ export const switchTableSpec: DerivedTableSpec = { { name: "switch_height_mm", type: "real" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db) { return db @@ -91,6 +92,7 @@ export const switchTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", switch_type: (c as any).subcategory || "", circuit: attrs["Circuit"] || null, diff --git a/lib/db/derivedtables/usb_c_connector.ts b/lib/db/derivedtables/usb_c_connector.ts index 6d7b317..54e7a86 100644 --- a/lib/db/derivedtables/usb_c_connector.ts +++ b/lib/db/derivedtables/usb_c_connector.ts @@ -28,6 +28,7 @@ export const usbCConnectorTableSpec: DerivedTableSpec = { { name: "operating_temp_max", type: "real" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents(db: KyselyDatabaseInstance) { return db @@ -69,6 +70,7 @@ export const usbCConnectorTableSpec: DerivedTableSpec = { in_stock: Boolean((c.stock || 0) > 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), mounting_style: attrs["Mounting Style"] || null, current_rating_a: parseNum(attrs["Current Rating - Power (Max)"]), diff --git a/lib/db/derivedtables/voltage_regulator.ts b/lib/db/derivedtables/voltage_regulator.ts index 86b0f14..e5c50cf 100644 --- a/lib/db/derivedtables/voltage_regulator.ts +++ b/lib/db/derivedtables/voltage_regulator.ts @@ -43,6 +43,7 @@ export const voltageRegulatorTableSpec: DerivedTableSpec = { { name: "topology", type: "text" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -184,6 +185,7 @@ export const voltageRegulatorTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", output_type: outputType, output_voltage_min: voltageMin, diff --git a/lib/db/derivedtables/wifi_module.ts b/lib/db/derivedtables/wifi_module.ts index f56be11..bffb83f 100644 --- a/lib/db/derivedtables/wifi_module.ts +++ b/lib/db/derivedtables/wifi_module.ts @@ -45,6 +45,7 @@ export const wifiModuleTableSpec: DerivedTableSpec = { { name: "has_pwm", type: "boolean" }, { name: "is_basic", type: "boolean" }, { name: "is_preferred", type: "boolean" }, + { name: "is_extended_promotional", type: "boolean" }, ], listCandidateComponents: (db) => db @@ -140,6 +141,7 @@ export const wifiModuleTableSpec: DerivedTableSpec = { in_stock: c.stock > 0, is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: c.package || "", core_processor: attrs["Core Processor"] || null, antenna_type: attrs["Antenna Type"] || null, diff --git a/lib/db/derivedtables/wire_to_board_connector.ts b/lib/db/derivedtables/wire_to_board_connector.ts index 48a30a6..c595131 100644 --- a/lib/db/derivedtables/wire_to_board_connector.ts +++ b/lib/db/derivedtables/wire_to_board_connector.ts @@ -61,6 +61,7 @@ export const wireToBoardConnectorTableSpec: DerivedTableSpec 0), is_basic: Boolean(c.basic), is_preferred: Boolean(c.preferred), + is_extended_promotional: Boolean(c.extra && JSON.parse(c.extra).promotional), package: String(c.package || ""), pitch_mm: pitchMm, num_rows: numRows, diff --git a/lib/db/optimizations/component-extended-promotional-column.ts b/lib/db/optimizations/component-extended-promotional-column.ts new file mode 100644 index 0000000..30937ba --- /dev/null +++ b/lib/db/optimizations/component-extended-promotional-column.ts @@ -0,0 +1,39 @@ +import { sql } from "kysely" +import type { DbOptimizationSpec } from "./types" +import type { KyselyDatabaseInstance } from "../kysely-types" + +export const componentExtendedPromotionalColumn: DbOptimizationSpec = { + name: "add_components_is_extended_promotional_column", + description: + "Adds is_extended_promotional boolean column to components table derived from extra JSON field", + + async checkIfAdded(db: KyselyDatabaseInstance) { + const { + rows: [ex], + } = await sql` + SELECT * FROM components LIMIT 1 + `.execute(db) + + return ex != null && "is_extended_promotional" in ex + }, + + async execute(db: KyselyDatabaseInstance) { + // Add the column derived from the JSON extra field + await sql` + ALTER TABLE components + ADD COLUMN is_extended_promotional boolean + GENERATED ALWAYS AS ( + CASE WHEN json_extract(extra, '$.promotional') IS NOT NULL + AND json_extract(extra, '$.promotional') != 0 + AND json_extract(extra, '$.promotional') != 'false' + THEN 1 ELSE 0 END + ) + `.execute(db) + + await db.schema + .createIndex("idx_components_is_extended_promotional") + .on("components") + .column("is_extended_promotional") + .execute() + }, +} diff --git a/scripts/setup-db-optimizations.ts b/scripts/setup-db-optimizations.ts index 062ed9d..bc2fec1 100644 --- a/scripts/setup-db-optimizations.ts +++ b/scripts/setup-db-optimizations.ts @@ -9,6 +9,7 @@ import { componentSearchFTS } from "lib/db/optimizations/component-search-fts" import { componentPackageIndex } from "lib/db/optimizations/component-indexes" import { componentBasicIndex } from "lib/db/optimizations/component-basic-index" import { componentPreferredIndex } from "lib/db/optimizations/component-preferred-index" +import { componentExtendedPromotionalColumn } from "lib/db/optimizations/component-extended-promotional-column" const OPTIMIZATIONS: DbOptimizationSpec[] = [ componentSearchFTS, @@ -18,6 +19,7 @@ const OPTIMIZATIONS: DbOptimizationSpec[] = [ removeStaleComponents, componentStockIndex, componentInStockColumn, + componentExtendedPromotionalColumn, componentCategoryIndex, componentInStockCategoryIndex, ]