1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Spanner client.

use std::sync::Arc;

use google_cloud_rust_raw::spanner::v1::{
    spanner::{CreateSessionRequest, Session},
    spanner_grpc::SpannerClient,
};
use grpcio::{CallOption, ChannelBuilder, ChannelCredentials, EnvBuilder, MetadataBuilder};

#[allow(dead_code)]
pub struct Client {
    database: String,
    client: SpannerClient,
    session: Session,
}

impl Client {
    /// Creates a new Spanner client.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// use google_cloud_rust::spanner;
    ///
    /// let db = "projects/my_project/instances/my_instance/databases/my_database";
    /// let client = spanner::Client::new(db);
    /// ```
    pub fn new(database: &str) -> crate::Result<Client> {
        let database = database.to_string();
        let endpoint = "spanner.googleapis.com:443";

        // Set up the gRPC environment.
        let env = Arc::new(EnvBuilder::new().build());
        let creds = ChannelCredentials::google_default_credentials()?;

        // Create a Spanner client.
        let chan = ChannelBuilder::new(Arc::clone(&env))
            .max_send_message_len(100 << 20)
            .max_receive_message_len(100 << 20)
            .set_credentials(creds)
            .connect(&endpoint);
        let client = SpannerClient::new(chan);

        let mut req = CreateSessionRequest::new();
        req.set_database(database.to_string());
        let mut meta = MetadataBuilder::new();
        meta.add_str("google-cloud-resource-prefix", &database)?;
        meta.add_str("x-goog-api-client", "googleapis-rs")?;
        let opt = CallOption::default().headers(meta.build());
        let session = client.create_session_opt(&req, opt)?;

        Ok(Client {
            database,
            client,
            session,
        })
    }
}