feat: complete shared database tenant sharding
This commit is contained in:
@@ -24,8 +24,8 @@ func TestEnsureIMGroupBusinessTablesUsesSelectedTenantDatabase(t *testing.T) {
|
||||
if err := ensureIMGroupBusinessTables(exec); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(exec.statements) != 25 {
|
||||
t.Fatalf("executed %d group schema statements, want 25", len(exec.statements))
|
||||
if len(exec.statements) != 22 {
|
||||
t.Fatalf("executed %d group schema statements, want 22", len(exec.statements))
|
||||
}
|
||||
for _, statement := range exec.statements {
|
||||
if strings.Contains(strings.ToLower(statement), "tinode.") || strings.Contains(strings.ToLower(statement), "create database") {
|
||||
@@ -36,6 +36,9 @@ func TestEnsureIMGroupBusinessTablesUsesSelectedTenantDatabase(t *testing.T) {
|
||||
if strings.Contains(joined, "im_group_events_outbox") {
|
||||
t.Fatal("group event outbox table must not be created")
|
||||
}
|
||||
if strings.Contains(joined, "im_group_idempotency") {
|
||||
t.Fatal("group idempotency table must not be created")
|
||||
}
|
||||
for _, expected := range []string{
|
||||
"primary key(id), unique index uk_im_group_settings_topic(topic)",
|
||||
"primary key(id), unique index uk_im_group_announcement_reads_announcement_user(announcement_id, user_id)",
|
||||
@@ -48,11 +51,17 @@ func TestEnsureIMGroupBusinessTablesUsesSelectedTenantDatabase(t *testing.T) {
|
||||
if !strings.Contains(joined, "json_set(public, '$.fn'") {
|
||||
t.Fatal("group schema is missing historical public.fn backfill")
|
||||
}
|
||||
for _, expected := range []string{"im_group_message_shards", "im_group_message_topic_shards", "im_group_message_dedup", "primary key(message_id)"} {
|
||||
for _, expected := range []string{"im_group_message_shards", "primary key(message_id)"} {
|
||||
if !strings.Contains(joined, expected) {
|
||||
t.Fatalf("group shard schema is missing %q", expected)
|
||||
}
|
||||
}
|
||||
if strings.Contains(joined, "im_group_message_topic_shards") {
|
||||
t.Fatal("group message topic shard routes must not be created in MySQL")
|
||||
}
|
||||
if strings.Contains(joined, "im_group_message_dedup") {
|
||||
t.Fatal("group message dedup table must not be created")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGroupMessageShardTableRejectsUnsafeMonth(t *testing.T) {
|
||||
@@ -71,11 +80,15 @@ func TestTenantPartitionTableNames(t *testing.T) {
|
||||
tenantID types.TenantID
|
||||
friends string
|
||||
messages string
|
||||
topics string
|
||||
members string
|
||||
subs string
|
||||
notices string
|
||||
group string
|
||||
}{
|
||||
{tenantID: 1, friends: "im_001_friendships", messages: "im_001_messages", group: "im_001_group_messages_202609"},
|
||||
{tenantID: 10, friends: "im_010_friendships", messages: "im_010_messages", group: "im_010_group_messages_202609"},
|
||||
{tenantID: 1000, friends: "im_1000_friendships", messages: "im_1000_messages", group: "im_1000_group_messages_202609"},
|
||||
{tenantID: 1, friends: "im_001_friendships", messages: "im_001_messages", topics: "im_001_topics", members: "im_001_group_members", subs: "im_001_subscriptions", notices: "im_001_system_notifications", group: "im_001_group_messages_202609"},
|
||||
{tenantID: 10, friends: "im_010_friendships", messages: "im_010_messages", topics: "im_010_topics", members: "im_010_group_members", subs: "im_010_subscriptions", notices: "im_010_system_notifications", group: "im_010_group_messages_202609"},
|
||||
{tenantID: 1000, friends: "im_1000_friendships", messages: "im_1000_messages", topics: "im_1000_topics", members: "im_1000_group_members", subs: "im_1000_subscriptions", notices: "im_1000_system_notifications", group: "im_1000_group_messages_202609"},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
if got := tenantFriendshipsTable(tc.tenantID); got != tc.friends {
|
||||
@@ -84,8 +97,34 @@ func TestTenantPartitionTableNames(t *testing.T) {
|
||||
if got := tenantMessagesTable(tc.tenantID); got != tc.messages {
|
||||
t.Fatalf("tenant %d message table: got %q, want %q", tc.tenantID, got, tc.messages)
|
||||
}
|
||||
if got := tenantTopicsTable(tc.tenantID); got != tc.topics {
|
||||
t.Fatalf("tenant %d topics table: got %q, want %q", tc.tenantID, got, tc.topics)
|
||||
}
|
||||
if got := tenantGroupMembersTable(tc.tenantID); got != tc.members {
|
||||
t.Fatalf("tenant %d group members table: got %q, want %q", tc.tenantID, got, tc.members)
|
||||
}
|
||||
if got := tenantSubscriptionsTable(tc.tenantID); got != tc.subs {
|
||||
t.Fatalf("tenant %d subscriptions table: got %q, want %q", tc.tenantID, got, tc.subs)
|
||||
}
|
||||
if got := tenantSystemNotificationsTable(tc.tenantID); got != tc.notices {
|
||||
t.Fatalf("tenant %d system notifications table: got %q, want %q", tc.tenantID, got, tc.notices)
|
||||
}
|
||||
if got, ok := tenantGroupMessagesTable(tc.tenantID, "202609"); !ok || got != tc.group {
|
||||
t.Fatalf("tenant %d group message table: got %q, ok=%v, want %q", tc.tenantID, got, ok, tc.group)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTenantShardSQL(t *testing.T) {
|
||||
query := tenantShardSQL(7, "SELECT * FROM im_topics t JOIN im_group_members gm ON gm.topic=t.name JOIN im_subscriptions s ON s.topic=gm.topic; INSERT INTO im_system_notifications(event_id) VALUES(?)")
|
||||
for _, expected := range []string{"im_007_topics", "im_007_group_members", "im_007_subscriptions", "im_007_system_notifications"} {
|
||||
if !strings.Contains(query, expected) {
|
||||
t.Fatalf("tenant shard query is missing %q: %s", expected, query)
|
||||
}
|
||||
}
|
||||
for _, legacy := range []string{" im_topics", " im_group_members", " im_subscriptions", " im_system_notifications"} {
|
||||
if strings.Contains(query, legacy) {
|
||||
t.Fatalf("tenant shard query still references %q: %s", legacy, query)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user