oracle/
row.rs

1// Rust-oracle - Rust binding for Oracle database
2//
3// URL: https://github.com/kubo/rust-oracle
4//
5//-----------------------------------------------------------------------------
6// Copyright (c) 2018 Kubo Takehiro <kubo@jiubao.org>. All rights reserved.
7// This program is free software: you can modify it and/or redistribute it
8// under the terms of:
9//
10// (i)  the Universal Permissive License v 1.0 or at your option, any
11//      later version (http://oss.oracle.com/licenses/upl); and/or
12//
13// (ii) the Apache License v 2.0. (http://www.apache.org/licenses/LICENSE-2.0)
14//-----------------------------------------------------------------------------
15
16use std::fmt;
17use std::iter::FusedIterator;
18use std::marker::PhantomData;
19use std::sync::Arc;
20
21use crate::sql_type::FromSql;
22use crate::statement::Stmt;
23use crate::AssertSend;
24use crate::ColumnIndex;
25use crate::ColumnInfo;
26#[cfg(doc)]
27use crate::Connection;
28use crate::Result;
29use crate::SqlValue;
30#[cfg(doc)]
31use crate::Statement;
32
33/// Row in a result set of a select statement
34pub struct Row {
35    pub(crate) column_info: Arc<Vec<ColumnInfo>>,
36    pub(crate) column_values: Vec<SqlValue<'static>>,
37}
38
39impl Row {
40    pub(crate) fn new(
41        column_info: Vec<ColumnInfo>,
42        column_values: Vec<SqlValue<'static>>,
43    ) -> Result<Row> {
44        Ok(Row {
45            column_info: Arc::new(column_info),
46            column_values,
47        })
48    }
49
50    /// Gets the column value at the specified index.
51    pub fn get<I, T>(&self, colidx: I) -> Result<T>
52    where
53        I: ColumnIndex,
54        T: FromSql,
55    {
56        let pos = colidx.idx(&self.column_info)?;
57        self.column_values[pos].get()
58    }
59
60    /// Returns column values as a vector of SqlValue
61    pub fn sql_values(&self) -> &[SqlValue] {
62        &self.column_values
63    }
64
65    /// Gets column values as specified type.
66    ///
67    /// Type inference for the return type doesn't work. You need to specify
68    /// it explicitly such as `row.get_as::<(i32, String)>()`.
69    /// See [`RowValue`] for available return types.
70    ///
71    /// ```no_run
72    /// # use oracle::*;
73    /// let conn = Connection::connect("scott", "tiger", "")?;
74    /// let mut stmt = conn.statement("select empno, ename from emp").build()?;
75    ///
76    /// for result in stmt.query(&[])? {
77    ///     let row = result?;
78    ///     // Gets a row as `(i32, String)`.
79    ///     let (empno, ename) = row.get_as::<(i32, String)>()?;
80    ///     println!("{},{}", empno, ename);
81    /// }
82    /// # Ok::<(), Error>(())
83    /// ```
84    pub fn get_as<T>(&self) -> Result<T>
85    where
86        T: RowValue,
87    {
88        <T>::get(self)
89    }
90
91    pub fn column_info(&self) -> &[ColumnInfo] {
92        &self.column_info
93    }
94}
95
96impl AssertSend for Row {}
97
98impl fmt::Debug for Row {
99    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100        write!(f, "Row {{ ")?;
101        for (info, value) in self.column_info.iter().zip(&self.column_values) {
102            write!(f, "{}: {:?} ", info.name(), value)?;
103        }
104        write!(f, "}}")
105    }
106}
107
108#[derive(Debug)]
109enum StmtHolder<'a> {
110    Borrowed(&'a mut Stmt),
111    Owned(Stmt),
112}
113
114/// Result set
115///
116/// # Remarks
117///
118/// The lifetime parameter `'a` is `'static` when this type is created by the following methods.
119///
120/// * [`Connection::query()`]
121/// * [`Connection::query_named()`]
122/// * [`Connection::query_as()`]
123/// * [`Connection::query_as_named()`]
124/// * [`Statement::into_result_set()`]
125/// * [`Statement::into_result_set_named()`]
126///
127/// On the other hand, `'a` refers to [`Statement`] when it is created by the following methods.
128///
129/// * [`Statement::query()`]
130/// * [`Statement::query_named()`]
131/// * [`Statement::query_as()`]
132/// * [`Statement::query_as_named()`]
133///
134#[derive(Debug)]
135pub struct ResultSet<'a, T>
136where
137    T: RowValue,
138{
139    stmt: StmtHolder<'a>,
140    phantom: PhantomData<T>,
141}
142
143impl<'a, T> ResultSet<'a, T>
144where
145    T: RowValue,
146{
147    pub(crate) fn new(stmt: &'a mut Stmt) -> ResultSet<'a, T> {
148        ResultSet {
149            stmt: StmtHolder::Borrowed(stmt),
150            phantom: PhantomData,
151        }
152    }
153
154    pub(crate) fn from_stmt(stmt: Stmt) -> ResultSet<'a, T> {
155        ResultSet {
156            stmt: StmtHolder::Owned(stmt),
157            phantom: PhantomData,
158        }
159    }
160
161    fn stmt(&self) -> &Stmt {
162        match self.stmt {
163            StmtHolder::Borrowed(ref stmt) => stmt,
164            StmtHolder::Owned(ref stmt) => stmt,
165        }
166    }
167
168    fn stmt_mut(&mut self) -> &mut Stmt {
169        match self.stmt {
170            StmtHolder::Borrowed(ref mut stmt) => stmt,
171            StmtHolder::Owned(ref mut stmt) => stmt,
172        }
173    }
174
175    pub fn column_info(&self) -> &[ColumnInfo] {
176        &self.stmt().row.as_ref().unwrap().column_info
177    }
178}
179
180unsafe impl<T> Send for ResultSet<'static, T> where T: RowValue {}
181
182impl<T> Iterator for ResultSet<'_, T>
183where
184    T: RowValue,
185{
186    type Item = Result<T>;
187
188    fn next(&mut self) -> Option<Self::Item> {
189        self.stmt_mut()
190            .next()
191            .map(|row_result| row_result.and_then(|row| row.get_as::<T>()))
192    }
193}
194
195impl<T> FusedIterator for ResultSet<'_, T> where T: RowValue {}
196
197/// A trait to get a row as specified type
198///
199/// This is the return type of [`Connection::query_row_as`],
200/// [`Connection::query_row_as_named`] and [`Row::get_as`].
201///
202/// The trait was added to fetch column values as a tuple.
203/// The oracle crate provides implementations for a type
204/// implementing [`FromSql`] and tuples of types implementing
205/// [`FromSql`]. The number of elements in a tuple should
206///  be 1 through 50.
207///
208/// ```no_run
209/// # use oracle::*;
210/// let conn = Connection::connect("scott", "tiger", "")?;
211///
212/// let sql = "select * from emp where empno = :1";
213///
214/// // Gets the first column value in a row.
215/// // Values after the second column are ignored.
216/// let empno = conn.query_row_as::<u32>(sql, &[&7369])?;
217///
218/// // Gets the first two column values in a row.
219/// // Values after the third column are ignored.
220/// let tuple_of_empno_and_ename = conn.query_row_as::<(i32, String)>(sql, &[&7499])?;
221/// # Ok::<(), Error>(())
222/// ```
223///
224/// You can implement the trait for your own types. For example
225/// when you have a struct whose members are `empno` and `ename`,
226/// you can make the struct from `empno` and `ename` column values
227/// as follows:
228///
229/// ```no_run
230/// # use oracle::{Connection, Error, Result, Row, RowValue};
231/// struct Emp {
232///     empno: i32,
233///     ename: String,
234/// }
235///
236/// impl RowValue for Emp {
237///     fn get(row: &Row) -> std::result::Result<Emp, Error> {
238///         Ok(Emp {
239///             empno: row.get("empno")?,
240///             ename: row.get("ename")?,
241///         })
242///     }
243/// }
244///
245/// let conn = Connection::connect("scott", "tiger", "")?;
246/// let mut stmt = conn.statement("select * from emp").build()?;
247///
248/// // Gets rows as Emp
249/// for result in stmt.query_as::<Emp>(&[])? {
250///     let emp = result?;
251///     println!("{},{}", emp.empno, emp.ename);
252/// }
253/// # Ok::<(), Error>(())
254/// ```
255pub trait RowValue: Sized {
256    fn get(row: &Row) -> Result<Self>;
257}
258
259impl RowValue for Row {
260    fn get(row: &Row) -> Result<Row> {
261        let num_cols = row.column_values.len();
262        let mut column_values = Vec::with_capacity(num_cols);
263        for val in &row.column_values {
264            column_values.push(val.clone_except_fetch_array_buffer()?);
265        }
266        Ok(Row {
267            column_info: row.column_info.clone(),
268            column_values,
269        })
270    }
271}
272
273impl<T: FromSql> RowValue for T {
274    fn get(row: &Row) -> Result<T> {
275        row.get::<usize, T>(0)
276    }
277}
278
279macro_rules! impl_row_value_for_tuple {
280    ($(
281        [$(($idx:tt, $T:ident))+],
282    )+) => {
283        $(
284            impl<$($T:FromSql,)+> RowValue for ($($T,)+) {
285                fn get(row: &Row) -> Result<($($T,)+)> {
286                    Ok((
287                        $(row.get::<usize, $T>($idx)?,)+
288                    ))
289                }
290            }
291        )+
292    }
293}
294
295impl_row_value_for_tuple! {
296    [(0,T0)],
297    [(0,T0)(1,T1)],
298    [(0,T0)(1,T1)(2,T2)],
299    [(0,T0)(1,T1)(2,T2)(3,T3)],
300    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)],
301    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)],
302    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)],
303    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)],
304    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)],
305    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)],
306    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
307     (10,T10)],
308    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
309     (10,T10)(11,T11)],
310    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
311     (10,T10)(11,T11)(12,T12)],
312    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
313     (10,T10)(11,T11)(12,T12)(13,T13)],
314    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
315     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)],
316    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
317     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)],
318    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
319     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)],
320    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
321     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)],
322    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
323     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)],
324    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
325     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)],
326    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
327     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
328     (20,T20)],
329    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
330     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
331     (20,T20)(21,T21)],
332    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
333     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
334     (20,T20)(21,T21)(22,T22)],
335    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
336     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
337     (20,T20)(21,T21)(22,T22)(23,T23)],
338    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
339     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
340     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)],
341    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
342     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
343     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)],
344    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
345     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
346     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)],
347    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
348     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
349     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)],
350    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
351     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
352     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)],
353    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
354     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
355     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)],
356    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
357     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
358     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
359     (30,T30)],
360    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
361     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
362     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
363     (30,T30)(31,T31)],
364    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
365     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
366     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
367     (30,T30)(31,T31)(32,T32)],
368    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
369     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
370     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
371     (30,T30)(31,T31)(32,T32)(33,T33)],
372    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
373     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
374     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
375     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)],
376    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
377     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
378     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
379     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)],
380    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
381     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
382     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
383     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)],
384    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
385     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
386     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
387     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)],
388    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
389     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
390     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
391     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)],
392    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
393     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
394     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
395     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)(39,T39)],
396    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
397     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
398     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
399     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)(39,T39)
400     (40,T40)],
401    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
402     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
403     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
404     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)(39,T39)
405     (40,T40)(41,T41)],
406    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
407     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
408     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
409     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)(39,T39)
410     (40,T40)(41,T41)(42,T42)],
411    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
412     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
413     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
414     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)(39,T39)
415     (40,T40)(41,T41)(42,T42)(43,T43)],
416    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
417     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
418     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
419     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)(39,T39)
420     (40,T40)(41,T41)(42,T42)(43,T43)(44,T44)],
421    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
422     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
423     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
424     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)(39,T39)
425     (40,T40)(41,T41)(42,T42)(43,T43)(44,T44)(45,T45)],
426    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
427     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
428     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
429     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)(39,T39)
430     (40,T40)(41,T41)(42,T42)(43,T43)(44,T44)(45,T45)(46,T46)],
431    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
432     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
433     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
434     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)(39,T39)
435     (40,T40)(41,T41)(42,T42)(43,T43)(44,T44)(45,T45)(46,T46)(47,T47)],
436    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
437     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
438     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
439     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)(39,T39)
440     (40,T40)(41,T41)(42,T42)(43,T43)(44,T44)(45,T45)(46,T46)(47,T47)(48,T48)],
441    [(0,T0)(1,T1)(2,T2)(3,T3)(4,T4)(5,T5)(6,T6)(7,T7)(8,T8)(9,T9)
442     (10,T10)(11,T11)(12,T12)(13,T13)(14,T14)(15,T15)(16,T16)(17,T17)(18,T18)(19,T19)
443     (20,T20)(21,T21)(22,T22)(23,T23)(24,T24)(25,T25)(26,T26)(27,T27)(28,T28)(29,T29)
444     (30,T30)(31,T31)(32,T32)(33,T33)(34,T34)(35,T35)(36,T36)(37,T37)(38,T38)(39,T39)
445     (40,T40)(41,T41)(42,T42)(43,T43)(44,T44)(45,T45)(46,T46)(47,T47)(48,T48)(49,T49)],
446}