コード例 #1
0
ファイル: table_test.go プロジェクト: Hellblazer/cockroach
func TestCreateTable(t *testing.T) {
	defer leaktest.AfterTest(t)
	s, db := setup()
	defer s.Stop()

	if err := db.CreateNamespace("t"); err != nil {
		t.Fatal(err)
	}

	if _, err := db.DescribeTable("t.users"); !isError(err, "unable to find table") {
		t.Fatalf("expected failure, but found '%+v'", err)
	}

	schema := makeTestSchema("t.users")
	if err := db.CreateTable(schema); err != nil {
		t.Fatal(err)
	}

	// Table names are case-insensitive.
	schema2, err := db.DescribeTable("T.USERS")
	if err != nil {
		t.Fatal(err)
	}
	if !reflect.DeepEqual(schema, *schema2) {
		t.Errorf("expected %+v, but got %+v", schema, schema2)
	}

	// Creating the table again should fail as the table already exists.
	if err := db.CreateTable(schema); !isError(err, "table .* already exists") {
		t.Fatalf("expected failure, but found '%+v'", err)
	}

	// Verify we were allocated a non-reserved table ID. This involves manually
	// retrieving the descriptor. Don't do this at home kiddies.
	gr, err := db.Get(keys.MakeNameMetadataKey(0, "t"))
	if err != nil {
		t.Fatal(err)
	}
	gr, err = db.Get(keys.MakeNameMetadataKey(uint32(gr.ValueInt()), "users"))
	if err != nil {
		t.Fatal(err)
	}
	desc := structured.TableDescriptor{}
	if err := db.GetProto(gr.ValueBytes(), &desc); err != nil {
		t.Fatal(err)
	}
	if desc.ID <= structured.MaxReservedDescID {
		t.Errorf("expected a non-reserved table ID, but got %d", desc.ID)
	}
}
コード例 #2
0
ファイル: table.go プロジェクト: Hellblazer/cockroach
// RenameTable renames a table. Old path and new path have the form
// "<namespace>.<table>".
func (db *DB) RenameTable(oldPath, newPath string) error {
	// TODO(pmattis): Should we allow both the old and new name to exist
	// simultaneously for a period of time? The thought is to allow an
	// application to access the table via either name while the application is
	// being upgraded. Alternatively, instead of a rename table operation perhaps
	// there should be a link table operation which adds a "hard link" to the
	// table. Similar to a file, a table would not be removed until all of the
	// hard links are removed.

	oldNSID, oldName, err := db.lookupTable(oldPath)
	if err != nil {
		return err
	}
	newNSID, newName, err := db.lookupTable(newPath)
	if err != nil {
		return err
	}
	if newName == "" {
		return fmt.Errorf("empty table name: %s", newPath)
	}

	return db.Txn(func(txn *Txn) error {
		oldNameKey := keys.MakeNameMetadataKey(oldNSID, oldName)
		gr, err := txn.Get(oldNameKey)
		if err != nil {
			return err
		}
		if !gr.Exists() {
			return fmt.Errorf("unable to find table \"%s\"", oldPath)
		}
		descKey := gr.ValueBytes()
		desc := structured.TableDescriptor{}
		if err := txn.GetProto(descKey, &desc); err != nil {
			return err
		}
		desc.Name = strings.ToLower(newPath)
		if err := structured.ValidateTableDesc(desc); err != nil {
			return err
		}
		newNameKey := keys.MakeNameMetadataKey(newNSID, newName)
		b := &Batch{}
		b.Put(descKey, &desc)
		// If the new name already exists the conditional put will fail causing the
		// transaction to fail.
		b.CPut(newNameKey, descKey, nil)
		b.Del(oldNameKey)
		return txn.Commit(b)
	})
}
コード例 #3
0
ファイル: create.go プロジェクト: routhcr/cockroach
// CreateTable creates a table.
func (p *planner) CreateTable(n *parser.CreateTable) (planNode, error) {
	var err error
	n.Table, err = p.normalizeTableName(n.Table)
	if err != nil {
		return nil, err
	}

	dbDesc, err := p.getDatabaseDesc(n.Table.Database())
	if err != nil {
		return nil, err
	}

	desc, err := makeTableDesc(n)
	if err != nil {
		return nil, err
	}
	if err := desc.AllocateIDs(); err != nil {
		return nil, err
	}

	nameKey := keys.MakeNameMetadataKey(dbDesc.ID, n.Table.Table())
	if err := p.writeDescriptor(nameKey, &desc, n.IfNotExists); err != nil {
		return nil, err
	}
	return &valuesNode{}, nil
}
コード例 #4
0
ファイル: create.go プロジェクト: XisiHuang/cockroach
// CreateDatabase creates a database.
func (p *planner) CreateDatabase(n *parser.CreateDatabase) (planNode, error) {
	if n.Name == "" {
		return nil, errEmptyDatabaseName
	}

	nameKey := keys.MakeNameMetadataKey(structured.RootNamespaceID, strings.ToLower(string(n.Name)))
	if gr, err := p.db.Get(nameKey); err != nil {
		return nil, err
	} else if gr.Exists() {
		if n.IfNotExists {
			return &valuesNode{}, nil
		}
		return nil, fmt.Errorf("database \"%s\" already exists", n.Name)
	}
	ir, err := p.db.Inc(keys.DescIDGenerator, 1)
	if err != nil {
		return nil, err
	}
	nsID := uint32(ir.ValueInt() - 1)
	// TODO(pmattis): Need to handle if-not-exists here as well.
	if err := p.db.CPut(nameKey, nsID, nil); err != nil {
		return nil, err
	}
	return &valuesNode{}, nil
}
コード例 #5
0
ファイル: conn.go プロジェクト: MarkBruns/NNO.tw
func (c *conn) ShowTables(p *parser.ShowTables, args []driver.Value) (*rows, error) {
	if p.Name == "" {
		if c.database == "" {
			return nil, fmt.Errorf("no database specified")
		}
		p.Name = c.database
	}
	dbID, err := c.lookupDatabase(p.Name)
	if err != nil {
		return nil, err
	}
	prefix := keys.MakeNameMetadataKey(dbID, "")
	sr, err := c.db.Scan(prefix, prefix.PrefixEnd(), 0)
	if err != nil {
		return nil, err
	}
	names := make([]string, len(sr))
	for i, row := range sr {
		names[i] = string(bytes.TrimPrefix(row.Key, prefix))
	}
	return &rows{
		columns: []string{"tables"},
		rows:    names,
		pos:     -1,
	}, nil
}
コード例 #6
0
ファイル: conn.go プロジェクト: Jaekyun/cockroach
func (c *conn) getTableDesc(table *parser.TableName) (*structured.TableDescriptor, error) {
	if err := c.normalizeTableName(table); err != nil {
		return nil, err
	}
	dbID, err := c.lookupDatabase(table.Qualifier)
	if err != nil {
		return nil, err
	}
	gr, err := c.db.Get(keys.MakeNameMetadataKey(dbID, table.Name))
	if err != nil {
		return nil, err
	}
	if !gr.Exists() {
		return nil, fmt.Errorf("table \"%s\" does not exist", table)
	}
	descKey := gr.ValueBytes()
	desc := structured.TableDescriptor{}
	if err := c.db.GetProto(descKey, &desc); err != nil {
		return nil, err
	}
	if err := structured.ValidateTableDesc(desc); err != nil {
		return nil, err
	}
	return &desc, nil
}
コード例 #7
0
ファイル: table.go プロジェクト: Hellblazer/cockroach
// DeleteTable deletes the specified table. Path has the form
// "<namespace>.<table>".
func (db *DB) DeleteTable(path string) error {
	nsID, name, err := db.lookupTable(path)
	if err != nil {
		return err
	}
	if name == "" {
		return fmt.Errorf("empty table name: %s", path)
	}
	nameKey := keys.MakeNameMetadataKey(nsID, name)
	gr, err := db.Get(nameKey)
	if err != nil {
		return err
	}
	if !gr.Exists() {
		return fmt.Errorf("unable to find table \"%s\"", path)
	}
	descKey := gr.ValueBytes()
	desc := structured.TableDescriptor{}
	if err := db.GetProto(descKey, &desc); err != nil {
		return err
	}

	panic("TODO(pmattis): delete all of the tables rows")
	// return db.Del(descKey)
}
コード例 #8
0
ファイル: server.go プロジェクト: greener98103/cockroach
// CreateDatabase creates a database if it doesn't exist.
func (s *Server) CreateDatabase(session *Session, p *parser.CreateDatabase, args []sqlwire.Datum, resp *sqlwire.Response) {
	if p.Name == "" {
		resp.SetGoError(errors.New("empty database name"))
		return
	}

	nameKey := keys.MakeNameMetadataKey(structured.RootNamespaceID, strings.ToLower(p.Name))
	if gr, err := s.db.Get(nameKey); err != nil {
		resp.SetGoError(err)
		return
	} else if gr.Exists() {
		if p.IfNotExists {
			return
		}
		resp.SetGoError(fmt.Errorf("database \"%s\" already exists", p.Name))
		return
	}
	ir, err := s.db.Inc(keys.DescIDGenerator, 1)
	if err != nil {
		resp.SetGoError(err)
		return
	}
	nsID := uint32(ir.ValueInt() - 1)
	if err := s.db.CPut(nameKey, nsID, nil); err != nil {
		// TODO(pmattis): Need to handle if-not-exists here as well.
		resp.SetGoError(err)
		return
	}
}
コード例 #9
0
ファイル: server.go プロジェクト: zmoon111/cockroach
// ShowTables returns all the tables.
func (s *Server) ShowTables(session *Session, p *parser.ShowTables, args []sqlwire.Datum, resp *sqlwire.Response) error {
	if p.Name == nil {
		if session.Database == "" {
			return errNoDatabase
		}
		p.Name = append(p.Name, session.Database)
	}
	dbID, err := s.lookupDatabase(p.Name.String())
	if err != nil {
		return err
	}
	prefix := keys.MakeNameMetadataKey(dbID, "")
	sr, err := s.db.Scan(prefix, prefix.PrefixEnd(), 0)
	if err != nil {
		return err
	}
	var rows []sqlwire.Result_Row

	for _, row := range sr {
		name := string(bytes.TrimPrefix(row.Key, prefix))
		rows = append(rows, sqlwire.Result_Row{
			Values: []sqlwire.Datum{
				{StringVal: &name},
			},
		})
	}
	resp.Results = []sqlwire.Result{
		{
			Columns: []string{"tables"},
			Rows:    rows,
		},
	}
	return nil
}
コード例 #10
0
ファイル: server.go プロジェクト: zmoon111/cockroach
func (s *Server) getTableDesc(database string, qname parser.QualifiedName) (
	*structured.TableDescriptor, error) {
	var err error
	qname, err = s.normalizeTableName(database, qname)
	if err != nil {
		return nil, err
	}
	dbID, err := s.lookupDatabase(qname.Database())
	if err != nil {
		return nil, err
	}
	gr, err := s.db.Get(keys.MakeNameMetadataKey(dbID, qname.Table()))
	if err != nil {
		return nil, err
	}
	if !gr.Exists() {
		return nil, fmt.Errorf("table \"%s\" does not exist", qname)
	}
	descKey := gr.ValueBytes()
	desc := structured.TableDescriptor{}
	if err := s.db.GetProto(descKey, &desc); err != nil {
		return nil, err
	}
	if err := desc.Validate(); err != nil {
		return nil, err
	}
	return &desc, nil
}
コード例 #11
0
ファイル: table.go プロジェクト: Hellblazer/cockroach
func (db *DB) getTableDesc(path string) (*structured.TableDescriptor, error) {
	nsID, name, err := db.lookupTable(path)
	if err != nil {
		return nil, err
	}
	if name == "" {
		return nil, fmt.Errorf("empty table name: %s", path)
	}
	gr, err := db.Get(keys.MakeNameMetadataKey(nsID, name))
	if err != nil {
		return nil, err
	}
	if !gr.Exists() {
		return nil, fmt.Errorf("unable to find table \"%s\"", path)
	}
	descKey := gr.ValueBytes()
	desc := structured.TableDescriptor{}
	if err := db.GetProto(descKey, &desc); err != nil {
		return nil, err
	}
	if err := structured.ValidateTableDesc(desc); err != nil {
		return nil, err
	}
	return &desc, nil
}
コード例 #12
0
ファイル: conn.go プロジェクト: Jaekyun/cockroach
func (c *conn) CreateDatabase(p *parser.CreateDatabase, args []driver.Value) (*rows, error) {
	if p.Name == "" {
		return nil, fmt.Errorf("empty database name")
	}

	nameKey := keys.MakeNameMetadataKey(structured.RootNamespaceID, strings.ToLower(p.Name))
	if gr, err := c.db.Get(nameKey); err != nil {
		return nil, err
	} else if gr.Exists() {
		if p.IfNotExists {
			return &rows{}, nil
		}
		return nil, fmt.Errorf("database \"%s\" already exists", p.Name)
	}
	ir, err := c.db.Inc(keys.DescIDGenerator, 1)
	if err != nil {
		return nil, err
	}
	nsID := uint32(ir.ValueInt() - 1)
	if err := c.db.CPut(nameKey, nsID, nil); err != nil {
		// TODO(pmattis): Need to handle if-not-exists here as well.
		return nil, err
	}
	return &rows{}, nil
}
コード例 #13
0
ファイル: database.go プロジェクト: routhcr/cockroach
// getDatabaseDesc looks up the database descriptor given its name.
func (p *planner) getDatabaseDesc(name string) (*structured.DatabaseDescriptor, error) {
	nameKey := keys.MakeNameMetadataKey(structured.RootNamespaceID, name)
	desc := structured.DatabaseDescriptor{}
	if err := p.getDescriptor(nameKey, &desc); err != nil {
		return nil, err
	}
	return &desc, nil
}
コード例 #14
0
ファイル: create.go プロジェクト: XisiHuang/cockroach
// CreateTable creates a table.
func (p *planner) CreateTable(n *parser.CreateTable) (planNode, error) {
	var err error
	n.Table, err = p.normalizeTableName(n.Table)
	if err != nil {
		return nil, err
	}

	dbID, err := p.lookupDatabase(n.Table.Database())
	if err != nil {
		return nil, err
	}

	desc, err := makeTableDesc(n)
	if err != nil {
		return nil, err
	}
	if err := desc.AllocateIDs(); err != nil {
		return nil, err
	}

	nameKey := keys.MakeNameMetadataKey(dbID, n.Table.Table())

	// This isn't strictly necessary as the conditional put below will fail if
	// the key already exists, but it seems good to avoid the table ID allocation
	// in most cases when the table already exists.
	if gr, err := p.db.Get(nameKey); err != nil {
		return nil, err
	} else if gr.Exists() {
		if n.IfNotExists {
			return &valuesNode{}, nil
		}
		return nil, fmt.Errorf("table \"%s\" already exists", n.Table)
	}

	ir, err := p.db.Inc(keys.DescIDGenerator, 1)
	if err != nil {
		return nil, err
	}
	desc.ID = uint32(ir.ValueInt() - 1)

	// TODO(pmattis): Be cognizant of error messages when this is ported to the
	// server. The error currently returned below is likely going to be difficult
	// to interpret.
	// TODO(pmattis): Need to handle if-not-exists here as well.
	err = p.db.Txn(func(txn *client.Txn) error {
		descKey := keys.MakeDescMetadataKey(desc.ID)
		b := &client.Batch{}
		b.CPut(nameKey, descKey, nil)
		b.Put(descKey, &desc)
		return txn.Commit(b)
	})
	if err != nil {
		return nil, err
	}
	return &valuesNode{}, nil
}
コード例 #15
0
ファイル: conn.go プロジェクト: Jaekyun/cockroach
func (c *conn) lookupDatabase(name string) (uint32, error) {
	nameKey := keys.MakeNameMetadataKey(structured.RootNamespaceID, name)
	gr, err := c.db.Get(nameKey)
	if err != nil {
		return 0, err
	} else if !gr.Exists() {
		return 0, fmt.Errorf("database \"%s\" does not exist", name)
	}
	return uint32(gr.ValueInt()), nil
}
コード例 #16
0
ファイル: conn.go プロジェクト: Jaekyun/cockroach
func (c *conn) CreateTable(p *parser.CreateTable, args []driver.Value) (*rows, error) {
	if err := c.normalizeTableName(p.Table); err != nil {
		return nil, err
	}

	dbID, err := c.lookupDatabase(p.Table.Qualifier)
	if err != nil {
		return nil, err
	}

	schema, err := makeSchema(p)
	if err != nil {
		return nil, err
	}
	desc := structured.TableDescFromSchema(schema)
	if err := structured.ValidateTableDesc(desc); err != nil {
		return nil, err
	}

	nameKey := keys.MakeNameMetadataKey(dbID, p.Table.Name)

	// This isn't strictly necessary as the conditional put below will fail if
	// the key already exists, but it seems good to avoid the table ID allocation
	// in most cases when the table already exists.
	if gr, err := c.db.Get(nameKey); err != nil {
		return nil, err
	} else if gr.Exists() {
		if p.IfNotExists {
			return &rows{}, nil
		}
		return nil, fmt.Errorf("table \"%s\" already exists", p.Table)
	}

	ir, err := c.db.Inc(keys.DescIDGenerator, 1)
	if err != nil {
		return nil, err
	}
	desc.ID = uint32(ir.ValueInt() - 1)

	// TODO(pmattis): Be cognizant of error messages when this is ported to the
	// server. The error currently returned below is likely going to be difficult
	// to interpret.
	err = c.db.Txn(func(txn *client.Txn) error {
		descKey := keys.MakeDescMetadataKey(desc.ID)
		b := &client.Batch{}
		b.CPut(nameKey, descKey, nil)
		b.Put(descKey, &desc)
		return txn.Commit(b)
	})
	if err != nil {
		// TODO(pmattis): Need to handle if-not-exists here as well.
		return nil, err
	}
	return &rows{}, nil
}
コード例 #17
0
ファイル: table.go プロジェクト: Hellblazer/cockroach
// ListNamespaces lists the namespaces.
func (db *DB) ListNamespaces() ([]string, error) {
	prefix := keys.MakeNameMetadataKey(structured.RootNamespaceID, "")
	rows, err := db.Scan(prefix, prefix.PrefixEnd(), 0)
	if err != nil {
		return nil, err
	}
	names := make([]string, len(rows))
	for i, row := range rows {
		names[i] = string(bytes.TrimPrefix(row.Key, prefix))
	}
	return names, nil
}
コード例 #18
0
ファイル: conn.go プロジェクト: Jaekyun/cockroach
func (c *conn) ShowDatabases(p *parser.ShowDatabases, args []driver.Value) (*rows, error) {
	prefix := keys.MakeNameMetadataKey(structured.RootNamespaceID, "")
	sr, err := c.db.Scan(prefix, prefix.PrefixEnd(), 0)
	if err != nil {
		return nil, err
	}
	names := make([]string, len(sr))
	for i, row := range sr {
		names[i] = string(bytes.TrimPrefix(row.Key, prefix))
	}
	return newSingleColumnRows("database", names), nil
}
コード例 #19
0
ファイル: create.go プロジェクト: arypurnomoz/cockroach
// CreateDatabase creates a database.
func (p *planner) CreateDatabase(n *parser.CreateDatabase) (planNode, error) {
	if n.Name == "" {
		return nil, errEmptyDatabaseName
	}

	nameKey := keys.MakeNameMetadataKey(structured.RootNamespaceID, string(n.Name))
	desc := makeDatabaseDesc(n)

	if err := p.writeDescriptor(nameKey, &desc, n.IfNotExists); err != nil {
		return nil, err
	}
	return &valuesNode{}, nil
}
コード例 #20
0
ファイル: show.go プロジェクト: arypurnomoz/cockroach
// ShowDatabases returns all the databases.
func (p *planner) ShowDatabases(n *parser.ShowDatabases) (planNode, error) {
	prefix := keys.MakeNameMetadataKey(structured.RootNamespaceID, "")
	sr, err := p.db.Scan(prefix, prefix.PrefixEnd(), 0)
	if err != nil {
		return nil, err
	}
	v := &valuesNode{columns: []string{"Database"}}
	for _, row := range sr {
		name := string(bytes.TrimPrefix(row.Key, prefix))
		v.rows = append(v.rows, []parser.Datum{parser.DString(name)})
	}
	return v, nil
}
コード例 #21
0
ファイル: server.go プロジェクト: backend2use/cockroachdb
// CreateTable creates a table if it doesn't already exist.
func (s *Server) CreateTable(session *Session, p *parser.CreateTable, args []sqlwire.Datum, resp *sqlwire.Response) error {
	if err := s.normalizeTableName(session.Database, p.Table); err != nil {
		return err
	}

	dbID, err := s.lookupDatabase(p.Table.Qualifier)
	if err != nil {
		return err
	}

	desc, err := makeTableDesc(p)
	if err != nil {
		return err
	}
	if err := desc.AllocateIDs(); err != nil {
		return err
	}

	nameKey := keys.MakeNameMetadataKey(dbID, p.Table.Name)

	// This isn't strictly necessary as the conditional put below will fail if
	// the key already exists, but it seems good to avoid the table ID allocation
	// in most cases when the table already exists.
	if gr, err := s.db.Get(nameKey); err != nil {
		return err
	} else if gr.Exists() {
		if p.IfNotExists {
			return nil
		}
		return fmt.Errorf("table \"%s\" already exists", p.Table)
	}

	ir, err := s.db.Inc(keys.DescIDGenerator, 1)
	if err != nil {
		return err
	}
	desc.ID = uint32(ir.ValueInt() - 1)

	// TODO(pmattis): Be cognizant of error messages when this is ported to the
	// server. The error currently returned below is likely going to be difficult
	// to interpret.
	// TODO(pmattis): Need to handle if-not-exists here as well.
	return s.db.Txn(func(txn *client.Txn) error {
		descKey := keys.MakeDescMetadataKey(desc.ID)
		b := &client.Batch{}
		b.CPut(nameKey, descKey, nil)
		b.Put(descKey, &desc)
		return txn.Commit(b)
	})
}
コード例 #22
0
ファイル: table.go プロジェクト: Hellblazer/cockroach
func (db *DB) lookupTable(path string) (nsID uint32, name string, err error) {
	parts := strings.Split(strings.ToLower(path), ".")
	if len(parts) != 2 {
		return 0, "", fmt.Errorf("\"%s\" malformed, expected \"<namespace>.<table>\"", path)
	}
	nameKey := keys.MakeNameMetadataKey(nsID, parts[0])
	gr, err := db.Get(nameKey)
	if err != nil {
		return 0, "", err
	} else if !gr.Exists() {
		return 0, "", fmt.Errorf("namespace \"%s\" does not exist", parts[0])
	}
	nsID = uint32(gr.ValueInt())
	return nsID, parts[1], nil
}
コード例 #23
0
ファイル: table.go プロジェクト: Hellblazer/cockroach
// ListTables lists the tables in the specified namespace.
func (db *DB) ListTables(namespace string) ([]string, error) {
	nsID, _, err := db.lookupTable(namespace + ".")
	if err != nil {
		return nil, err
	}
	prefix := keys.MakeNameMetadataKey(nsID, "")
	rows, err := db.Scan(prefix, prefix.PrefixEnd(), 0)
	if err != nil {
		return nil, err
	}
	names := make([]string, len(rows))
	for i, row := range rows {
		names[i] = string(bytes.TrimPrefix(row.Key, prefix))
	}
	return names, nil
}
コード例 #24
0
ファイル: table.go プロジェクト: arypurnomoz/cockroach
func (p *planner) getTableDesc(qname *parser.QualifiedName) (
	*structured.TableDescriptor, error) {
	if err := p.normalizeTableName(qname); err != nil {
		return nil, err
	}
	dbDesc, err := p.getDatabaseDesc(qname.Database())
	if err != nil {
		return nil, err
	}

	nameKey := keys.MakeNameMetadataKey(dbDesc.ID, qname.Table())
	desc := structured.TableDescriptor{}
	if err := p.getDescriptor(nameKey, &desc); err != nil {
		return nil, err
	}
	return &desc, nil
}
コード例 #25
0
ファイル: table.go プロジェクト: Hellblazer/cockroach
// CreateNamespace creates a new namespace.
//
// TODO(pmattis): Is "namespace" the correct terminology? PostgreSQL and MySQL
// use "database". PostgreSQL also has the notion of a schema. A
// fully-qualified name in PostgreSQL looks like
// "<database>.<schema>.<table>". See
// http://www.postgresql.org/docs/9.4/static/ddl-schemas.html.
func (db *DB) CreateNamespace(name string) error {
	if name == "" {
		return fmt.Errorf("empty namespace name")
	}

	nameKey := keys.MakeNameMetadataKey(structured.RootNamespaceID, strings.ToLower(name))
	if gr, err := db.Get(nameKey); err != nil {
		return err
	} else if gr.Exists() {
		return fmt.Errorf("namespace \"%s\" already exists", name)
	}
	ir, err := db.Inc(keys.DescIDGenerator, 1)
	if err != nil {
		return err
	}
	nsID := uint32(ir.ValueInt() - 1)
	return db.CPut(nameKey, nsID, nil)
}
コード例 #26
0
ファイル: table.go プロジェクト: Hellblazer/cockroach
// CreateTable creates a table from the specified schema. Table creation will
// fail if the table name is already in use. The table name is required to have
// the form "<namespace>.<table>".
func (db *DB) CreateTable(schema structured.TableSchema) error {
	schema.Name = strings.ToLower(schema.Name)
	desc := structured.TableDescFromSchema(schema)
	if err := structured.ValidateTableDesc(desc); err != nil {
		return err
	}

	nsID, name, err := db.lookupTable(desc.Name)
	if err != nil {
		return err
	}
	if name == "" {
		return fmt.Errorf("empty table name: %s", desc.Name)
	}
	nameKey := keys.MakeNameMetadataKey(nsID, name)

	// This isn't strictly necessary as the conditional put below will fail if
	// the key already exists, but it seems good to avoid the table ID allocation
	// in most cases when the table already exists.
	if gr, err := db.Get(nameKey); err != nil {
		return err
	} else if gr.Exists() {
		return fmt.Errorf("table \"%s\" already exists", desc.Name)
	}

	ir, err := db.Inc(keys.DescIDGenerator, 1)
	if err != nil {
		return err
	}
	desc.ID = uint32(ir.ValueInt() - 1)

	// TODO(pmattis): Be cognizant of error messages when this is ported to the
	// server. The error currently returned below is likely going to be difficult
	// to interpret.
	return db.Txn(func(txn *Txn) error {
		descKey := keys.MakeDescMetadataKey(desc.ID)
		b := &Batch{}
		b.CPut(nameKey, descKey, nil)
		b.Put(descKey, &desc)
		return txn.Commit(b)
	})
}
コード例 #27
0
ファイル: server.go プロジェクト: zhaoyta/cockroach
// CreateDatabase creates a database if it doesn't exist.
func (s *Server) CreateDatabase(session *Session, p *parser.CreateDatabase, args []driver.Datum, resp *driver.Response) error {
	if p.Name == "" {
		return errEmptyDatabaseName
	}

	nameKey := keys.MakeNameMetadataKey(structured.RootNamespaceID, strings.ToLower(p.Name))
	if gr, err := s.db.Get(nameKey); err != nil {
		return err
	} else if gr.Exists() {
		if p.IfNotExists {
			return nil
		}
		return fmt.Errorf("database \"%s\" already exists", p.Name)
	}
	ir, err := s.db.Inc(keys.DescIDGenerator, 1)
	if err != nil {
		return err
	}
	nsID := uint32(ir.ValueInt() - 1)
	// TODO(pmattis): Need to handle if-not-exists here as well.
	return s.db.CPut(nameKey, nsID, nil)
}
コード例 #28
0
ファイル: show.go プロジェクト: arypurnomoz/cockroach
// ShowTables returns all the tables.
func (p *planner) ShowTables(n *parser.ShowTables) (planNode, error) {
	if n.Name == nil {
		if p.session.Database == "" {
			return nil, errNoDatabase
		}
		n.Name = &parser.QualifiedName{Base: parser.Name(p.session.Database)}
	}
	dbDesc, err := p.getDatabaseDesc(n.Name.String())
	if err != nil {
		return nil, err
	}
	prefix := keys.MakeNameMetadataKey(dbDesc.ID, "")
	sr, err := p.db.Scan(prefix, prefix.PrefixEnd(), 0)
	if err != nil {
		return nil, err
	}
	v := &valuesNode{columns: []string{"Table"}}
	for _, row := range sr {
		name := string(bytes.TrimPrefix(row.Key, prefix))
		v.rows = append(v.rows, []parser.Datum{parser.DString(name)})
	}
	return v, nil
}
コード例 #29
0
ファイル: server.go プロジェクト: zmoon111/cockroach
// ShowDatabases returns all the databases.
func (s *Server) ShowDatabases(session *Session, p *parser.ShowDatabases, args []sqlwire.Datum, resp *sqlwire.Response) error {
	prefix := keys.MakeNameMetadataKey(structured.RootNamespaceID, "")
	sr, err := s.db.Scan(prefix, prefix.PrefixEnd(), 0)
	if err != nil {
		return err
	}
	var rows []sqlwire.Result_Row
	for _, row := range sr {
		name := string(bytes.TrimPrefix(row.Key, prefix))
		rows = append(rows, sqlwire.Result_Row{
			Values: []sqlwire.Datum{
				{StringVal: &name},
			},
		})
	}
	resp.Results = []sqlwire.Result{
		{
			Columns: []string{"Database"},
			Rows:    rows,
		},
	}
	return nil
}
コード例 #30
0
ファイル: server.go プロジェクト: Gardenya/cockroach
// ShowTables returns all the tables.
func (s *Server) ShowTables(p *parser.ShowTables, args []sqlwire.Datum, resp *sqlwire.Response) {
	if p.Name == "" {
		if s.database == "" {
			resp.SetGoError(errors.New("no database specified"))
			return
		}
		p.Name = s.database
	}
	dbID, err := s.lookupDatabase(p.Name)
	if err != nil {
		resp.SetGoError(err)
		return
	}
	prefix := keys.MakeNameMetadataKey(dbID, "")
	sr, err := s.db.Scan(prefix, prefix.PrefixEnd(), 0)
	if err != nil {
		resp.SetGoError(err)
		return
	}
	var rows []sqlwire.Result_Row

	for _, row := range sr {
		name := string(bytes.TrimPrefix(row.Key, prefix))
		rows = append(rows, sqlwire.Result_Row{
			Values: []sqlwire.Datum{
				{StringVal: &name},
			},
		})
	}
	resp.Results = []sqlwire.Result{
		{
			Columns: []string{"tables"},
			Rows:    rows,
		},
	}
}