Project

General

Profile

1
#!/bin/bash -e
2
realpath () { readlink -f -- "$1"; }
3

    
4
include_guard_var () { realpath "$1"|sed 's/[^a-zA-Z0-9_]/_/g'; }
5

    
6
self_not_included () # usage: if self_not_included; then ... fi
7
{
8
	test "$#" -ge 1 || set -- "${BASH_SOURCE[1]}"
9
	local include_guard="$(include_guard_var "$1")"
10
	alias self_being_included=false
11
	test -z "${!include_guard+t}" && \
12
	{ eval "$include_guard"=1; alias self_being_included=true; }
13
}
14

    
15
# to load newly-defined aliases for use in functions in the same file:
16
## fi # load new aliases
17
## if self_being_included; then
18
# this is needed because aliases defined inside an if statement are not
19
# available inside that if statement
20

    
21
if self_not_included "${BASH_SOURCE[0]}"; then
22

    
23
shopt -s expand_aliases
24

    
25
set_var () { eval "$1"'="$2"'; }
26

    
27
join () { local IFS="$delim"; echo "$*"; } # usage: delim=... join elems...
28

    
29
reverse () # usage: array=($(reverse args...))
30
{
31
	local i
32
	for (( i=$#; i >= 1; i-- )); do printf '%q ' "${!i}"; done
33
}
34

    
35
: "${verbosity:=$verbose}" "${verbosity:=0}"
36

    
37
echo_cmd () { echo "$PS4$*" >&2; }
38

    
39
echo_run () { echo_cmd "$@"; "$@"; }
40

    
41
canon_rel_path ()
42
{
43
	local path="$1"
44
	path="$(realpath "$path")" # canonicalize
45
	path="${path#$(pwd -P)/}" # remove any shared prefix with the current dir
46
	echo "$path"
47
}
48

    
49
# usage: echo_func "$@"
50
echo_func ()
51
{
52
	local script="$(canon_rel_path "${BASH_SOURCE[1]}")"
53
	echo_cmd "$script:${BASH_LINENO[0]}" "${FUNCNAME[1]}" "$@"
54
}
55

    
56
echo_stdin () # usage: input|echo_stdin|cmd
57
{
58
	echo ----- >&2
59
	tee -a /dev/stderr;
60
	echo ----- >&2
61
}
62

    
63
echo_vars () { declare -p "${@%%=*}" >&2; } # usage: echo_vars var...
64

    
65
echo_export ()
66
{
67
	builtin export "$@"
68
	echo_vars "$@"
69
}
70

    
71
if test "$verbosity" -ge 2; then
72
	alias export="echo_export" # automatically echo env vars when they are set
73
fi
74

    
75
usage () { echo "Usage: $1" >&2; (exit 2); }
76

    
77
top_dir="$(dirname "$0")" # outermost script
78

    
79
run_args_cmd () # runs the command line args command
80
{
81
	test "$?" -eq 0 || return
82
	eval set -- "$(reverse "${BASH_ARGV[@]}")"
83
	test "$#" -ge 1 || set -- all
84
	echo_cmd "$(canon_rel_path "$0")" "$@"; "$@"
85
}
86

    
87
fwd () # usage: subdirs=(...); fwd "$FUNCNAME" "$@"
88
{
89
	echo_func "$@"
90
	: "${subdirs?}"
91
	
92
	for subdir in "${subdirs[@]}"; do
93
		"$(dirname "${BASH_SOURCE[1]}")"/"$subdir"/run "$@"
94
	done
95
}
96

    
97
make ()
98
{
99
	echo_func "$@"
100
	echo_run env make --directory="$top_dir" "$@"
101
}
102

    
103
if false; then ## usage:
104
inline_make 3<<'EOF'
105
target:
106
	$(self_dir)/cmd >$@
107
EOF
108
# target will be run automatically because it's first in the makefile
109
fi ##
110
inline_make ()
111
{
112
	echo_func "$@"
113
	local self="$(readlink -f "${BASH_SOURCE[1]}")"
114
	local self_dir="$(dirname "$self")"
115
	export self self_dir
116
	
117
	make --makefile=<((
118
		cat /dev/fd/3
119
		echo -n "
120
.SUFFIXES: # turn off built-in suffix rules
121
.SECONDARY: # don't automatically delete intermediate files
122
.DELETE_ON_ERROR: # delete target if recipe fails
123
"
124
	)|echo_stdin) "$@"
125
}
126

    
127
alias zip="echo_run zip"
128
alias unzip="echo_run unzip"
129
alias zip_newer="zip -u"
130
alias unzip_newer="unzip -u -o" # -o is safe b/c -u only extracts newer files
131

    
132
#### databases
133

    
134
quote='"'
135

    
136
esc_name () { echo "$quote${1//$quote/$quote$quote}$quote"; }
137

    
138
mk_esc_name () { set_var "$1"_esc "$(esc_name "${!1}")"; }
139

    
140
alias mk_schema_esc="local schema_esc; mk_esc_name schema"
141
alias mk_table_esc="local table_esc; mk_esc_name table"
142

    
143
fi # load new aliases
144
if self_being_included; then
145

    
146
log_sql () { test "$verbosity" -ge 2; }
147

    
148
### MySQL
149

    
150
mysql ()
151
{
152
	echo_func "$@"
153
	echo_run env mysql --verbose "$@"
154
}
155

    
156
mysql_ANSI ()
157
{
158
	echo_func "$@"
159
	(echo "SET sql_mode = 'ANSI';"; cat)|mysql "$@"
160
}
161

    
162
### PostgreSQL
163

    
164
pg_copy_to ()
165
{
166
	echo_func "$@"
167
	if test -z "$source"; then
168
		: "${table:?}"; mk_table_esc
169
		if test -z "$limit"; then local source="$table_esc"
170
		else local source="(SELECT * FROM $table_esc LIMIT $limit)"
171
		fi
172
	fi
173
	local pg_copy_format="${pg_copy_format-CSV HEADER}"
174
	
175
	psql "$@" <<<"COPY $source TO STDOUT $pg_copy_format;"
176
}
177

    
178
pg_header ()
179
{
180
	echo_func "$@"
181
	local pg_copy_format="CSV HEADER" limit=0
182
	pg_copy_to "$@"|echo_stdin
183
}
184

    
185
pg_export_table_no_header ()
186
{
187
	echo_func "$@"
188
	local pg_copy_format="CSV"
189
	pg_copy_to "$@"
190
}
191

    
192
pg_export_table_to_dir_no_header ()
193
{
194
	echo_func "$@"
195
	local table="$1"; shift; mk_table_esc
196
	local cols="$(pg_header)"
197
	pg_export_table_no_header "$@" >"$exports_dir/$table.no_header.cols=$cols.csv"
198
}
199

    
200
fi
(45-45/50)