source: trunk/base/portmgr/packaging/PortIndex2MySQL.tcl @ 27826

Last change on this file since 27826 was 27826, checked in by jmpp@…, 13 years ago

Add still place-holder proc for proper error reporting and processing to the PortIndex2MySQL.tcl script,
pending on the still being worked on macports1.0 intialization through mportinit's args to get verbose/debugging
output (gotta review how port(1) does this to get it right, possibly integrating some of the functionality
into macports1.0's default implementation).

Also add a call to macports::selfupdate (leveraging the now optional arg API change) to insure the tree we're
working with is always fresh.

Improve the db command call and relocate the sql string escaping proc.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.2 KB
Line 
1#!/usr/bin/env tclsh
2#
3# PortIndex2MySQL.tcl
4# Kevin Van Vechten | kevin@opendarwin.org
5# 3-Oct-2002
6# Juan Manuel Palacios | jmpp@macports.org
7# 30-Jul-2007
8# $Id: PortIndex2MySQL.tcl 27826 2007-08-14 21:38:44Z jmpp@macports.org $
9#
10# Copyright (c) 2007 Juan Manuel Palacios, MacPorts Team.
11# Copyright (c) 2003 Apple Computer, Inc.
12# Copyright (c) 2002 Kevin Van Vechten.
13# All rights reserved.
14#
15# Redistribution and use in source and binary forms, with or without
16# modification, are permitted provided that the following conditions
17# are met:
18# 1. Redistributions of source code must retain the above copyright
19#    notice, this list of conditions and the following disclaimer.
20# 2. Redistributions in binary form must reproduce the above copyright
21#    notice, this list of conditions and the following disclaimer in the
22#    documentation and/or other materials provided with the distribution.
23# 3. Neither the name of Apple Computer, Inc. nor the names of its contributors
24#    may be used to endorse or promote products derived from this software
25#    without specific prior written permission.
26#
27# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37# POSSIBILITY OF SUCH DAMAGE.
38
39
40# Error messages reciepient.
41set SPAM_LOVERS macports-dev@lists.macosforge.org
42
43# Place holder proc for error catching and processing.
44proc bail_on_error {error_log} {
45   
46}
47
48
49# Load macports1.0 so that we can use some of its procs and the portinfo array.
50catch {source \
51           [file join "@TCL_PACKAGE_DIR@" macports1.0 macports_fastload.tcl]}
52package require macports
53
54# Initialize MacPorts to find the sources.conf file, wherefrom we'll
55# get the PortIndex that'll feed the database.
56#more work needs to be done than just initializing and passing the
57#ui_options array to get mportinit to output verbose/debugging info;
58#I'm currently looking into this.
59array set ui_options {ports_verbose yes}
60mportinit
61
62# Call the selfupdate procedure to make sure the MacPorts installation
63# is up-to-date and with a fresh ports tree.
64macports::selfupdate
65
66
67# Procedure to catch the database password from a protected file.
68proc getpasswd {passwdfile} {
69    if {[catch {open $passwdfile r} passwdfile_fd]} {
70        ui_error "${::errorCode}: $passwdfile_fd"
71        exit 1
72    }
73    if {[gets $passwdfile_fd passwd] <= 0} {
74        ui_error "No password found in $passwdfile!"
75        exit 1
76    }
77    close $passwdfile_fd
78    return $passwd
79}
80
81# Database abstraction variables:
82set sqlfile [file join /tmp ports.sql]
83set dbcmd [macports::findBinary mysql5]
84set dbhost 127.0.0.1
85set dbname macports
86set dbuser macports
87set passwdfile [file join . password_file]
88set dbpasswd [getpasswd $passwdfile]
89set dbcmdargs "-h $dbhost -u $dbuser -p$dbpasswd $dbname"
90
91# Flat text file to which sql statements are written.
92if {[catch {open $sqlfile w+} sqlfile_fd]} {
93    ui_error "${::errorCode}: $sqlfile_fd"
94    exit 1
95}
96
97
98# SQL string escaping.
99proc sql_escape {str} {
100        regsub -all -- {'} $str {\\'} str
101        regsub -all -- {"} $str {\\"} str
102        regsub -all -- {\n} $str {\\n} str
103        return $str
104}
105
106# Initial creation of database tables: log, portfiles, categories, maintainers, dependencies, variants and platforms.
107# Do we need any other?
108puts $sqlfile_fd "DROP TABLE log"
109puts $sqlfile_fd "CREATE TABLE IF NOT EXISTS log (activity VARCHAR(255), activity_time TIMESTAMP(14))"
110puts $sqlfile_fd "INSERT INTO log VALUES ('update', NOW())"
111
112puts $sqlfile_fd "DROP TABLE portfiles"
113puts $sqlfile_fd "CREATE TABLE portfiles (name VARCHAR(255) PRIMARY KEY NOT NULL, path VARCHAR(255), version VARCHAR(255),  description TEXT)"
114
115puts $sqlfile_fd "DROP TABLE IF EXISTS categories"
116puts $sqlfile_fd "CREATE TABLE categories (portfile VARCHAR(255), category VARCHAR(255), is_primary INTEGER)"
117
118puts $sqlfile_fd "DROP TABLE IF EXISTS maintainers"
119puts $sqlfile_fd "CREATE TABLE maintainers (portfile VARCHAR(255), maintainer VARCHAR(255), is_primary INTEGER)"
120
121puts $sqlfile_fd "DROP TABLE IF EXISTS dependencies"
122puts $sqlfile_fd "CREATE TABLE dependencies (portfile VARCHAR(255), library VARCHAR(255))"
123
124puts $sqlfile_fd "DROP TABLE IF EXISTS variants"
125puts $sqlfile_fd "CREATE TABLE variants (portfile VARCHAR(255), variant VARCHAR(255))"
126
127puts $sqlfile_fd "DROP TABLE IF EXISTS platforms"
128puts $sqlfile_fd "CREATE TABLE platforms (portfile VARCHAR(255), platform VARCHAR(255))"
129
130
131# Load every port in the index through a search matching everything.
132if {[catch {set ports [mportsearch ".+"]} errstr]} {
133        ui_error "port search failed: $errstr"
134        exit 1
135}
136
137# Iterate over each matching port, extracting its information from the
138# portinfo array.
139foreach {name array} $ports {
140
141        array unset portinfo
142        array set portinfo $array
143
144        set portname [sql_escape $portinfo(name)]
145        if {[info exists portinfo(version)]} {
146                set portversion [sql_escape $portinfo(version)]
147        } else {
148                set portversion ""
149        }
150        set portdir [sql_escape $portinfo(portdir)]
151        if {[info exists portinfo(description)]} {
152                set description [sql_escape $portinfo(description)]
153        } else {
154                set description ""
155        }
156        if {[info exists portinfo(categories)]} {
157                set categories $portinfo(categories)
158        } else {
159                set categories ""
160        }
161        if {[info exists portinfo(maintainers)]} {
162                set maintainers $portinfo(maintainers)
163        } else {
164                set maintainers ""
165        }
166        if {[info exists portinfo(variants)]} {
167                set variants $portinfo(variants)
168        } else {
169                set variants ""
170        }
171        if {[info exists portinfo(depends_build)]} {
172                set depends_build $portinfo(depends_build)
173        } else {
174                set depends_build ""
175        }
176        if {[info exists portinfo(depends_lib)]} {
177                set depends_lib $portinfo(depends_lib)
178        } else {
179                set depends_lib ""
180        }
181        if {[info exists portinfo(depends_run)]} {
182                set depends_run $portinfo(depends_run)
183        } else {
184                set depends_run ""
185        }
186        if {[info exists portinfo(platforms)]} {
187                set platforms $portinfo(platforms)
188        } else {
189                set platforms ""
190        }
191
192        puts $sqlfile_fd "INSERT INTO portfiles VALUES ('$portname', '$portdir', '$portversion', '$description')"
193
194        set primary 1
195        foreach category $categories {
196                set category [sql_escape $category]
197                puts $sqlfile_fd "INSERT INTO categories VALUES ('$portname', '$category', $primary)"
198                incr primary
199        }
200       
201        set primary 1
202        foreach maintainer $maintainers {
203                set maintainer [sql_escape $maintainer]
204                puts $sqlfile_fd "INSERT INTO maintainers VALUES ('$portname', '$maintainer', $primary)"
205                incr primary
206        }
207
208        foreach build_dep $depends_build {
209            set build_dep [sql_escape $build_dep]
210            puts $sqlfile_fd "INSERT INTO dependencies VALUES ('$portname', '$build_dep')"
211        }
212
213        foreach lib $depends_lib {
214                set lib [sql_escape $lib]
215                puts $sqlfile_fd "INSERT INTO dependencies VALUES ('$portname', '$lib')"
216        }
217
218        foreach run_dep $depends_run {
219            set run_dep [sql_escape $run_dep]
220            puts $sqlfile_fd "INSERT INTO dependencies VALUES ('$portname', '$run_dep')"
221        }
222
223        foreach variant $variants {
224                set variant [sql_escape $variant]
225                puts $sqlfile_fd "INSERT INTO variants VALUES ('$portname', '$variant')"
226        }
227
228        foreach platform $platforms {
229                set platform [sql_escape $platform]
230                puts $sqlfile_fd "INSERT INTO platforms VALUES ('$portname', '$platform')"
231        }
232
233}
234
235
236# Pipe the contents of the generated sql file to the database command,
237# reading from the file descriptor for the raw sql file to assure completeness.
238if {[catch {seek $sqlfile_fd 0 start} errstr]} {
239    ui_error "${::errorCode}: $errstr"
240    exit 1
241}
242if {[catch {exec $dbcmd $dbcmdargs <@ $sqlfile_fd} errstr]} {
243    ui_error "${::errorCode}: $errstr"
244    exit 1
245}
246
247
248# And we're done regen'ing the MacPorts dabase! (cleanup)
249close $sqlfile_fd
250file delete -force $sqlfile
Note: See TracBrowser for help on using the repository browser.