|
4 | 4 |
|
5 | 5 | use Utopia\Database\Database; |
6 | 6 | use Utopia\Database\Document; |
| 7 | +use Utopia\Database\Exception; |
7 | 8 | use Utopia\Database\Helpers\ID; |
8 | 9 | use Utopia\Database\Helpers\Permission; |
9 | 10 | use Utopia\Database\Helpers\Role; |
@@ -340,7 +341,12 @@ public function testSpatialAttributes(): void |
340 | 341 |
|
341 | 342 | // Create spatial indexes |
342 | 343 | $this->assertEquals(true, $database->createIndex($collectionName, 'idx_point', Database::INDEX_SPATIAL, ['pointAttr'])); |
343 | | - $this->assertEquals(true, $database->createIndex($collectionName, 'idx_line', Database::INDEX_SPATIAL, ['lineAttr'])); |
| 344 | + if ($database->getAdapter()->getSupportForSpatialIndexNull()) { |
| 345 | + $this->assertEquals(true, $database->createIndex($collectionName, 'idx_line', Database::INDEX_SPATIAL, ['lineAttr'])); |
| 346 | + } else { |
| 347 | + // Attribute was created as required above; directly create index once |
| 348 | + $this->assertEquals(true, $database->createIndex($collectionName, 'idx_line', Database::INDEX_SPATIAL, ['lineAttr'])); |
| 349 | + } |
344 | 350 | $this->assertEquals(true, $database->createIndex($collectionName, 'idx_poly', Database::INDEX_SPATIAL, ['polyAttr'])); |
345 | 351 |
|
346 | 352 | $collection = $database->getCollection($collectionName); |
@@ -1773,4 +1779,90 @@ public function testSptialAggregation(): void |
1773 | 1779 | $database->deleteCollection($collectionName); |
1774 | 1780 | } |
1775 | 1781 | } |
| 1782 | + |
| 1783 | + public function testUpdateSpatialAttributes(): void |
| 1784 | + { |
| 1785 | + /** @var Database $database */ |
| 1786 | + $database = static::getDatabase(); |
| 1787 | + if (!$database->getAdapter()->getSupportForSpatialAttributes()) { |
| 1788 | + $this->markTestSkipped('Adapter does not support spatial attributes'); |
| 1789 | + } |
| 1790 | + |
| 1791 | + $collectionName = 'spatial_update_attrs_'; |
| 1792 | + try { |
| 1793 | + $database->createCollection($collectionName); |
| 1794 | + |
| 1795 | + // 0) Disallow creation of spatial attributes with size or array |
| 1796 | + try { |
| 1797 | + $database->createAttribute($collectionName, 'geom_bad_size', Database::VAR_POINT, 10, true); |
| 1798 | + $this->fail('Expected DatabaseException when creating spatial attribute with non-zero size'); |
| 1799 | + } catch (\Throwable $e) { |
| 1800 | + $this->assertInstanceOf(Exception::class, $e); |
| 1801 | + } |
| 1802 | + |
| 1803 | + try { |
| 1804 | + $database->createAttribute($collectionName, 'geom_bad_array', Database::VAR_POINT, 0, true, array: true); |
| 1805 | + $this->fail('Expected DatabaseException when creating spatial attribute with array=true'); |
| 1806 | + } catch (\Throwable $e) { |
| 1807 | + $this->assertInstanceOf(Exception::class, $e); |
| 1808 | + } |
| 1809 | + |
| 1810 | + // Create a single spatial attribute (required=true) |
| 1811 | + $this->assertEquals(true, $database->createAttribute($collectionName, 'geom', Database::VAR_POINT, 0, true)); |
| 1812 | + $this->assertEquals(true, $database->createIndex($collectionName, 'idx_geom', Database::INDEX_SPATIAL, ['geom'])); |
| 1813 | + |
| 1814 | + // 1) Disallow size and array updates on spatial attributes: expect DatabaseException |
| 1815 | + try { |
| 1816 | + $database->updateAttribute($collectionName, 'geom', size: 10); |
| 1817 | + $this->fail('Expected DatabaseException when updating size on spatial attribute'); |
| 1818 | + } catch (\Throwable $e) { |
| 1819 | + $this->assertInstanceOf(Exception::class, $e); |
| 1820 | + } |
| 1821 | + |
| 1822 | + try { |
| 1823 | + $database->updateAttribute($collectionName, 'geom', array: true); |
| 1824 | + $this->fail('Expected DatabaseException when updating array on spatial attribute'); |
| 1825 | + } catch (\Throwable $e) { |
| 1826 | + $this->assertInstanceOf(Exception::class, $e); |
| 1827 | + } |
| 1828 | + |
| 1829 | + // 2) required=true -> create index -> update required=false |
| 1830 | + $nullSupported = $database->getAdapter()->getSupportForSpatialIndexNull(); |
| 1831 | + if ($nullSupported) { |
| 1832 | + // Should succeed on adapters that allow nullable spatial indexes |
| 1833 | + $database->updateAttribute($collectionName, 'geom', required: false); |
| 1834 | + $meta = $database->getCollection($collectionName); |
| 1835 | + $this->assertEquals(false, $meta->getAttribute('attributes')[0]['required']); |
| 1836 | + } else { |
| 1837 | + // Should error (index constraint) when making required=false while spatial index exists |
| 1838 | + $threw = false; |
| 1839 | + try { |
| 1840 | + $database->updateAttribute($collectionName, 'geom', required: false); |
| 1841 | + } catch (\Throwable $e) { |
| 1842 | + $threw = true; |
| 1843 | + } |
| 1844 | + $this->assertTrue($threw, 'Expected error when setting required=false with existing spatial index and adapter not supporting nullable indexes'); |
| 1845 | + // Ensure attribute remains required |
| 1846 | + $meta = $database->getCollection($collectionName); |
| 1847 | + $this->assertEquals(true, $meta->getAttribute('attributes')[0]['required']); |
| 1848 | + } |
| 1849 | + |
| 1850 | + // 3) Spatial index order support: providing orders should fail if not supported |
| 1851 | + $orderSupported = $database->getAdapter()->getSupportForSpatialIndexOrder(); |
| 1852 | + if ($orderSupported) { |
| 1853 | + $this->assertTrue($database->createIndex($collectionName, 'idx_geom_desc', Database::INDEX_SPATIAL, ['geom'], [], [Database::ORDER_DESC])); |
| 1854 | + // cleanup |
| 1855 | + $this->assertTrue($database->deleteIndex($collectionName, 'idx_geom_desc')); |
| 1856 | + } else { |
| 1857 | + try { |
| 1858 | + $database->createIndex($collectionName, 'idx_geom_desc', Database::INDEX_SPATIAL, ['geom'], [], ['DESC']); |
| 1859 | + $this->fail('Expected error when providing orders for spatial index on adapter without order support'); |
| 1860 | + } catch (\Throwable $e) { |
| 1861 | + $this->assertTrue(true); |
| 1862 | + } |
| 1863 | + } |
| 1864 | + } finally { |
| 1865 | + $database->deleteCollection($collectionName); |
| 1866 | + } |
| 1867 | + } |
1776 | 1868 | } |
0 commit comments