mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
strings: replace_each([]); orm: update
This commit is contained in:
parent
4e69c40e12
commit
cdfbb2978d
@ -190,6 +190,101 @@ pub fn (s string) replace(rep, with string) string {
|
|||||||
return tos(b, new_len)
|
return tos(b, new_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RepIndex {
|
||||||
|
idx int
|
||||||
|
val_idx int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (a mut []RepIndex) sort() {
|
||||||
|
a.sort_with_compare(compare_rep_index)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
/*
|
||||||
|
fn (a RepIndex) < (b RepIndex) bool {
|
||||||
|
return a.idx < b.idx
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
fn compare_rep_index(a, b &RepIndex) int {
|
||||||
|
if a.idx < b.idx {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
if a.idx > b.idx {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn (s string) replace_each(vals []string) string {
|
||||||
|
if s.len == 0 || vals.len == 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
if vals.len % 2 != 0 {
|
||||||
|
println('string.replace_many(): odd number of strings')
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
// `rep` - string to replace
|
||||||
|
// `with` - string to replace with
|
||||||
|
// Remember positions of all rep strings, and calculate the length
|
||||||
|
// of the new string to do just one allocation.
|
||||||
|
mut new_len := s.len
|
||||||
|
mut idxs := []RepIndex
|
||||||
|
mut idx := 0
|
||||||
|
for rep_i := 0; rep_i < vals.len; rep_i+=2 {
|
||||||
|
// vals: ['rep1, 'with1', 'rep2', 'with2']
|
||||||
|
rep := vals[rep_i]
|
||||||
|
with := vals[rep_i+1]
|
||||||
|
for {
|
||||||
|
idx = s.index_after(rep, idx)
|
||||||
|
if idx == -1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// We need to remember both the position in the string,
|
||||||
|
// and which rep/with pair it refers to.
|
||||||
|
idxs << RepIndex{idx, rep_i}
|
||||||
|
idx++
|
||||||
|
new_len += with.len - rep.len
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Dont change the string if there's nothing to replace
|
||||||
|
if idxs.len == 0 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
idxs.sort()
|
||||||
|
mut b := malloc(new_len + 1)// add a \0 just in case
|
||||||
|
// Fill the new string
|
||||||
|
mut idx_pos := 0
|
||||||
|
mut cur_idx := idxs[idx_pos]
|
||||||
|
mut b_i := 0
|
||||||
|
for i := 0; i < s.len; i++ {
|
||||||
|
// Reached the location of rep, replace it with "with"
|
||||||
|
if i == cur_idx.idx {
|
||||||
|
rep := vals[cur_idx.val_idx]
|
||||||
|
with := vals[cur_idx.val_idx+1]
|
||||||
|
for j := 0; j < with.len; j++ {
|
||||||
|
b[b_i] = with[j]
|
||||||
|
b_i++
|
||||||
|
}
|
||||||
|
// Skip the length of rep, since we just replaced it with "with"
|
||||||
|
i += rep.len - 1
|
||||||
|
// Go to the next index
|
||||||
|
idx_pos++
|
||||||
|
if idx_pos < idxs.len {
|
||||||
|
cur_idx = idxs[idx_pos]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Rep doesnt start here, just copy
|
||||||
|
else {
|
||||||
|
b[b_i] = s[i]
|
||||||
|
b_i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b[new_len] = `\0`
|
||||||
|
return tos(b, new_len)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (s string) bool() bool {
|
pub fn (s string) bool() bool {
|
||||||
return s == 'true' || s == 't' // TODO t for pg, remove
|
return s == 'true' || s == 't' // TODO t for pg, remove
|
||||||
}
|
}
|
||||||
|
@ -219,6 +219,22 @@ fn test_replace() {
|
|||||||
assert c.replace('','-') == c
|
assert c.replace('','-') == c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_replace_each() {
|
||||||
|
s := 'hello man man :)'
|
||||||
|
q := s.replace_each([
|
||||||
|
'man', 'dude',
|
||||||
|
'hello', 'hey'
|
||||||
|
])
|
||||||
|
assert q == 'hey dude dude :)'
|
||||||
|
bb := '[b]bold[/b] [code]code[/code]'
|
||||||
|
assert bb.replace_each([
|
||||||
|
'[b]', '<b>',
|
||||||
|
'[/b]', '</b>',
|
||||||
|
'[code]', '<code>',
|
||||||
|
'[/code]', '</code>'
|
||||||
|
]) == '<b>bold</b> <code>code</code>'
|
||||||
|
}
|
||||||
|
|
||||||
fn test_itoa() {
|
fn test_itoa() {
|
||||||
num := 777
|
num := 777
|
||||||
assert num.str() == '777'
|
assert num.str() == '777'
|
||||||
|
@ -1764,7 +1764,11 @@ fn (p mut Parser) var_expr(v Var) string {
|
|||||||
name := p.tokens[p.token_idx].lit
|
name := p.tokens[p.token_idx].lit
|
||||||
if !name.contains('exec') && !name.starts_with('q_') {
|
if !name.contains('exec') && !name.starts_with('q_') {
|
||||||
p.next()
|
p.next()
|
||||||
p.insert_query(fn_ph)
|
if name == 'insert' {
|
||||||
|
p.insert_query(fn_ph)
|
||||||
|
} else if name == 'update' {
|
||||||
|
p.update_query(fn_ph)
|
||||||
|
}
|
||||||
return 'void'
|
return 'void'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,3 +245,63 @@ fn (p mut Parser) insert_query(fn_ph int) {
|
|||||||
0, params, 0, 0, 0)')
|
0, params, 0, 0, 0)')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `db.update User set nr_orders=nr_orders+1`
|
||||||
|
fn (p mut Parser) update_query(fn_ph int) {
|
||||||
|
println('update query')
|
||||||
|
p.check_name()
|
||||||
|
table_name := p.check_name()
|
||||||
|
typ := p.table.find_type(table_name)
|
||||||
|
if typ.name == '' {
|
||||||
|
p.error('unknown type `$table_name`')
|
||||||
|
}
|
||||||
|
set := p.check_name()
|
||||||
|
if set != 'set' {
|
||||||
|
p.error('expected `set`')
|
||||||
|
}
|
||||||
|
if typ.fields.len == 0 {
|
||||||
|
p.error('V orm: update: empty fields in `$typ.name`')
|
||||||
|
}
|
||||||
|
if typ.fields[0].name != 'id' {
|
||||||
|
p.error('V orm: `id int` must be the first field in `$typ.name`')
|
||||||
|
}
|
||||||
|
field := p.check_name()
|
||||||
|
p.check(.assign)
|
||||||
|
for f in typ.fields {
|
||||||
|
if !(f.typ in ['string', 'int', 'bool']) {
|
||||||
|
println('orm: skipping $f.name')
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
p.register_var({ f | is_mut: true, is_used:true, is_changed:true })
|
||||||
|
}
|
||||||
|
mut q := 'update ${typ.name}s set $field='
|
||||||
|
p.is_sql = true
|
||||||
|
set_typ, expr := p.tmp_expr()
|
||||||
|
p.is_sql = false
|
||||||
|
// TODO this hack should not be necessary
|
||||||
|
if set_typ == 'bool' {
|
||||||
|
if expr.trim_space() == '1' {
|
||||||
|
q += 'true'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
q += 'false'
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
q += expr
|
||||||
|
}
|
||||||
|
// where
|
||||||
|
if p.tok == .name && p.lit == 'where' {
|
||||||
|
p.next()
|
||||||
|
p.is_sql = true
|
||||||
|
_, wexpr := p.tmp_expr()
|
||||||
|
p.is_sql = false
|
||||||
|
q += ' where ' + wexpr
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nr_vals := 0
|
||||||
|
p.cgen.insert_before('char* params[$nr_vals];')// + params)
|
||||||
|
p.cgen.set_placeholder(fn_ph, 'PQexecParams( ')
|
||||||
|
println('update q="$q"')
|
||||||
|
p.genln('.conn, "$q", $nr_vals, 0, params, 0, 0, 0)')
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -196,6 +196,7 @@ pub fn run<T>(app mut T, port int) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
// Call the right action
|
// Call the right action
|
||||||
|
println('action=$action')
|
||||||
app.$action() or {
|
app.$action() or {
|
||||||
conn.write(HTTP_404) or {}
|
conn.write(HTTP_404) or {}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user