コード例 #1
0
ファイル: parser.go プロジェクト: forndb/bytengine
// grant/deny user database access parser
func (p *Parser) parseUserDatabaseAccessCmd(ctx string) {
	_token := p.expect(itemString, ctx)
	_user, err := formatString(_token.val)
	if err != nil {
		p.errorf("Improperly quoted username in %s", ctx)
	}
	_token = p.expect(itemString, ctx)
	_db, err2 := formatString(_token.val)
	if err2 != nil {
		p.errorf("Improperly quoted database in %s", ctx)
	}
	_token = p.expect(itemIdentifier, ctx)
	_grant := false
	switch _token.val {
	case "grant":
		_grant = true
	case "deny":
		// do nothing _grant already false
		break
	default:
		p.errorf("Invalid indentifier "+_token.val+" in %s", ctx)
	}
	_filter := p.parseEndofCommand(ctx)
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: true,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Args["username"] = _user
	cmd.Args["database"] = _db
	cmd.Args["grant"] = _grant
	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #2
0
ファイル: parser.go プロジェクト: forndb/bytengine
// list directory contents parser
func (p *Parser) parseListDirectoryCmd(db, ctx string) {
	_token := p.expect(itemPath, ctx)
	_path := _token.val
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = db
	cmd.Args["path"] = _path

	// parse arguments
	ac := newOptList()
	ac.Add("regex", optString)
	p.parseOptions(ctx, ac)
	// get arguments
	arg := ac.Get("regex")
	if arg != nil {
		cmd.Options["regex"] = arg
	}

	_filter := p.parseEndofCommand(ctx)
	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #3
0
ファイル: parser.go プロジェクト: forndb/bytengine
// initialize bytengine parser
func (p *Parser) parseServerInitCmd(ctx string) {
	_filter := p.parseEndofCommand(ctx)
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: true,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #4
0
ファイル: parser.go プロジェクト: forndb/bytengine
// read file JSON content parser
func (p *Parser) parseReadFileCmd(db, ctx string) {
	_token := p.expect(itemPath, ctx)
	_path := _token.val
	// check if we have an array of fields to return
	_list := []string{}
	if p.peek().typ == itemLeftBracket {
		// parse array and make sure all elements are strings
		// absorb left bracket
		p.next()
		// check type of next token
	Loop:
		for {
			switch p.peek().typ {
			case itemString:
				_next := p.next()
				_val, err := formatString(_next.val)
				if err != nil {
					p.errorf("Improperly quoted string value in %s Array definition.", ctx)
				}
				_list = append(_list, _val)
				continue
			case itemComma:
				// absorb comma
				p.next()
				if p.peek().typ == itemRightBracket {
					p.errorf("Trailing comma ',' in %s Array definition.", ctx)
				}
				continue
			case itemRightBracket:
				// absorb
				p.next()
				break Loop
			default:
				p.errorf("Invalid value: "+p.peek().val+" in %s Array definition.", ctx)
			}
		}
	}

	_filter := p.parseEndofCommand(ctx)
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = db
	cmd.Args["path"] = _path
	cmd.Args["fields"] = _list
	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #5
0
ファイル: parser.go プロジェクト: forndb/bytengine
// delete file bytes parser
func (p *Parser) parseDeleteAttachmentCmd(db, ctx string) {
	_token := p.expect(itemPath, ctx)
	_path := _token.val
	_filter := p.parseEndofCommand(ctx)
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = db
	cmd.Args["path"] = _path
	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #6
0
ファイル: parser.go プロジェクト: forndb/bytengine
// delete user parser
func (p *Parser) parseDropUserCmd(ctx string) {
	_token := p.expect(itemString, ctx)
	_user, err := formatString(_token.val)
	if err != nil {
		p.errorf("Improperly quoted username in %s", ctx)
	}
	_filter := p.parseEndofCommand(ctx)
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: true,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Args["username"] = _user
	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #7
0
ファイル: parser.go プロジェクト: forndb/bytengine
// rename file/directory parser
func (p *Parser) parseRenameContentCmd(db, ctx string) {
	_token := p.expect(itemPath, ctx)
	_path := _token.val
	_token = p.expect(itemString, ctx)
	_name, err := formatString(_token.val)
	if err != nil {
		p.errorf("Improperly quoted new name in %s", ctx)
	}
	_filter := p.parseEndofCommand(ctx)
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = db
	cmd.Args["path"] = _path
	cmd.Args["name"] = _name
	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #8
0
ファイル: bytengine.go プロジェクト: johnwilson/bytengine
func getUploadTicketHandler(ctx *gin.Context) {
	var form struct {
		Token    string `form:"token" binding:"required"`
		Database string `form:"database" binding:"required"`
		Path     string `form:"path" binding:"required"`
	}
	ok := ctx.Bind(&form)
	if ok != nil {
		data := errorResponse(errors.New("Missing parameters"))
		ctx.Data(400, "application/json", data)
		return
	}

	cmd := bytengine.Command{
		Name:    "uploadticket",
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = form.Database
	cmd.Args["path"] = form.Path

	duration := Configuration.Timeout.UploadTicket // in minutes
	cmd.Args["duration"] = duration

	req := EngineRequest{
		Token:        form.Token,
		Command:      &cmd,
		ResponseChan: make(chan EngineResponse),
	}
	EngineRequestChan <- &req
	rep := <-req.ResponseChan
	if rep.Error != nil {
		data := errorResponse(rep.Error)
		ctx.Data(400, "application/json", data)
		return
	}

	ctx.Data(200, "application/json", okResponse(rep.Response))
}
コード例 #9
0
ファイル: parser.go プロジェクト: forndb/bytengine
// list users parser
func (p *Parser) parseListUsersCmd(ctx string) {
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: true,

		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{})} // check if regex option has been added

	// parse arguments
	ac := newOptList()
	ac.Add("regex", optString)
	p.parseOptions(ctx, ac)
	// get arguments
	arg := ac.Get("regex")
	if arg != nil {
		cmd.Options["regex"] = arg
	}

	_filter := p.parseEndofCommand(ctx)
	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #10
0
ファイル: bytengine.go プロジェクト: johnwilson/bytengine
func downloadFileHandler(ctx *gin.Context) {
	var form struct {
		Token    string `form:"token" binding:"required"`
		Database string `form:"database" binding:"required"`
		Path     string `form:"path" binding:"required"`
	}
	ok := ctx.Bind(&form)
	if ok != nil {
		data := errorResponse(errors.New("Missing parameters"))
		ctx.Data(400, "application/json", data)
		return
	}

	cmd := bytengine.Command{
		Name:    "readbytes",
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = form.Database
	cmd.Args["path"] = form.Path
	cmd.Args["writer"] = ctx.Writer

	ctx.Writer.Header().Set("Content-Type", "application/octet-stream")
	req := EngineRequest{
		Token:        form.Token,
		Command:      &cmd,
		ResponseChan: make(chan EngineResponse),
	}
	EngineRequestChan <- &req
	rep := <-req.ResponseChan
	if rep.Error != nil {
		data := errorResponse(rep.Error)
		ctx.String(400, string(data))
		return
	}
}
コード例 #11
0
ファイル: parser.go プロジェクト: forndb/bytengine
// overwrite file JSON parser
func (p *Parser) parseModifyFileCmd(db, ctx string) {
	_token := p.expect(itemPath, ctx)
	_path := _token.val

	// check if next item is a json object
	var _json interface{}
	if p.peek().typ == itemLeftBrace {
		_json = p.parseJSON(ctx)
	} else {
		p.errorf("Expecting a JSON object in %s", ctx)
	}
	_filter := p.parseEndofCommand(ctx)
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = db
	cmd.Args["path"] = _path
	cmd.Args["data"] = _json
	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #12
0
ファイル: parser.go プロジェクト: forndb/bytengine
// copy file/directory parser
func (p *Parser) parseCopyContentCmd(db, ctx string) {
	_token := p.expect(itemPath, ctx)
	_path := _token.val
	_token = p.expect(itemPath, ctx)
	_path2 := _token.val
	_rename := ""
	if p.peek().typ == itemString {
		_nxt := p.next()
		_rename = _nxt.val
	}
	_filter := p.parseEndofCommand(ctx)
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = db
	cmd.Args["path"] = _path
	cmd.Args["to"] = _path2
	cmd.Args["rename"] = _rename
	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #13
0
ファイル: parser.go プロジェクト: forndb/bytengine
// select query statement parser
func (p *Parser) parseSelectCmd(db, ctx string) {
	_fields := []string{}
	// get fields
	for p.peek().typ == itemString {
		_token := p.next()
		_field, err := formatString(_token.val)
		if err != nil {
			p.errorf("Improperly quoted field name in %s", ctx)
		}
		_fields = append(_fields, FieldPrefix+_field)
		continue
	}
	// get directories
	_in := p.expect(itemIdentifier, ctx)
	if strings.ToLower(_in.val) != "in" {
		p.errorf("Invalid %s, expecting 'In statement'.", ctx)
	}
	_paths := []string{}
	for p.peek().typ == itemPath {
		_path := p.next().val
		_paths = append(_paths, _path)
		continue
	}
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = db
	cmd.Args["fields"] = _fields
	cmd.Args["dirs"] = _paths
	var _filter string

	// get optional identifiers
Loop:
	for {
		switch _token := p.next(); {
		case _token.typ == itemIdentifier && strings.ToLower(_token.val) == "where":
			_where := p.parseWhereCmd()
			cmd.Args["where"] = _where
			continue
		case _token.typ == itemIdentifier && strings.ToLower(_token.val) == "sort":
			cmd.Args["sort"] = p.parseSortCmd()
			continue
		case _token.typ == itemIdentifier && strings.ToLower(_token.val) == "limit":
			// add to select statement
			cmd.Args["limit"] = p.parseLimitCmd()
			continue
		case _token.typ == itemIdentifier && strings.ToLower(_token.val) == "distinct":
			// add to select statement
			cmd.Args["distinct"] = p.parseDistinctCmd()
			continue
		case _token.typ == itemIdentifier && strings.ToLower(_token.val) == "count":
			cmd.Args["count"] = true
			continue
		case _token.typ == itemSendTo:
			p.backup()
			_filter = p.parseEndofCommand(ctx)
			break Loop
		case _token.typ == itemSemiColon:
			break Loop
		case _token.typ == itemEOF:
			p.backup()
			break Loop
		default:
			p.errorf("Invalid identifier "+_token.val+" in %s", ctx)
		}
	}

	// validate select statement
	_, hascount := cmd.Args["count"]
	_, haslimit := cmd.Args["limit"]
	_, hassort := cmd.Args["sort"]
	_, hasdistinct := cmd.Args["distinct"]

	if haslimit || hassort {
		if hascount {
			p.errorf("'Count' cannot be used with 'Limit' or 'Sort' in %s", ctx)
		}
		if hasdistinct {
			p.errorf("'Distinct' cannot be used with 'Limit' or 'Sort' in %s", ctx)
		}
	} else if hasdistinct {
		if haslimit {
			p.errorf("'Limit' cannot be used with 'Distinct' in %s", ctx)
		}
		if hassort {
			p.errorf("'Sort' cannot be used with 'Distinct' in %s", ctx)
		}
		if hascount {
			p.errorf("'Count' cannot be used with 'Distinct' in %s", ctx)
		}
	} else if hascount {
		if haslimit {
			p.errorf("'Limit' cannot be used with 'Count' in %s", ctx)
		}
		if hassort {
			p.errorf("'Sort' cannot be used with 'Count' in %s", ctx)
		}
		if hasdistinct {
			p.errorf("'Distinct' cannot be used with 'Count' in %s", ctx)
		}
	}

	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #14
0
ファイル: parser.go プロジェクト: forndb/bytengine
// increment/decrement/list counter parser
func (p *Parser) parseCounterCmd(db, ctx string) {
	_token := p.expectOneOf(itemString, itemIdentifier, ctx)
	if _token.typ == itemIdentifier {
		if _token.val == "list" {
			cmd := bytengine.Command{
				Name:    ctx,
				IsAdmin: false,
				Args:    make(map[string]interface{}),
				Options: make(map[string]interface{}),
			}
			cmd.Database = db
			cmd.Args["action"] = "list"

			// parse arguments
			ac := newOptList()
			ac.Add("regex", optString)
			p.parseOptions(ctx, ac)
			// get arguments
			arg := ac.Get("regex")
			if arg != nil {
				cmd.Options["regex"] = arg
			}

			_filter := p.parseEndofCommand(ctx)
			cmd.Filter = _filter
			p.commands = append(p.commands, cmd)
			return

		} else {
			p.errorf("Invalid identifier %s in %s", _token.val, ctx)
		}
	}

	_counter, err := formatString(_token.val)
	if err != nil {
		p.errorf("Improperly quoted counter name in %s", ctx)
	}
	_token = p.expect(itemIdentifier, ctx)
	_action := ""
	switch _token.val {
	case "incr":
		fallthrough
	case "decr":
		fallthrough
	case "reset":
		_action = _token.val
	default:
		p.errorf("Invalid indentifier "+_token.val+" in %s", ctx)
	}

	_token = p.expect(itemNumber, ctx)
	_val, err := strconv.ParseInt(_token.val, 10, 64) // base 10 64bit integer
	if err != nil {
		p.errorf("Invalid numerical value in %s", ctx)
	}

	_filter := p.parseEndofCommand(ctx)
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = db
	cmd.Args["name"] = _counter
	cmd.Args["action"] = _action
	cmd.Args["value"] = _val
	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #15
0
ファイル: parser.go プロジェクト: forndb/bytengine
// unset query statement parser
func (p *Parser) parseUnsetCmd(db, ctx string) {
	_fields := map[string]interface{}{}
	// get fields
	for p.peek().typ == itemString {
		_token := p.next()
		_field, err := formatString(_token.val)
		if err != nil {
			p.errorf("Improperly quoted field name in %s", ctx)
		}
		_field = FieldPrefix + _field
		_fields[_field] = 1
		continue
	}
	if len(_fields) < 1 {
		p.errorf("Invalid %s: no fields found", ctx)
	}

	// get directories
	_in := p.expect(itemIdentifier, ctx)
	if strings.ToLower(_in.val) != "in" {
		p.errorf("Invalid %s, expecting 'In statement'.", ctx)
	}
	_paths := []string{}
	for p.peek().typ == itemPath {
		_path := p.next().val
		_paths = append(_paths, _path)
		continue
	}
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = db
	cmd.Args["fields"] = _fields
	cmd.Args["dirs"] = _paths
	var _filter string

	// get optional identifiers
Loop2:
	for {
		switch _token := p.next(); {
		case _token.typ == itemIdentifier && strings.ToLower(_token.val) == "where":
			_where := p.parseWhereCmd()
			cmd.Args["where"] = _where
			continue
		case _token.typ == itemSendTo:
			p.backup()
			_filter = p.parseEndofCommand(ctx)
			break Loop2
		case _token.typ == itemSemiColon:
			break Loop2
		case _token.typ == itemEOF:
			// do not consume eof
			p.backup()
			break Loop2
		default:
			p.errorf("Invalid identifier "+_token.val+" in %s", ctx)
		}
	}

	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}
コード例 #16
0
ファイル: parser.go プロジェクト: forndb/bytengine
// set query statement parser
func (p *Parser) parseSetCmd(db, ctx string) {
	_fields := map[string]interface{}{}
	_incr := map[string]interface{}{}

	// get field assignment list
Loop:
	for {
		switch i := p.next(); i.typ {
		case itemString:
			switch p.peek().typ {
			case itemEqual:
				p.backup2(i)
				f, v := p.parseValueAssignment()
				_fields[f] = v
				continue
			case itemPlusEqual:
				fallthrough
			case itemMinusEqual:
				p.backup2(i)
				f, v := p.parseIncrDecrValue()
				_incr[f] = v
				continue
			default:
				p.errorf("Invalid assingment operator in %s", ctx)
			}

		default:
			p.backup()
			break Loop
		}
	}
	if len(_fields) < 1 && len(_incr) < 1 {
		p.errorf("Invalid %s: no field assignments found", ctx)
	}

	// get directories
	_in := p.expect(itemIdentifier, ctx)
	if strings.ToLower(_in.val) != "in" {
		p.errorf("Invalid %s, expecting 'In statement'.", ctx)
	}
	_paths := []string{}
	for p.peek().typ == itemPath {
		_path := p.next().val
		_paths = append(_paths, _path)
		continue
	}
	cmd := bytengine.Command{
		Name:    ctx,
		IsAdmin: false,
		Args:    make(map[string]interface{}),
		Options: make(map[string]interface{}),
	}
	cmd.Database = db
	cmd.Args["fields"] = _fields
	if len(_incr) > 0 {
		cmd.Args["incr"] = _incr
	}
	cmd.Args["dirs"] = _paths
	var _filter string

	// get optional identifiers
Loop2:
	for {
		switch _token := p.next(); {
		case _token.typ == itemIdentifier && strings.ToLower(_token.val) == "where":
			_where := p.parseWhereCmd()
			cmd.Args["where"] = _where
			continue
		case _token.typ == itemSendTo:
			p.backup()
			_filter = p.parseEndofCommand(ctx)
			break Loop2
		case _token.typ == itemSemiColon:
			break Loop2
		case _token.typ == itemEOF:
			// do not consume eof
			p.backup()
			break Loop2
		default:
			p.errorf("Invalid identifier "+_token.val+" in %s", ctx)
		}
	}

	cmd.Filter = _filter
	p.commands = append(p.commands, cmd)
}