// Shorten returns new short links. func Shorten(ctx context.Context, params []*ReqParams) ([]*CustomURL, error) { c, err := conf.FromContext(ctx) if err != nil { return nil, err } u, err := auth.ExtractUser(ctx) if err != nil { return nil, err } // check URLs pack size n := len(params) if n > c.Settings.MaxPack { return nil, fmt.Errorf("too big ReqParams pack size [%v]", n) } s, err := db.CtxSession(ctx) if err != nil { return nil, err } // prepare coll, err := db.Coll(s, "urls") if err != nil { return nil, err } now := time.Now().UTC() err = db.LockURL(s) if err != nil { return nil, err } defer db.UnlockURL(s) num, err := getMax(coll) if err != nil { return nil, err } documents := make([]interface{}, n) cus := make([]*CustomURL, n) for i, param := range params { num++ cus[i] = &CustomURL{ ID: num, Group: param.Group, Tag: param.Tag, Original: param.Original, User: u.Name, TTL: param.TTL, NotDirect: param.NotDirect, Created: now, Modified: now, Cb: param.Cb, API: param.IsAPI, } documents[i] = cus[i] } err = coll.Insert(documents...) if err != nil { return nil, err } return cus, nil }
// Import imports short URLs. func Import(ctx context.Context, links map[string]*ReqParams) ([]ChangeResult, error) { var result []ChangeResult c, err := conf.FromContext(ctx) if err != nil { return nil, err } u, err := auth.ExtractUser(ctx) if err != nil { return nil, err } n := len(links) if n > c.Settings.MaxPack { return nil, fmt.Errorf("too big pack size [%v]", n) } s, err := db.CtxSession(ctx) if err != nil { return nil, err } // prepare coll, err := db.Coll(s, "urls") if err != nil { return nil, err } now := time.Now().UTC() for short, param := range links { num, err := Decode(short) if err != nil { result = append(result, ChangeResult{Err: "invalid short URL value"}) continue } cu := &CustomURL{ ID: num, Group: param.Group, Tag: param.Tag, Original: param.Original, User: u.Name, TTL: param.TTL, NotDirect: param.NotDirect, Created: now, Modified: now, Cb: param.Cb, API: param.IsAPI, } // a locking of every insert is not fast // but the pack doesn't lock other operations. err = db.LockURL(s) if err != nil { return nil, err } errIns := coll.Insert(cu) err = db.UnlockURL(s) if err != nil { return nil, err } if errIns != nil { msg := "internal error" if mgo.IsDup(errIns) { msg = "duplicate item" } result = append(result, ChangeResult{Err: msg}) continue } result = append(result, ChangeResult{Cu: cu}) } return result, nil }