1+ /*
2+ * Licensed to the Apache Software Foundation (ASF) under one
3+ * or more contributor license agreements. See the NOTICE file
4+ * distributed with this work for additional information
5+ * regarding copyright ownership. The ASF licenses this file
6+ * to you under the Apache License, Version 2.0 (the
7+ * "License"); you may not use this file except in compliance
8+ * with the License. You may obtain a copy of the License at
9+ *
10+ * http://www.apache.org/licenses/LICENSE-2.0
11+ *
12+ * Unless required by applicable law or agreed to in writing, software
13+ * distributed under the License is distributed on an "AS IS" BASIS,
14+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+ * See the License for the specific language governing permissions and
16+ * limitations under the License.
17+ */
18+
19+ package gocql_test
20+
21+ import (
22+ "context"
23+ "fmt"
24+ "log"
25+
26+ gocql "github.com/apache/cassandra-gocql-driver/v2"
27+ )
28+
29+ // Example_setKeyspace demonstrates the SetKeyspace method that allows
30+ // specifying keyspace per query, available with Protocol 5+ (Cassandra 4.0+).
31+ //
32+ // This example shows the complete keyspace precedence hierarchy:
33+ // 1. Keyspace in CQL query string (keyspace.table) - HIGHEST precedence
34+ // 2. SetKeyspace() method - MIDDLE precedence
35+ // 3. Default session keyspace - LOWEST precedence
36+ func Example_setKeyspace () {
37+ /* The example assumes the following CQL was used to setup the keyspaces:
38+ create keyspace example with replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };
39+ create keyspace example2 with replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };
40+ create keyspace example3 with replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };
41+ create table example.users(id int, name text, PRIMARY KEY(id));
42+ create table example2.users(id int, name text, PRIMARY KEY(id));
43+ create table example3.users(id int, name text, PRIMARY KEY(id));
44+ */
45+ cluster := gocql .NewCluster ("localhost:9042" )
46+ cluster .ProtoVersion = 5 // SetKeyspace requires Protocol 5+, available in Cassandra 4.0+
47+ cluster .Keyspace = "example" // Set a default keyspace
48+ session , err := cluster .CreateSession ()
49+ if err != nil {
50+ log .Fatal (err )
51+ }
52+ defer session .Close ()
53+
54+ ctx := context .Background ()
55+
56+ // Example 1: Keyspace Precedence Hierarchy Demonstration
57+ fmt .Println ("Demonstrating complete keyspace precedence hierarchy:" )
58+ fmt .Println ("1. Keyspace in CQL (keyspace.table) - HIGHEST" )
59+ fmt .Println ("2. SetKeyspace() method - MIDDLE" )
60+ fmt .Println ("3. Default session keyspace - LOWEST" )
61+ fmt .Println ()
62+
63+ // Insert test data
64+ // Default keyspace (example) - lowest precedence
65+ err = session .Query ("INSERT INTO users (id, name) VALUES (?, ?)" ).
66+ Bind (1 , "Alice" ).
67+ ExecContext (ctx )
68+ if err != nil {
69+ log .Fatal (err )
70+ }
71+
72+ // SetKeyspace overrides default - middle precedence
73+ err = session .Query ("INSERT INTO users (id, name) VALUES (?, ?)" ).
74+ SetKeyspace ("example2" ).
75+ Bind (1 , "Bob" ).
76+ ExecContext (ctx )
77+ if err != nil {
78+ log .Fatal (err )
79+ }
80+
81+ // Fully qualified table name - highest precedence
82+ err = session .Query ("INSERT INTO example3.users (id, name) VALUES (?, ?)" ).
83+ Bind (1 , "Charlie" ).
84+ ExecContext (ctx )
85+ if err != nil {
86+ log .Fatal (err )
87+ }
88+
89+ // Example 2: Fully qualified table names override SetKeyspace
90+ fmt .Println ("Example 2: Fully qualified table names take precedence over SetKeyspace:" )
91+
92+ // This query sets keyspace to "example2" via SetKeyspace, but the fully qualified
93+ // table name "example3.users" takes precedence - query will target example3
94+ err = session .Query ("INSERT INTO example3.users (id, name) VALUES (?, ?)" ).
95+ SetKeyspace ("example2" ). // This is IGNORED because CQL has "example3.users"
96+ Bind (2 , "Diana" ).
97+ ExecContext (ctx )
98+ if err != nil {
99+ log .Fatal (err )
100+ }
101+ fmt .Println ("Inserted Diana into example3.users despite SetKeyspace(\" example2\" )" )
102+
103+ // Verify data went to example3, not example2
104+ var count int
105+ iter := session .Query ("SELECT COUNT(*) FROM users" ).
106+ SetKeyspace ("example2" ).
107+ IterContext (ctx )
108+ if iter .Scan (& count ) {
109+ fmt .Printf ("Count in example2: %d (only Bob)\n " , count )
110+ }
111+ if err := iter .Close (); err != nil {
112+ log .Fatal (err )
113+ }
114+
115+ iter = session .Query ("SELECT COUNT(*) FROM users" ).
116+ SetKeyspace ("example3" ).
117+ IterContext (ctx )
118+ if iter .Scan (& count ) {
119+ fmt .Printf ("Count in example3: %d (Charlie and Diana)\n " , count )
120+ }
121+ if err := iter .Close (); err != nil {
122+ log .Fatal (err )
123+ }
124+
125+ // Example 3: SetKeyspace overrides default keyspace
126+ fmt .Println ("\n Example 3: SetKeyspace overrides default keyspace:" )
127+
128+ // Query using default keyspace (no SetKeyspace)
129+ var id int
130+ var name string
131+ iter = session .Query ("SELECT id, name FROM users WHERE id = ?" , 1 ).
132+ IterContext (ctx ) // Uses default keyspace "example"
133+ if iter .Scan (& id , & name ) {
134+ fmt .Printf ("Default keyspace (example): ID %d, Name %s\n " , id , name )
135+ }
136+ if err := iter .Close (); err != nil {
137+ log .Fatal (err )
138+ }
139+
140+ // SetKeyspace overrides default
141+ iter = session .Query ("SELECT id, name FROM users WHERE id = ?" , 1 ).
142+ SetKeyspace ("example2" ). // Override default keyspace
143+ IterContext (ctx )
144+ if iter .Scan (& id , & name ) {
145+ fmt .Printf ("SetKeyspace override (example2): ID %d, Name %s\n " , id , name )
146+ }
147+ if err := iter .Close (); err != nil {
148+ log .Fatal (err )
149+ }
150+
151+ // Example 4: Mixed query patterns in one workflow
152+ fmt .Println ("\n Example 4: Using all precedence levels in one workflow:" )
153+
154+ // Query from default keyspace
155+ iter = session .Query ("SELECT name FROM users WHERE id = 1" ).IterContext (ctx )
156+ if iter .Scan (& name ) {
157+ fmt .Printf ("Default (example): %s\n " , name )
158+ }
159+ iter .Close ()
160+
161+ // Query using SetKeyspace
162+ iter = session .Query ("SELECT name FROM users WHERE id = 1" ).
163+ SetKeyspace ("example2" ).IterContext (ctx )
164+ if iter .Scan (& name ) {
165+ fmt .Printf ("SetKeyspace (example2): %s\n " , name )
166+ }
167+ iter .Close ()
168+
169+ // Query using fully qualified table name (ignores both default and SetKeyspace)
170+ iter = session .Query ("SELECT name FROM example3.users WHERE id = 1" ).
171+ SetKeyspace ("example2" ). // This is ignored due to qualified table name
172+ IterContext (ctx )
173+ if iter .Scan (& name ) {
174+ fmt .Printf ("Qualified name (example3): %s\n " , name )
175+ }
176+ iter .Close ()
177+
178+ // Demonstrating complete keyspace precedence hierarchy:
179+ // 1. Keyspace in CQL (keyspace.table) - HIGHEST
180+ // 2. SetKeyspace() method - MIDDLE
181+ // 3. Default session keyspace - LOWEST
182+ //
183+ // Example 2: Fully qualified table names take precedence over SetKeyspace:
184+ // Inserted Diana into example3.users despite SetKeyspace("example2")
185+ // Count in example2: 1 (only Bob)
186+ // Count in example3: 2 (Charlie and Diana)
187+ //
188+ // Example 3: SetKeyspace overrides default keyspace:
189+ // Default keyspace (example): ID 1, Name Alice
190+ // SetKeyspace override (example2): ID 1, Name Bob
191+ //
192+ // Example 4: Using all precedence levels in one workflow:
193+ // Default (example): Alice
194+ // SetKeyspace (example2): Bob
195+ // Qualified name (example3): Charlie
196+ }
0 commit comments