1
- from pgcli .packages .parseutils .meta import FunctionMetadata , ForeignKey
2
- from prompt_toolkit .completion import Completion
3
1
from functools import partial
4
2
from itertools import product
3
+ from pgcli .packages .parseutils .meta import FunctionMetadata , ForeignKey
4
+ from prompt_toolkit .completion import Completion
5
5
from prompt_toolkit .document import Document
6
6
from mock import Mock
7
7
import pytest
8
8
9
- escape = lambda name : ('"' + name + '"' if not name .islower () or name in (
10
- 'select' , 'insert' ) else name )
11
-
12
9
parametrize = pytest .mark .parametrize
10
+
13
11
qual = ['if_more_than_one_table' , 'always' ]
14
12
no_qual = ['if_more_than_one_table' , 'never' ]
15
13
14
+
15
+ def escape (name ):
16
+ if not name .islower () or name in ('select' , 'insert' ):
17
+ return '"' + name + '"'
18
+ return name
19
+
20
+
16
21
def completion (display_meta , text , pos = 0 ):
17
22
return Completion (text , start_position = pos , display_meta = display_meta )
18
23
24
+
19
25
def get_result (completer , text , position = None ):
20
26
position = len (text ) if position is None else position
21
27
return completer .get_completions (
22
28
Document (text = text , cursor_position = position ), Mock ()
23
29
)
24
30
31
+
25
32
def result_set (completer , text , position = None ):
26
33
return set (get_result (completer , text , position ))
27
34
@@ -30,14 +37,23 @@ def result_set(completer, text, position=None):
30
37
# def schema(text, pos=0):
31
38
# return completion('schema', text, pos)
32
39
# and so on
33
- schema , table , view , function , column , keyword , datatype , alias , name_join ,\
34
- fk_join , join = [partial (completion , display_meta )
35
- for display_meta in ('schema' , 'table' , 'view' , 'function' , 'column' ,
36
- 'keyword' , 'datatype' , 'table alias' , 'name join' , 'fk join' , 'join' )]
40
+ schema = partial (completion , 'schema' )
41
+ table = partial (completion , 'table' )
42
+ view = partial (completion , 'view' )
43
+ function = partial (completion , 'function' )
44
+ column = partial (completion , 'column' )
45
+ keyword = partial (completion , 'keyword' )
46
+ datatype = partial (completion , 'datatype' )
47
+ alias = partial (completion , 'table alias' )
48
+ name_join = partial (completion , 'name join' )
49
+ fk_join = partial (completion , 'fk join' )
50
+ join = partial (completion , 'join' )
51
+
37
52
38
53
def wildcard_expansion (cols , pos = - 1 ):
39
- return Completion (cols , start_position = pos , display_meta = 'columns' ,
40
- display = '*' )
54
+ return Completion (
55
+ cols , start_position = pos , display_meta = 'columns' , display = '*' )
56
+
41
57
42
58
class MetaData (object ):
43
59
def __init__ (self , metadata ):
@@ -52,97 +68,103 @@ def builtin_datatypes(self, pos=0):
52
68
def keywords (self , pos = 0 ):
53
69
return [keyword (kw , pos ) for kw in self .completer .keywords ]
54
70
55
- def columns (self , parent , schema = 'public' , typ = 'tables' , pos = 0 ):
71
+ def columns (self , tbl , parent = 'public' , typ = 'tables' , pos = 0 ):
56
72
if typ == 'functions' :
57
- fun = [x for x in self .metadata [typ ][schema ] if x [0 ] == parent ][0 ]
73
+ fun = [x for x in self .metadata [typ ][parent ] if x [0 ] == tbl ][0 ]
58
74
cols = fun [1 ]
59
75
else :
60
- cols = self .metadata [typ ][schema ][ parent ]
76
+ cols = self .metadata [typ ][parent ][ tbl ]
61
77
return [column (escape (col ), pos ) for col in cols ]
62
78
63
- def datatypes (self , schema = 'public' , pos = 0 ):
64
- return [datatype (escape (x ), pos )
65
- for x in self .metadata .get ('datatypes' , {}).get (schema , [])]
79
+ def datatypes (self , parent = 'public' , pos = 0 ):
80
+ return [
81
+ datatype (escape (x ), pos )
82
+ for x in self .metadata .get ('datatypes' , {}).get (parent , [])]
66
83
67
- def tables (self , schema = 'public' , pos = 0 ):
68
- return [table (escape (x ), pos )
69
- for x in self .metadata .get ('tables' , {}).get (schema , [])]
84
+ def tables (self , parent = 'public' , pos = 0 ):
85
+ return [
86
+ table (escape (x ), pos )
87
+ for x in self .metadata .get ('tables' , {}).get (parent , [])]
70
88
71
- def views (self , schema = 'public' , pos = 0 ):
72
- return [view (escape (x ), pos )
73
- for x in self .metadata .get ('views' , {}).get (schema , [])]
89
+ def views (self , parent = 'public' , pos = 0 ):
90
+ return [
91
+ view (escape (x ), pos )
92
+ for x in self .metadata .get ('views' , {}).get (parent , [])]
74
93
75
- def functions (self , schema = 'public' , pos = 0 ):
76
- return [function (escape (x [0 ] + '()' ), pos )
77
- for x in self .metadata .get ('functions' , {}).get (schema , [])]
94
+ def functions (self , parent = 'public' , pos = 0 ):
95
+ return [
96
+ function (escape (x [0 ] + '()' ), pos )
97
+ for x in self .metadata .get ('functions' , {}).get (parent , [])]
78
98
79
99
def schemas (self , pos = 0 ):
80
100
schemas = set (sch for schs in self .metadata .values () for sch in schs )
81
101
return [schema (escape (s ), pos = pos ) for s in schemas ]
82
102
83
- def functions_and_keywords (self , schema = 'public' , pos = 0 ):
103
+ def functions_and_keywords (self , parent = 'public' , pos = 0 ):
84
104
return (
85
- self .functions (schema , pos ) + self .builtin_functions (pos ) +
105
+ self .functions (parent , pos ) + self .builtin_functions (pos ) +
86
106
self .keywords (pos )
87
107
)
88
108
89
109
# Note that the filtering parameters here only apply to the columns
90
- def columns_functions_and_keywords (self , parent , schema = 'public' , typ = 'tables' , pos = 0 ):
110
+ def columns_functions_and_keywords (
111
+ self , tbl , parent = 'public' , typ = 'tables' , pos = 0
112
+ ):
91
113
return (
92
114
self .functions_and_keywords (pos = pos ) +
93
- self .columns (parent , schema , typ , pos )
115
+ self .columns (tbl , parent , typ , pos )
94
116
)
95
117
96
- def from_clause_items (self , schema = 'public' , pos = 0 ):
118
+ def from_clause_items (self , parent = 'public' , pos = 0 ):
97
119
return (
98
- self .functions (schema , pos ) + self .views (schema , pos ) +
99
- self .tables (schema , pos )
120
+ self .functions (parent , pos ) + self .views (parent , pos ) +
121
+ self .tables (parent , pos )
100
122
)
101
123
102
- def schemas_and_from_clause_items (self , schema = 'public' , pos = 0 ):
103
- return self .from_clause_items (schema , pos ) + self .schemas (pos )
124
+ def schemas_and_from_clause_items (self , parent = 'public' , pos = 0 ):
125
+ return self .from_clause_items (parent , pos ) + self .schemas (pos )
104
126
105
- def types (self , schema = 'public' , pos = 0 ):
106
- return self .datatypes (schema , pos ) + self .tables (schema , pos )
127
+ def types (self , parent = 'public' , pos = 0 ):
128
+ return self .datatypes (parent , pos ) + self .tables (parent , pos )
107
129
108
130
@property
109
131
def completer (self ):
110
132
return self .get_completer ()
111
133
112
134
def get_completers (self , casing ):
113
- '''
114
- Returns a function taking three bools `casing`, `filtr`, `alias ` and
135
+ """
136
+ Returns a function taking three bools `casing`, `filtr`, `aliasing ` and
115
137
the list `qualify`, all defaulting to None.
116
138
Returns a list of completers.
117
139
These parameters specify the allowed values for the corresponding
118
140
completer parameters, `None` meaning any, i.e. (None, None, None, None)
119
141
results in all 24 possible completers, whereas e.g.
120
- (True, False, True, ['never']) results in the one completer with casing,
121
- without `search_path` filtering of objects, with table aliasing, and
122
- without column qualification.
123
- '''
124
- def _cfg (_casing , filtr , alias , qualify ):
125
- cfg = {'settings' :{}}
142
+ (True, False, True, ['never']) results in the one completer with
143
+ casing, without `search_path` filtering of objects, with table
144
+ aliasing, and without column qualification.
145
+ """
146
+ def _cfg (_casing , filtr , aliasing , qualify ):
147
+ cfg = {'settings' : {}}
126
148
if _casing :
127
149
cfg ['casing' ] = casing
128
150
cfg ['settings' ]['search_path_filter' ] = filtr
129
- cfg ['settings' ]['generate_aliases' ] = alias
151
+ cfg ['settings' ]['generate_aliases' ] = aliasing
130
152
cfg ['settings' ]['qualify_columns' ] = qualify
131
153
return cfg
132
154
133
- def _cfgs (casing , filtr , alias , qualify ):
155
+ def _cfgs (casing , filtr , aliasing , qualify ):
134
156
casings = [True , False ] if casing is None else [casing ]
135
157
filtrs = [True , False ] if filtr is None else [filtr ]
136
- aliases = [True , False ] if alias is None else [alias ]
158
+ aliases = [True , False ] if aliasing is None else [aliasing ]
137
159
qualifys = qualify or ['always' , 'if_more_than_one_table' , 'never' ]
138
160
return [
139
161
_cfg (* p ) for p in product (casings , filtrs , aliases , qualifys )
140
162
]
141
163
142
- def completers (casing = None , filtr = None , alias = None , qualify = None ):
164
+ def completers (casing = None , filtr = None , aliasing = None , qualify = None ):
143
165
get_comp = self .get_completer
144
166
return [
145
- get_comp (** c ) for c in _cfgs (casing , filtr , alias , qualify )
167
+ get_comp (** c ) for c in _cfgs (casing , filtr , aliasing , qualify )
146
168
]
147
169
148
170
return completers
@@ -154,29 +176,32 @@ def get_completer(self, settings=None, casing=None):
154
176
155
177
schemata , tables , tbl_cols , views , view_cols = [], [], [], [], []
156
178
157
- for schema , tbls in metadata ['tables' ].items ():
158
- schemata .append (schema )
179
+ for sch , tbls in metadata ['tables' ].items ():
180
+ schemata .append (sch )
159
181
160
- for table , cols in tbls .items ():
161
- tables .append ((schema , table ))
182
+ for tbl , cols in tbls .items ():
183
+ tables .append ((sch , tbl ))
162
184
# Let all columns be text columns
163
- tbl_cols .extend ([(schema , table , col , 'text' ) for col in cols ])
185
+ tbl_cols .extend ([(sch , tbl , col , 'text' ) for col in cols ])
164
186
165
- for schema , tbls in metadata .get ('views' , {}).items ():
166
- for view , cols in tbls .items ():
167
- views .append ((schema , view ))
187
+ for sch , tbls in metadata .get ('views' , {}).items ():
188
+ for tbl , cols in tbls .items ():
189
+ views .append ((sch , tbl ))
168
190
# Let all columns be text columns
169
- view_cols .extend ([(schema , view , col , 'text' ) for col in cols ])
191
+ view_cols .extend ([(sch , tbl , col , 'text' ) for col in cols ])
170
192
171
- functions = [FunctionMetadata (schema , * func_meta )
172
- for schema , funcs in metadata ['functions' ].items ()
173
- for func_meta in funcs ]
193
+ functions = [
194
+ FunctionMetadata (sch , * func_meta )
195
+ for sch , funcs in metadata ['functions' ].items ()
196
+ for func_meta in funcs ]
174
197
175
- datatypes = [(schema , datatype )
176
- for schema , datatypes in metadata ['datatypes' ].items ()
177
- for datatype in datatypes ]
198
+ datatypes = [
199
+ (sch , typ )
200
+ for sch , datatypes in metadata ['datatypes' ].items ()
201
+ for typ in datatypes ]
178
202
179
- foreignkeys = [ForeignKey (* fk ) for fks in metadata ['foreignkeys' ].values ()
203
+ foreignkeys = [
204
+ ForeignKey (* fk ) for fks in metadata ['foreignkeys' ].values ()
180
205
for fk in fks ]
181
206
182
207
comp .extend_schemata (schemata )
0 commit comments