Ignore:
Timestamp:
Aug 3, 2007, 3:15:11 AM (13 years ago)
Author:
jmpp@…
Message:

Sizeable facelift to the PortIndex2MySQL.tcl script. Highlights:

  • Bring it up to date wrt the macports1.0 api and into the new namespace;
  • Make it self-contained, writing its sql output to a flat file directly and then piping its contents to a proper database command (like mysql5(1)); this eliminates both the need to load the mysqltcl library or, the other case, wrap the tcl code with a shell script to do all the needed redirection to get the information into the db;
  • Get rid of a lot of now unnecessary code due to the rework above;
  • Provide abstraction variables to easily adapt the script to any scenario and a proc to read the db password from a file that must exist (this bit could definitely use some improvements, like for passwordless db's);
  • Add build and run dependencies for a given port as sql statements into the db (previously only lib deps were being recorded);
  • For fields with multiple and hierarchycal values, like categories, index them sequentially up from 1 (1 being topmost), rather than 1 for the first one (most important) and 0 for the rest (flat second place) as it was being done;
  • Use procs in the macports1.0 package, like ui_error;
  • Provide a Makefile (currently unhooked from MacPorts build system) to tie the script into an already configured MacPorts installation.

So, in a nutshell, the script now works to generate valid SQL statements for our ports tree,
we can extend it to do anything else we want and then find a client that will read such db
and thus put it to good use ;-) (old ports.php page, here I come!)

Location:
trunk/base/portmgr/packaging
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/base/portmgr/packaging/PortIndex2MySQL.tcl

    r26177 r27415  
    11#!/usr/bin/env tclsh
     2#
    23# PortIndex2MySQL.tcl
    34# Kevin Van Vechten | kevin@opendarwin.org
    45# 3-Oct-2002
     6# Juan Manuel Palacios | jmpp@macports.org
     7# 30-Jul-2007
    58# $Id$
    69#
     10# Copyright (c) 2007 Juan Manuel Palacios, MacPorts Team.
    711# Copyright (c) 2003 Apple Computer, Inc.
    812# Copyright (c) 2002 Kevin Van Vechten.
     
    3539
    3640catch {source \
    37            [file join "@TCL_PACKAGE_DIR@" darwinports1.0 darwinports_fastload.tcl]}
    38 package require darwinports
    39 
    40 proc ui_prefix {priority} {
    41         return ""
    42 }
    43 
    44 proc ui_channels {priority} {
    45         return {}
    46 }
    47 
    48 # This should be a command line argument.
    49 # if true, use_db insructs the script to insert directly into a database
    50 # otherwise, sql statements will be printed to stdout.
    51 set use_db ""
    52 
    53 array set ui_options {}
    54 array set global_options {}
    55 array set global_variations {}
    56 dportinit ui_options global_options global_variations
    57 
    58 if {$use_db != ""} {
    59     load @PREFIX@/lib/libmysqltcl.dylib
    60     set db [mysqlconnect -user darwinports -password woot -db darwinports]
    61 } else {
    62     set db ""
    63 }
    64 
    65 proc sql_exec {db sql} {
    66     if {$db != ""} {
    67         mysqlexec $db $sql
    68     } else {
    69         puts "${sql};"
     41           [file join "@TCL_PACKAGE_DIR@" macports1.0 macports_fastload.tcl]}
     42package require macports
     43
     44# Initialize the MacPorts system to find the sources.conf file, wherefrom we'll be
     45# getting the PortIndex file that'll feed the database, and initialize the portinfo
     46# array for each port.
     47mportinit
     48
     49# Procedure to catch the database password from a protected file.
     50proc getpasswd {passwdfile} {
     51    if {[catch {open $passwdfile r} passwdfile_fd]} {
     52        ui_error "${::errorCode}: $passwdfile_fd"
     53        exit 1
    7054    }
    71 }
    72 
     55    if {[gets $passwdfile_fd passwd] <= 0} {
     56        ui_error "No password found in $passwdfile!"
     57        exit 1
     58    }
     59    close $passwdfile_fd
     60    return $passwd
     61}
     62
     63
     64# Needed escaping for some strings output as sql statements.
    7365proc sql_escape {str} {
    74     global use_db
    75     if {$use_db != ""} {
    76         return [msyqlescape $str]
    77     } else {
    7866        regsub -all -- {'} $str {\\'} str
    7967        regsub -all -- {"} $str {\\"} str
    8068        regsub -all -- {\n} $str {\\n} str
    8169        return $str
    82     }
    83 }
    84 
    85 # CREATE TABLE portfiles (name VARCHAR(255) PRIMARY KEY NOT NULL,
    86 #  path VARCHAR(255),
    87 #  version VARCHAR(255),
    88 #  description TEXT);
    89 
    90 # CREATE TABLE categories (portfile VARCHAR(255),
    91 #  category VARCHAR(255),
    92 #  primary INTEGER);
    93 
    94 # CREATE TABLE maintainers (portfile VARCHAR(255),
    95 #  maintainer VARCHAR(255),
    96 #  primary INTEGER);
    97 
    98 sql_exec $db "DROP TABLE log"
    99 sql_exec $db "CREATE TABLE IF NOT EXISTS log (activity VARCHAR(255), activity_time TIMESTAMP(14))"
    100 sql_exec $db "INSERT INTO log VALUES ('update', NOW())"
    101 
    102 sql_exec $db "DROP TABLE portfiles"
    103 sql_exec $db "CREATE TABLE portfiles (name VARCHAR(255) PRIMARY KEY NOT NULL, path VARCHAR(255), version VARCHAR(255),  description TEXT)"
    104 
    105 sql_exec $db "DROP TABLE IF EXISTS categories"
    106 sql_exec $db "CREATE TABLE categories (portfile VARCHAR(255), category VARCHAR(255), is_primary INTEGER)"
    107 
    108 sql_exec $db "DROP TABLE IF EXISTS maintainers"
    109 sql_exec $db "CREATE TABLE maintainers (portfile VARCHAR(255), maintainer VARCHAR(255), is_primary INTEGER)"
    110 
    111 sql_exec $db "DROP TABLE IF EXISTS dependencies"
    112 sql_exec $db "CREATE TABLE dependencies (portfile VARCHAR(255), library VARCHAR(255))"
    113 
    114 sql_exec $db "DROP TABLE IF EXISTS variants"
    115 sql_exec $db "CREATE TABLE variants (portfile VARCHAR(255), variant VARCHAR(255))"
    116 
    117 sql_exec $db "DROP TABLE IF EXISTS platforms"
    118 sql_exec $db "CREATE TABLE platforms (portfile VARCHAR(255), platform VARCHAR(255))"
    119 
    120 if {[catch {set ports [dportsearch ".+"]} errstr]} {
    121         puts "port search failed: $errstr"
     70}
     71
     72
     73# Abstraction variables:
     74set sqlfile [file join /tmp ports.sql]
     75set dbcmd [macports::findBinary mysql5]
     76set dbname macports
     77set passwdfile [file join . password_file]
     78set dbpasswd [getpasswd $passwdfile]
     79set dbcmdargs "$dbname --password=$dbpasswd"
     80
     81
     82# Flat text file to which sql statements are written.
     83if {[catch {open $sqlfile w+} sqlfile_fd]} {
     84    ui_error "${::errorCode}: $sqlfile_fd"
     85    exit 1
     86}
     87
     88
     89# Initial creation of database tables: log, portfiles, categories, maintainers, dependencies, variants and platforms.
     90# Do we need any other?
     91puts $sqlfile_fd "DROP TABLE log"
     92puts $sqlfile_fd "CREATE TABLE IF NOT EXISTS log (activity VARCHAR(255), activity_time TIMESTAMP(14))"
     93puts $sqlfile_fd "INSERT INTO log VALUES ('update', NOW())"
     94
     95puts $sqlfile_fd "DROP TABLE portfiles"
     96puts $sqlfile_fd "CREATE TABLE portfiles (name VARCHAR(255) PRIMARY KEY NOT NULL, path VARCHAR(255), version VARCHAR(255),  description TEXT)"
     97
     98puts $sqlfile_fd "DROP TABLE IF EXISTS categories"
     99puts $sqlfile_fd "CREATE TABLE categories (portfile VARCHAR(255), category VARCHAR(255), is_primary INTEGER)"
     100
     101puts $sqlfile_fd "DROP TABLE IF EXISTS maintainers"
     102puts $sqlfile_fd "CREATE TABLE maintainers (portfile VARCHAR(255), maintainer VARCHAR(255), is_primary INTEGER)"
     103
     104puts $sqlfile_fd "DROP TABLE IF EXISTS dependencies"
     105puts $sqlfile_fd "CREATE TABLE dependencies (portfile VARCHAR(255), library VARCHAR(255))"
     106
     107puts $sqlfile_fd "DROP TABLE IF EXISTS variants"
     108puts $sqlfile_fd "CREATE TABLE variants (portfile VARCHAR(255), variant VARCHAR(255))"
     109
     110puts $sqlfile_fd "DROP TABLE IF EXISTS platforms"
     111puts $sqlfile_fd "CREATE TABLE platforms (portfile VARCHAR(255), platform VARCHAR(255))"
     112
     113if {[catch {set ports [mportsearch ".+"]} errstr]} {
     114        ui_error "port search failed: $errstr"
    122115        exit 1
    123116}
    124117
    125118foreach {name array} $ports {
     119
    126120        array unset portinfo
    127121        array set portinfo $array
     122
    128123        set portname [sql_escape $portinfo(name)]
    129124        if {[info exists portinfo(version)]} {
     
    153148                set variants ""
    154149        }
     150        if {[info exists portinfo(depends_build)]} {
     151                set depends_build $portinfo(depends_build)
     152        } else {
     153                set depends_build ""
     154        }
    155155        if {[info exists portinfo(depends_lib)]} {
    156156                set depends_lib $portinfo(depends_lib)
     
    158158                set depends_lib ""
    159159        }
     160        if {[info exists portinfo(depends_run)]} {
     161                set depends_run $portinfo(depends_run)
     162        } else {
     163                set depends_run ""
     164        }
    160165        if {[info exists portinfo(platforms)]} {
    161166                set platforms $portinfo(platforms)
     
    163168                set platforms ""
    164169        }
    165                
    166         set sql "INSERT INTO portfiles VALUES ('$portname', '$portdir', '$portversion', '$description')"
    167         #puts "$sql"
    168         sql_exec $db $sql
     170
     171        puts $sqlfile_fd "INSERT INTO portfiles VALUES ('$portname', '$portdir', '$portversion', '$description')"
    169172
    170173        set primary 1
    171174        foreach category $categories {
    172175                set category [sql_escape $category]
    173                 set sql "INSERT INTO categories VALUES ('$portname', '$category', $primary)"
    174                 #puts "$sql"
    175                 sql_exec $db $sql
    176                 set primary 0
     176                puts $sqlfile_fd "INSERT INTO categories VALUES ('$portname', '$category', $primary)"
     177                incr primary
    177178        }
    178179       
     
    180181        foreach maintainer $maintainers {
    181182                set maintainer [sql_escape $maintainer]
    182                 set sql "INSERT INTO maintainers VALUES ('$portname', '$maintainer', $primary)"
    183                 #puts "$sql"
    184                 sql_exec $db $sql
    185                 set primary 0
    186         }
     183                puts $sqlfile_fd "INSERT INTO maintainers VALUES ('$portname', '$maintainer', $primary)"
     184                incr primary
     185        }
     186
     187        foreach build_dep $depends_build {
     188            set build_dep [sql_escape $build_dep]
     189            puts $sqlfile_fd "INSERT INTO dependencies VALUES ('$portname', '$build_dep')"
     190        }
    187191
    188192        foreach lib $depends_lib {
    189193                set lib [sql_escape $lib]
    190                 set sql "INSERT INTO dependencies VALUES ('$portname', '$lib')"
    191                 #puts "$sql"
    192                 sql_exec $db $sql
    193         }
     194                puts $sqlfile_fd "INSERT INTO dependencies VALUES ('$portname', '$lib')"
     195        }
     196
     197        foreach run_dep $depends_run {
     198            set run_dep [sql_escape $run_dep]
     199            puts $sqlfile_fd "INSERT INTO dependencies VALUES ('$portname', '$run_dep')"
     200        }
    194201
    195202        foreach variant $variants {
    196203                set variant [sql_escape $variant]
    197                 set sql "INSERT INTO variants VALUES ('$portname', '$variant')"
    198                 #puts "$sql"
    199                 sql_exec $db $sql
     204                puts $sqlfile_fd "INSERT INTO variants VALUES ('$portname', '$variant')"
    200205        }
    201206
    202207        foreach platform $platforms {
    203208                set platform [sql_escape $platform]
    204                 set sql "INSERT INTO platforms VALUES ('$portname', '$platform')"
    205                 #puts "$sql"
    206                 sql_exec $db $sql
    207         }
    208 
    209 }
    210 
    211 if {$db != ""} {
    212     mysqlclose $db
    213     mysqlclose
    214 }
     209                puts $sqlfile_fd "INSERT INTO platforms VALUES ('$portname', '$platform')"
     210        }
     211
     212}
     213
     214
     215# Pipe the contents of the generated sql file to the database command:
     216if {[catch {seek $sqlfile_fd 0 start} errstr]} {
     217    ui_error "${::errorCode}: $errstr"
     218    exit 1
     219}
     220if {[catch {exec $dbcmd $dbcmdargs <@ $sqlfile_fd} errstr]} {
     221    ui_error "${::errorCode}: $errstr"
     222    exit 1
     223}
     224
     225
     226# And we're done regen'ing the MacPorts dabase! (cleanup)
     227close $sqlfile_fd
     228file delete -force $sqlfile
Note: See TracChangeset for help on using the changeset viewer.