Пример #1
0
func TestResultTypes(t *testing.T) {
	conn, err := aspect.Connect("sqlite3", ":memory:")
	require.Nil(t, err, "Failed to connect to in-memory sqlite3 instance")
	defer conn.Close()

	// Create the users table
	_, err = conn.Execute(users.Create())
	require.Nil(t, err, "Failed to create users table")

	admin := embedUser{
		id:       id{ID: 1},
		fullname: fullname{Name: "admin"},
		Password: "******",
	}
	_, err = conn.Execute(users.Insert().Values(admin))
	require.Nil(t, err, "Inserting a single user should not error")

	// Tagless destination
	var untagged tagless
	conn.MustQueryOne(
		aspect.Select(users.C["id"], users.C["name"]).Limit(1),
		&untagged,
	)
	assert.EqualValues(t, 1, untagged.ID)
	assert.Equal(t, "admin", untagged.Name)

	var untaggeds []tagless
	conn.MustQueryAll(
		aspect.Select(users.C["id"], users.C["name"]),
		&untaggeds,
	)
	require.Equal(t, 1, len(untaggeds))
	assert.EqualValues(t, 1, untaggeds[0].ID)
	assert.Equal(t, "admin", untaggeds[0].Name)

	// Tagless insert - number of columns must match numebr of exported fields
	noTag := fullTagless{
		ID:   2,
		Name: "tagless",
		// Password is a blank string
	}
	_, err = conn.Execute(users.Insert().Values(noTag))
	require.Nil(t, err, "Inserting a single tagless user should not error")

	// Embedded destination
	var embed embedUser
	conn.MustQueryOne(
		users.Select().Where(users.C["id"].Equals(1)).Limit(1),
		&embed,
	)
	assert.EqualValues(t, 1, embed.id.ID)
	assert.Equal(t, "admin", embed.fullname.Name)
	assert.Equal(t, "secret", embed.Password)
}
Пример #2
0
// Connect to an in-memory sqlite3 instance and execute some statements.
func TestConnect(t *testing.T) {
	assert := assert.New(t)

	conn, err := aspect.Connect("sqlite3", ":memory:")
	require.Nil(t, err, "Failed to connect to in-memory sqlite3 instance")
	defer conn.Close()

	// Create the users table
	_, err = conn.Execute(users.Create())
	require.Nil(t, err, "Failed to create users table")

	// Insert a user
	admin := user{
		ID:       1,
		Name:     "admin",
		Password: "******",
	}
	_, err = conn.Execute(users.Insert().Values(admin))
	require.Nil(t, err, "Inserting a single user should not error")

	// Insert multiple users
	clients := []user{
		user{ID: 2, Name: "client1"},
		user{ID: 3, Name: "client2"},
	}
	_, err = conn.Execute(users.Insert().Values(clients))
	require.Nil(t, err, "Inserting multiple users should not error")

	// Select a user - Query must be given a pointer
	var u user
	require.Nil(t, conn.QueryOne(users.Select(), &u))
	assert.Equal(admin.ID, u.ID)
	assert.Equal(admin.Name, u.Name)
	assert.Equal(admin.Password, u.Password)

	// Select an incomplete, embedded struct
	var embed embedded
	require.Nil(t, conn.QueryOne(users.Select(), &embed))
	assert.Equal(admin.ID, embed.id.ID)
	assert.Equal(admin.Name, embed.Name)

	// Select a wrapped struct
	var wrap wrapped
	require.Nil(t, conn.QueryOne(users.Select(), &wrap))
	assert.Equal(admin.ID, wrap.user.ID)
	assert.Equal(admin.Name, wrap.user.Name)
	assert.Equal(admin.Password, wrap.user.Password)
	assert.EqualValues(0, wrap.ID)

	// Select multiple users
	var us []user
	require.Nil(t, conn.QueryAll(users.Select().OrderBy(users.C["id"]), &us))
	require.Equal(t, 3, len(us))
	assert.Equal(admin.ID, us[0].ID)
	assert.Equal(admin.Name, us[0].Name)
	assert.Equal(admin.Password, us[0].Password)

	// Select multiple users with embedding
	var embeds []embedded
	require.Nil(t,
		conn.QueryAll(users.Select().OrderBy(users.C["id"]), &embeds),
	)
	require.Equal(t, 3, len(us))
	assert.Equal(admin.ID, embeds[0].id.ID)
	assert.Equal(admin.Name, embeds[0].Name)

	// Select multiple embedded users into a slice that is pre-populated
	embeds = []embedded{
		{Name: "a"},
		{Name: "b"},
		{Name: "c"},
	}
	require.Nil(t, conn.QueryAll(
		aspect.Select(users.C["id"]).OrderBy(users.C["id"]), &embeds,
	))
	require.Equal(t, 3, len(us))
	assert.EqualValues(1, embeds[0].id.ID)
	assert.Equal("a", embeds[0].Name)

	// Drop the table
	_, err = conn.Execute(users.Drop())
	assert.Nil(err, "Dropping the users table should not fail")
}
Пример #3
0
func TestSelect(t *testing.T) {
	// Connect to the database specified in the test db.json config
	// Default to the Travis CI settings if no file is found
	conn, tx := dbtest.WithConfig(t, "./db.json")

	// Perform all tests in a transaction and always rollback
	defer conn.Close()
	defer tx.Rollback()

	_, err := tx.Execute(users.Create())
	require.Nil(t, err)

	// Insert users as values or pointers
	admin := user{Name: "admin", IsActive: true}
	stmt := aspect.Insert(
		users.C["name"],
		users.C["password"],
		users.C["is_active"],
	)
	_, err = tx.Execute(stmt.Values(admin))
	require.Nil(t, err)

	_, err = tx.Execute(stmt.Values(&admin))
	require.Nil(t, err)

	var u user
	require.Nil(t, tx.QueryOne(users.Select(), &u))
	assert.Equal(t, "admin", u.Name)
	assert.True(t, u.IsActive)

	// Select using a returning clause
	client := user{Name: "client", Password: "******", IsActive: false}
	returningStmt := Insert(
		users.C["name"],
		users.C["password"],
		users.C["is_active"],
	).Returning(
		users.C["id"],
		users.C["created_at"],
	)
	require.Nil(t, tx.QueryOne(returningStmt.Values(client), &client))

	// The ID and time should be anything but zero
	assert.NotEqual(t, int64(0), client.ID)
	assert.False(t, client.CreatedAt.IsZero())

	// Select into a struct that has extra columns
	// TODO Skip unexported fields
	var extraField testUser
	require.Nil(t, tx.QueryOne(users.Select().Where(users.C["name"].Equals("client")), &extraField))
	assert.Equal(t, "client", extraField.Name)
	assert.False(t, extraField.IsActive)

	// Query multiple users
	var extraFields []testUser
	assert.Nil(t, tx.QueryAll(users.Select(), &extraFields))
	assert.Equal(t, 3, len(extraFields))

	// Query ids directly
	var ids []int64
	orderBy := aspect.Select(users.C["id"]).OrderBy(users.C["id"].Desc())
	assert.Nil(t, tx.QueryAll(orderBy, &ids))
	assert.Equal(t, 3, len(ids))
	var prev int64
	for _, id := range ids {
		if prev != 0 {
			if prev < id {
				t.Errorf("id results returned out of order")
			}
		}
	}

	// Scan into a Values map - all fields should be returned
	selectByName := users.Select().OrderBy(users.C["name"])
	values := aspect.Values{}
	assert.Nil(t, tx.QueryOne(selectByName, values))
	assert.Equal(t, 5, len(values))
	assert.NotEqual(t, int64(0), values["id"])
	assert.Equal(t, []byte("admin"), values["name"]) // Yup, strings are []byte
	assert.EqualValues(t, true, values["is_active"])
	assert.Equal(t, []byte{}, values["password"])

	// Scan into a slice of Values maps
	var allValues []aspect.Values
	assert.Nil(t, tx.QueryAll(selectByName, &allValues))
	assert.Equal(t, 3, len(allValues))

	values = allValues[2]
	assert.Equal(t, 5, len(values))
	assert.NotEqual(t, int64(0), values["id"])
	assert.Equal(t, []byte("client"), values["name"])
	assert.EqualValues(t, false, values["is_active"])
	assert.Equal(t, []byte("1234"), values["password"])

	// TODO Test duplicate names in a table join

	// TODO destination types that don't match the result

	// Update
	// ------

	updateStmt := users.Update().Values(
		aspect.Values{"name": "HELLO", "password": "******"},
	).Where(
		users.C["id"].Equals(client.ID),
	)
	result, err := tx.Execute(updateStmt)
	require.Nil(t, err)

	rowsAffected, err := result.RowsAffected()
	assert.Nil(t, err)
	assert.EqualValues(t, 1, rowsAffected)

	// Delete
	// ------

	result, err = tx.Execute(users.Delete())
	require.Nil(t, err)

	rowsAffected, err = result.RowsAffected()
	assert.Nil(t, err)
	assert.EqualValues(t, 3, rowsAffected)
}