92 lines
4.5 KiB
Ruby
Executable File
92 lines
4.5 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
# encoding: utf-8
|
|
# ruby: 3.0.0
|
|
=begin
|
|
KiCAD can have a KiCad database library
|
|
https://docs.kicad.org/master/en/eeschema/eeschema.html#database_libraries
|
|
this script creates views from the partdb table so to create a database for KiCAD
|
|
if wil also output the KiCad database library file
|
|
=end
|
|
require 'mysql2'
|
|
require 'json'
|
|
|
|
CREDENTIALS = "credentials.json"
|
|
raise "database information #{CREDENTIALS} do not exist" unless File.file? CREDENTIALS
|
|
credentials = {}
|
|
JSON.parse(IO.read(CREDENTIALS)).each {|key,value| credentials[key.to_sym] = value}
|
|
Mysql2::Client.default_query_options.merge!(:as => :hash)
|
|
db = Mysql2::Client.new(credentials)
|
|
KICAD_FILE = "partdb.kicad_dbl"
|
|
DEBUG = false # print debug information
|
|
|
|
puts "= create part to properties views ="
|
|
|
|
prop2view = [{property: "kicad_symbol"}, {property: "kicad_footprint"}, {property: "qeda_part"}, {property: "qeda_variant"}, {property: "JLCPCB_CORRECTION"}]
|
|
prop2view.each do |prop|
|
|
puts prop[:property]
|
|
prop[:table] = "part_" + prop[:property].downcase.gsub(/[- \/]/,"_")
|
|
view = "CREATE OR REPLACE VIEW #{prop[:table]} AS SELECT properties.part AS part, properties.value AS #{prop[:property]} FROM properties JOIN property ON property.id = properties.property WHERE property.name = '#{prop[:property]}'"
|
|
puts view if DEBUG
|
|
db.query(view)
|
|
end
|
|
|
|
puts "= create part to distribution views ="
|
|
|
|
dist2view = [{property: "LCSC"}, {property: "JLCPCB"}, {property: "DigiKey"}]
|
|
|
|
dist2view.each do |prop|
|
|
puts prop[:property]
|
|
prop[:table] = "part_" + prop[:property].downcase.gsub(/[- \/]/,"_")
|
|
view = "CREATE OR REPLACE VIEW #{prop[:table]} AS SELECT distribution.part AS part, distribution.sku AS #{prop[:property]} FROM distribution JOIN distributor ON distributor.id = distribution.distributor WHERE distributor.name = '#{prop[:property]}'"
|
|
puts view if DEBUG
|
|
db.query(view)
|
|
end
|
|
|
|
puts "= create part category tables ="
|
|
|
|
kicad_dbl = {} # kicad database library file
|
|
kicad_dbl["meta"] = {version: 0}
|
|
kicad_dbl["name"] = "CuVoodoo Database Library"
|
|
kicad_dbl["description"] = "database of all my parts"
|
|
# username/UID and password should be configured in DSN so we don't lead it when we share the resulting file
|
|
kicad_dbl["source"] = {type: "odbc", dsn: "partdb", timeout_seconds: 3}
|
|
kicad_dbl["libraries"] = []
|
|
|
|
categories = db.query("SELECT properties.value AS category FROM properties LEFT JOIN property ON property.id = properties.property WHERE property.name = 'category'").to_a.collect {|row| row['category']}
|
|
categories.uniq!
|
|
categories.each do |category|
|
|
puts category
|
|
table = "kicad_lib_" + category.downcase.gsub(/[- \/]/,"_")
|
|
view = "CREATE OR REPLACE VIEW #{table} AS "
|
|
view += "SELECT part.id, part.name, part.description, "
|
|
(prop2view + dist2view).each do |prop|
|
|
view += "COALESCE(#{prop[:table]}1.#{prop[:property]},#{prop[:table]}2.#{prop[:property]}) AS #{prop[:property]}, "
|
|
end
|
|
view += "COALESCE(part.datasheet,parent.datasheet) AS datasheet FROM part "
|
|
view += "LEFT JOIN part AS parent ON parent.id = part.family "
|
|
(prop2view + dist2view).each do |prop|
|
|
view += "LEFT JOIN #{prop[:table]} AS #{prop[:table]}1 ON #{prop[:table]}1.part = part.id "
|
|
view += "LEFT JOIN #{prop[:table]} AS #{prop[:table]}2 ON #{prop[:table]}2.part = parent.id "
|
|
end
|
|
view += "WHERE part.id IN (SELECT part FROM properties LEFT JOIN property ON property.id = properties.property WHERE property.name = 'category' AND properties.value = '#{category}') "
|
|
view += "OR parent.id IN (SELECT part FROM properties LEFT JOIN property ON property.id = properties.property WHERE property.name = 'category' AND properties.value = '#{category}')"
|
|
puts view if DEBUG
|
|
db.query(view)
|
|
|
|
library = {name: category, table: table, key: "name", symbols: "kicad_symbol", footprints: "kicad_footprint"}
|
|
library[:properties] = {description: "description"}
|
|
library[:fields] = []
|
|
library[:fields] << {name: "Description", column: "description", visible_on_add: false, visible_in_chooser: true, show_name: false, inherit_properties: true}
|
|
library[:fields] << {name: "Datasheet", column: "datasheet", visible_on_add: false, visible_in_chooser: true, show_name: false, inherit_properties: true}
|
|
(prop2view + dist2view).each do |prop|
|
|
next if prop[:property].start_with? "kicad_"
|
|
library[:fields] << {name: prop[:property], column: prop[:property], visible_on_add: false, visible_in_chooser: true, show_name: false, inherit_properties: true}
|
|
end
|
|
kicad_dbl["libraries"] << library
|
|
end
|
|
|
|
puts "writing KiCad database library file to #{KICAD_FILE}"
|
|
File.open(KICAD_FILE, "w") do |file|
|
|
file.write kicad_dbl.to_json
|
|
end
|